MENU

Azure Container Apps入門|AKS・ACIとの違いとサーバーレスコンテナ基盤の設計・料金ガイド

KubernetesをAzureで動かしたいが、AKSは管理コストが高すぎる。かといってAzure Container Instances(ACI)では自動スケーリングもマイクロサービス間通信も満足に扱えない。そのジレンマを抱えているインフラエンジニアは多い。

Azure Container Appsは、AKSとACIのちょうど中間に位置するフルマネージドのサーバーレスコンテナ基盤だ。Kubernetesの複雑なクラスター管理を意識せずに、マイクロサービスや非同期ワーカー、APIサーバーをコンテナで稼働させられる。

この記事では、Azure Container Appsの基本設計をACI・AKSとの比較で整理したうえで、Environment・Revision・スケーリングルールの実装手順、料金の仕組みと月額コスト試算、現場で使える運用Tipsまでを網羅する。

Azure Container Apps入門|AKS・ACIとの違いとサーバーレスコンテナ基盤の設計・料金ガイド - 解説

目次

なぜAzure Container Appsなのか?ACI・AKSとの違いを整理する

Azureにはコンテナを動かすサービスが複数あり、選び方で迷うことが多い。まずは3つの位置づけを明確にしておこう。

比較軸 Azure Container Instances(ACI) Azure Container Apps Azure Kubernetes Service(AKS)
主なユースケース バッチ処理・単発タスク・CI/CDエージェント マイクロサービス・API・非同期ワーカー 大規模本番環境・高度なK8s制御が必要な場合
Kubernetes管理 不要 不要(内部で自動管理) 必要(ノードプール・アップグレード等)
自動スケーリング 手動のみ スケールゼロ含む自動スケール HPA・Karpenterなどの設定が必要
Daprサポート 非対応 組み込みサポート 手動インストール
最小稼働コスト 起動秒数のみ課金(常時起動も可) スケールゼロ時は無料 ノード分の料金が常時発生
カスタムドメイン/TLS 手動設定が煩雑 マネージドTLS証明書あり Ingress Controllerの設定が必要

現場での判断基準をまとめると次のとおりだ。

・ACI を選ぶとき: 起動時間が短く完了する単発バッチや、GitHub ActionsのセルフホストランナーなどCI/CDの一時コンテナに向いている。常時稼働サービスには不向き。
・Container Apps を選ぶとき: マイクロサービス構成のAPIや非同期メッセージワーカーで、Kubernetesの運用コストを掛けたくない場合に最適。スケールゼロで夜間コストを抑えたい用途にも合う。
・AKS を選ぶとき: StatefulSetやカスタムオペレーターが必要、既存のHelmチャートをそのまま使いたい、GPU対応ノードが必要など、KubernetesのAPIを直接制御したい場合に選ぶ。

Container Appsは内部的にKubernetes・KEDA・Dapr・Envoyの組み合わせで動いているが、ユーザーからはそれらが完全に隠蔽されている。オンプレのKubernetesクラスター運用でノードのメンテナンスやアップグレード作業に疲弊した経験があるなら、Container Appsの「管理不要」という価値は実感しやすいはずだ。

Azure Container Appsの3つのコア概念

Container Appsを使いこなすには、次の3つの概念を正確に理解しておく必要がある。

1. Container Apps Environment(環境)

Container Apps Environmentは、複数のContainer Appを収容する共有実行環境だ。Azureのリソースグループ内に1つ以上作成でき、同一Environment内のアプリはプライベートネットワーク(内部VNET)で直接通信できる。

オンプレの感覚に置き換えると、「1つのDCラック内でVLANを共有している複数のサーバー」に近い。EnvironmentはLog Analytics Workspaceと紐付くため、ログ・メトリクスの収集単位にもなる。

注意点として、Environment間の通信はパブリックエンドポイント経由になるため、マイクロサービスを密に連携させたい場合は同一Environmentに配置する設計が基本だ。

2. Container App(アプリケーション)

Container Appは、コンテナイメージ1つ(または複数のサイドカー)に対応する論理単位だ。HTTPトラフィックを受け付けるかどうかをIngress設定で制御し、外部公開か内部のみかを選べる。

