ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Azure Functions on Azure Container Apps


Kubernetes で Azure Functions が動くなら*1 Azure Container App でも動く?と思って勢いでやってみたら、割と簡単に動いた。

リソース構成

あまり普段意識しない子リソースがいくつかあって少しごちゃごちゃしてるけど、デプロイするリソース (「MCR」以外) はこんな感じ。

Container App は Azure Functions Host のコンテナ イメージ*2を動かす。
Storage Account は File ストレージで関数コードの保存先として、Container App から /home/site/wwwroot としてマウント*3

Application Insights は Azure Functions のテレメトリ/ログの送信先
実際は、近頃の Application Insights は Log Analytics でログを保存してるみたい。
なので Container Apps Environment 用の Log Analytics をそのまま流用。

Azure へデプロイ

試したい人は、こちらのカスタム デプロイのボタンからどうぞ。

Bicep はこちらで公開中。 github.com

他と比べてどうなのか

Azure Functions と比べて

イイところ。

Container App なので、組み込みの KEDA がスケーリングしてくれるので zero-scale もできる。 その上に VNET の中にデプロイできる。ELB / ILB 、どちらでも。

ちなみに Azure Functions の場合、zero-scale できる従量課金プランでは VNET 統合も Private Endpoint も使えない。
VNET が使える Elrastic Premium プランの場合は、zero-scale ができない。

おそらく一番の(そして唯一の?)アドバンテージかもしれない。

残念なところ。

タイマー トリガーの挙動が当初の期待と違った。
zero-scale すると当然ながらコンテナが無くなるので、スケジュールを管理できなくなりトリガーされない。
当たり前な動きだけど、タイマー トリガーの動作としては厳しい。
あとスケール アウトした時、全てのレプリカ上で関数が実行される。

一方で Azure Functions でホスティングしたタイマー トリガーは既定はシングルトン。
2 つ以上のインスタンスにスケール アウトしても関数は 1 つのインスタンス上でだけ実行される。
当然 zero-scale してもその直前にインスタンスが立ち上がり、スケジュール通りに実行する。

Azure Functions のスケール コントローラって、割と大変なことしているんじゃないだろうか。頭が下がる。

価格面は比較計算が難しい。
vCPU 1 コアあたりとかメモリ 1GB あたりの料金だけを (超局所的に) 比較すると、Elrastic Premium プランよりは安く見える。
が、これは使い方次第。

On Kubernetes と比べて

Kubernetesホスティングする場合、イベント ドリブンで Pod をスケーリングするに KEDA & Prometheus *4 が必要。
Azure Container Apps には元から入っているので、これらを入れる手間はなし。

Kubernetes も KEDA でスケーリングする以上、タイマー トリガー周りは違いはない。はず。と予想*5

VNET 内のリソースへのアクセスについては、AKSホスティングすればできるので、この辺りは特にアドバンテージなし。

価格は Pod のスケーリングよりもノード プール サイズの影響が大きいので、これまた比較が難しい。

比較まとめ

感想レベルだけども。

Azure Functions On Kubernetes On Azure Container App
Scaling
要 KEDA and Prometheus
Triggers
一部に限られる

(左に同じ)
VNET Injection
要 Elrastic Premium or ASP
Price
ユースケース次第なので比較困難

プラン & 使用量次第

ノード プール次第

vCPU/メモリ単価は安そう

VNET 内のリソースとの連携が必要であれば選択肢に入る、、、かも?