各Container Appには独自のURLが付与される(例: myapp.xxx.japaneast.azurecontainerapps.io)。カスタムドメインも設定可能で、マネージドTLS証明書が自動的に発行される。

3. Revision(リビジョン)

Container Appのコンテナイメージやスケール設定を変更するたびに、新しいRevisionが作成される。Revisionは変更不可なスナップショットであり、複数のRevisionを同時にアクティブにしてトラフィックを分割することができる。

例えばv1.0に90%、v1.1に10%のトラフィックを向けることで、本格的なカナリアリリース運用が実現できる。CI/CDパイプラインと組み合わせることで、デプロイリスクを大幅に下げられる。

デプロイの実践手順

ここではAzure CLIを使って、Container Apps EnvironmentとHello Worldアプリをデプロイする手順を示す。

1. 拡張機能のインストールと変数の設定

# Azure CLI 拡張機能を追加 az extension add --name containerapp --upgrade # プロバイダー登録(初回のみ) az provider register --namespace Microsoft.App az provider register --namespace Microsoft.OperationalInsights # 変数定義 RESOURCE_GROUP="rg-containerapp-demo" LOCATION="japaneast" ENVIRONMENT="my-container-env" APP_NAME="hello-containerapp"

2. リソースグループとEnvironmentの作成

# リソースグループを作成 az group create \ --name $RESOURCE_GROUP \ --location $LOCATION # Container Apps Environment を作成 # --logs-destination none で Log Analytics を省略(検証環境向け) az containerapp env create \ --name $ENVIRONMENT \ --resource-group $RESOURCE_GROUP \ --location $LOCATION

本番環境では --logs-destination log-analytics を指定し、Log Analytics Workspaceと連携することを推奨する。

3. コンテナアプリのデプロイ

# コンテナアプリを作成してデプロイ az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --environment $ENVIRONMENT \ --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \ --target-port 80 \ --ingress external \ --cpu 0.5 \ --memory 1.0Gi \ --min-replicas 0 \ --max-replicas 5 \ --query properties.configuration.ingress.fqdn \ --output tsv

コマンドが成功すると、アプリのFQDN(例: hello-containerapp.xxx.japaneast.azurecontainerapps.io)が出力される。ブラウザでアクセスすると、Hello Worldページが表示される。

--min-replicas 0 を指定すると、リクエストがない間はコンテナが0台まで縮退し、待機コストがゼロになる。

4. スケーリングルールの設定(HTTPトリガー)

# HTTP同時接続数100を超えたらスケールアウト az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --scale-rule-name http-scale \ --scale-rule-type http \ --scale-rule-http-concurrency 100

このルールは「100並列リクエストにつき1レプリカ」でスケールすることを意味する。最大5レプリカまで自動的に増加し、負荷が下がれば縮退する。

5. Revisionを更新してカナリアリリースを設定する

# 複数Revisionを許可するモードに変更 az containerapp revision set-mode \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --mode multiple # 新しいイメージをデプロイ(新Revisionが自動作成される) az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --image myacr.azurecr.io/myapp:v2.0 # 既存Revisionを確認して名前を取得 az containerapp revision list \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --query "[].{name:name,active:properties.active,traffic:properties.trafficWeight}" \ --output table # トラフィックを90%(v1)/ 10%(v2)に分割 az containerapp ingress traffic set \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --revision-weight \ hello-containerapp--revision-v1=90 \ hello-containerapp--revision-v2=10

料金の仕組みとコスト試算

Container Appsにはプランが2つある。多くのワークロードで最初に検討するのはConsumption(従量課金)プランだ。

Consumptionプランの料金体系(2026年6月時点・東日本リージョン)

・無料枠(月ごと・サブスクリプション単位): vCPU 180,000秒、メモリ 360,000 GiB秒、リクエスト 200万回
・アクティブ時vCPU: $0.000024/秒(≒$0.0864/時間)
・アクティブ時メモリ: $0.000003/GiB秒(≒$0.0108/GiB時間)
・アイドル時vCPU: $0.000001/秒(≒$0.0036/時間)
・アイドル時メモリ: $0.000000125/GiB秒(≒$0.00045/GiB時間)
・リクエスト: $0.40/100万リクエスト(無料枠超過分)

「アクティブ時」とはリクエストを処理している時間、「アイドル時」はレプリカが起動しているが処理をしていない時間を指す。min-replicas 0 にすれば、リクエストがない間は完全にスケールゼロになりコストが発生しない。

コスト試算例

0.5 vCPU / 1 GiB メモリのAPIサーバーを1日8時間、月22日稼働(夜間はスケールゼロ)させる場合の試算だ。

・稼働時間: 8h × 22日 = 176時間 = 633,600秒
・vCPU料金: 0.5コア × 633,600秒 = 316,800秒 → 無料枠180,000秒を差し引いた136,800秒 × $0.000024 = $3.28
・メモリ料金: 1 GiB × 633,600秒 = 633,600秒 → 無料枠360,000秒を差し引いた273,600秒 × $0.000003 = $0.82
・合計: 約$4.10/月(リクエスト数が200万回以内なら追加なし)

同等ワークロードをAKSの最小構成(Standard_D2s_v5 × 2ノード)で動かした場合、ノード代だけで月約$200~$300かかる。小中規模のサービスではContainer Appsのコスト優位性が際立つ。

Dedicatedプランが有利なケース

常時高い処理量があり、スケールゼロを使わない場合はDedicatedプランの方が安くなることがある。DedicatedプランではD4(4 vCPU / 16 GiB)などのワークロードプロファイルを予約し、そのリソースをContainer Appが共有して利用する。月間稼働率が高いワークロードはDedicatedプランとの比較試算を行うことを勧める。

運用・設計のポイント

Daprを使ったサービス間通信とpub/sub

Container Appsに組み込まれたDapr(Distributed Application Runtime)を有効化すると、サービス間のHTTP/gRPC呼び出し、状態管理、pub/subメッセージングをサイドカーが代替してくれる。

マイクロサービスAからBを呼び出す際、ハードコードされたURLではなくDaprのApp IDで解決できるため、サービス間の依存関係をコードから分離できる。オンプレでEurekaやConsulのようなサービス検出ツールを使っていた場合、Daprが代替に近い役割を果たす。

# Daprを有効化してデプロイ az containerapp create \ --name order-service \ --resource-group $RESOURCE_GROUP \ --environment $ENVIRONMENT \ --image myacr.azurecr.io/order-service:latest \ --target-port 3000 \ --ingress internal \ --enable-dapr \ --dapr-app-id order-service \ --dapr-app-port 3000 \ --dapr-app-protocol http

KEDAによるイベント駆動スケーリング

HTTP以外のトリガーでスケールさせたい場合は、KEDA(Kubernetes Event-driven Autoscaling)ベースのカスタムスケールルールを使う。Azure Service Busキューのメッセージ数に応じてスケールアウトするワーカーの例を示す。

# Azure Service Bus のキュー長に応じたスケールルール az containerapp update \ --name queue-worker \ --resource-group $RESOURCE_GROUP \ --min-replicas 0 \ --max-replicas 10 \ --scale-rule-name servicebus-scale \ --scale-rule-type azure-servicebus \ --scale-rule-metadata \ "queueName=myqueue" \ "messageCount=5" \ --scale-rule-auth "connection=connectionstring-secretref"

この設定では「キューに5メッセージあれば1レプリカ追加」のペースでスケールアウトする。メッセージが0になれば自動的に0台まで縮退するため、バッチワーカーにコスト効率よく使えるパターンだ。

Azure Monitorによるログ・メトリクス監視

Azure Monitorと連携することで、コンテナのCPU使用率・メモリ使用率・リクエスト数・レスポンスタイムをメトリクスとして監視できる。

Container Apps Environmentに紐付けたLog Analytics Workspaceには、コンテナの標準出力ログが自動的に収集される。以下のKQLクエリでアプリのエラーログを抽出できる。

# Log Analytics でアプリのエラーログを確認するKQL ContainerAppConsoleLogs_CL | where ContainerAppName_s == "hello-containerapp" | where Log_s contains "ERROR" | order by TimeGenerated desc | take 50

ACRからのプライベートイメージ pull

Azure Container Registry(ACR)と組み合わせる場合は、Managed Identityを使ってパスワードレスで認証できる。Container AppのシステムマネージドIDにACRの AcrPull ロールを付与するだけで設定が完了し、認証情報をシークレットに格納する必要がない。

よくあるトラブルと対処法

コンテナが起動直後にクラッシュする

Revision作成後にコンテナが繰り返し再起動する場合は、まず以下のコマンドでログを確認する。

az containerapp logs show \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --type console \ --tail 50

よくある原因は「コンテナの起動コマンドがAzure環境の環境変数と合っていない」「ヘルスプローブのタイムアウトが短すぎて初期化中に失敗判定される」の2つだ。スタートアップ時間が長いアプリには、Liveness ProbeのinitialDelaySecondsを延長するか、Startup Probeを別途設定する。

スケールゼロから復帰するレイテンシが大きい

min-replicas 0 に設定した場合、コールドスタート(0台→1台の起動)に数秒~十数秒かかる。SLAが厳しいエンドポイントでは、--min-replicas 1 に変更してウォームインスタンスを常に1台確保するか、Dedicated Planへの移行を検討する。

カスタムドメインのTLS証明書が発行されない

マネージドTLS証明書が自動発行される条件として、カスタムドメインのDNSレコードがContainer AppsのFQDNに向いている必要がある。CNAMEを設定してから伝播完了(最大48時間)を待ってから証明書の発行操作を行うこと。先に証明書発行を試みてもDNS検証に失敗してエラーになる。

内部Ingressのアプリに別のContainer Appからアクセスできない

内部IngressのアプリのFQDNは appname.internal.xxx.japaneast.azurecontainerapps.io の形式になる。同一Environment内の別アプリからは、このFQDNまたは http://appname(Daprが有効な場合)でアクセスできる。異なるEnvironmentからはプライベートDNSの追加設定が必要になるため、密結合なサービスは同一Environmentに配置する設計が基本だ。

Azure Container Apps入門|AKS・ACIとの違いとサーバーレスコンテナ基盤の設計・料金ガイド - まとめ

まとめ

Azure Container Appsは、「Kubernetesの恩恵を受けながらクラスター管理はしたくない」という現場の要求に応えたサービスだ。特に次のようなシナリオでは第一候補になる。

・マイクロサービスAPIやBFFをコンテナで動かすが、AKSの管理コストを掛けられない
・夜間トラフィックがほぼゼロのAPIサーバーでスケールゼロによるコスト削減を狙いたい
・Service Busやイベントキューをトリガーとする非同期ワーカーを簡単にスケールさせたい
・Daprのpub/sub・サービス呼び出し抽象化をマイクロサービスで活用したい

一方、AKSが適しているのは、StatefulSetやカスタムオペレーター、GPU対応ノード、既存のHelmチャートをそのまま運用したい場合だ。Kubernetesを直接制御する必要があるなら迷わずAKSを選んでほしい。

まず試してみるなら、Consumptionプランで無料枠の範囲から始めれば費用ゼロで動作を確認できる。オンプレからAzureへのコンテナ移行の最初の一歩として、Container Appsは学習コストとコスト効率のバランスが取れた現実的な選択肢だ。

判断ポイント 推奨サービス
バッチ・単発タスク(スケーリング不要) Azure Container Instances
マイクロサービス・APIサーバー・非同期ワーカー Azure Container Apps
大規模・StatefulSet・GPU・Helmチャートをフル制御 Azure Kubernetes Service
HTTPトリガーのイベント処理(軽量・単機能) Azure Functions

PR

Kubernetes完全ガイド 第2版(青山真也/インプレス)

Container Appsの内部はKubernetesが動いている。Pod・Deployment・Service・IngressといったK8sの基礎概念を体系的に習得しておくと、Container Appsのスケーリング設定やRevision管理の理解が格段に深まる。AKSへのステップアップにも必携の一冊だ。

関連記事をもっと読む

同じテーマの記事をまとめています。あわせて読みたい記事はこちらからご覧いただけます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次