0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PR: NECイノベーションコミュニティ
技術で挑む価値づくり

Azure Container Appsとコンテナの学び直し

0
Last updated at Posted at 2026-10-04

はじめに

近頃、Azure Container Apps(以下 ACA)や ACA Jobs を利用する機会が増えてきましたが、「なんとなく動いているから大丈夫( ー`дー´)キリッ」で済ませてしまっている部分も少なくない。
今回自分の理解を棚卸し再学習する意味も込めて、ACAの基本機能を整理した上でKubernetes(k8s)がACAではどう扱われている(あるいは扱われていない)のかも合わせて確認していこうと思います。

とは云え、k8sも全く詳しいわけではなく、以前にしくみがわかるKubernetes Azureで動かしながら学ぶコンセプトと実践知識 (翔泳社)を読んだレベルです。

ACAの全体像

まずACAの全体的な構成を見てみる。

Container Apps 環境という境界

ACAは単体のコンテナではなく、Container Apps 環境(Environment) というAzureリソースの中で動作する。Container Apps 環境は1つ以上のコンテナー アプリおよびコンテナー アプリ ジョブをまとめて囲む境界であり、同じContainer Apps 環境の中にあるアプリ同士は仮想ネットワークとログの送信先を共有する。

Container Apps 環境は下表の2種類。

環境タイプ 特徴 最小サブネットサイズ
ワークロードプロファイル(既定) 独自ルーティングやPrivate Endpointの作成に対応 /27
従量課金のみ(レガシー) 独自ルーティングやPrivate Endpointの作成は非対応 /23

Azure Container Apps環境でのネットワーク

Azure既定のネットワークを使うか、自分で用意した仮想ネットワークを使うかは、Container Apps 環境を作った後からは変更できないので、閉域化(後述)が要件にあるなら最初から自分の仮想ネットワークを指定して作る必要がある。

アプリとジョブの使い分け

ACAには「コンテナー アプリ」と「コンテナー アプリ ジョブ」という2種類の実行単位がある。文字通りで常時稼働させ外部からのリクエストに対するオンライン処理はコンテナー アプリ、手動・スケジュール・イベントをトリガに、決まった処理をして終わったら止まってよいバッチ処理はコンテナー アプリ ジョブを選択する。
なお、次章で説明するIngressや後述のDaprは、現時点でコンテナー アプリ ジョブでは使えない。

Ingressの構造

Ingressは、クラスターの外からクラスターの中のサービスへHTTP/HTTPSの通信を届けるための仕組みのこと。
ACAではこの仕組みが完全にマネージド化されていて、開発者は難しい設定をせずに「外部に公開するか」「内部だけに公開するか」を選ぶだけで済むが、関連すべき箇所が2か所ある。

1つ目はContainer Apps 環境自体の公開範囲で、Container Apps 環境のネットワーク設定において、パブリックアクセスの有効・無効を設定できる。
2つ目はコンテナー アプリごとの公開範囲で、Container Apps 環境の境界の中でさらに「どこからでもトラフィックを受け入れます(Container Apps 環境経由で届く)」か「Container Apps 環境に限定(同じContainer Apps 環境内の他アプリからのみ到達できる)」かをアプリ単位で選べる。

Ingressを有効にすると、HTTPかTCPかの選択、独自ドメインの設定、特定IPからのみ許可する制限、クライアント証明書による認証、新旧バージョン間のトラフィック分割なども同じ設定の中で行える。

なお、Container Apps 環境を後述する閉域構成にするためプライベートエンドポイントや仮想ネットワーク統合を行う場合は後から変更ができず、Container Apps 環境を最初に構成する際に設定しておく必要がある。

設定箇所:

  • Container Apps 環境 → ネットワーク
  • コンテナー アプリ → ネットワーク → イングレス

前段に何を置くか

ACA単体のIngressにもTLSの終端や独自ドメインの機能はあるが、WAF(Web攻撃対策)やグローバル配信、URLパスによる振り分けが必要な場合は、前段に別のAzureネットワークサービスを置く。エンタープライズシステムにおいてパブリックに公開する際には必須で考えるべきで、代表的なパターンを示す。

  • Application Gateway(WAF)を前段に置く:ACAをインターネットから直接見えない内部公開の状態にし、Application GatewayをACAの手前に立ててWAFとして機能させる構成。アクセス制御やリクエストの中身のチェックを前段でまとめて行える。Azure Container Apps環境と Azure Firewall の統合
  • Azure Front Door + Private Linkで閉域公開する:ACA側のインターネットからの着信を完全に止めたうえで、Front DoorからACAへ専用の非公開経路(Private Link)をつなぐ構成。世界中への配信をしつつ、ACA自体はインターネットに一切公開しない。

いずれの構成でもACA自体をインターネットに直接さらさず、前段のサービスだけを公開窓口にしている。より強固にDMZ用仮想ネットワークを構成すべきであるが、ACAに限った構成ではないので割愛。

Dapr

 
Dapr(Distributed Application Runtime・ダパー)は、マイクロサービス向けのよくある処理(サービス同士の呼び出し、状態の保存、メッセージのやり取りなど)を、アプリケーションのコードを複雑にせずに利用できるようにするランタイムである。
 
ACAではDaprがネイティブ統合されており、Daprを有効化すると各レプリカ内に Dapr Sidecar(サイドカーコンテナー) が自動的に追加される。アプリケーションは外部サービスと直接通信する代わりに、同じレプリカ内で動作しているDapr Sidecarとローカル通信を行い、Dapr Sidecarが他のコンテナー アプリや各種サービスとの通信を仲介する。
 

機能 できること
サービス呼び出し 他のアプリを、通信の暗号化や認証を意識せず呼び出せる
状態管理 キー・バリュー形式でデータを保存・取得できる
Pub/Sub メッセージを発行・購読できる
バインディング 外部サービス(キューなど)と連携できる
シークレット 秘密情報を安全に取得できる

なお、Daprは仕組み全体の名称であり、実際に各レプリカ内で動作している実体がDapr Sidecarである。どのアプリがどのDapr機能を利用できるかは、Dapr App ID(アプリケーション識別子)によって管理される。

設定箇所:

  • Container Apps 環境 → 設定 → Dapr コンポーネント
  • コンテナー アプリ → 設定 → Dapr

設定の渡し方(ConfigMapとの違い)

k8sにはConfigMapという、アプリの設定値をコードから切り離して外部から渡すための仕組みがある。パスワードなどの機密情報は別の仕組み(Secret)に入れ、ConfigMapには機密ではない設定だけを入れる、という使い分けが基本になる。
が、ACAには「ConfigMap」という独立した設定オブジェクトは存在しない。代わりに下表のようになる。

用途 k8sでの呼び方 ACAでの渡し方
機密でない設定値 ConfigMap コンテナーの環境変数に直接指定
機密値(パスワード等) Secret アプリ側のSecrets機能を利用(値を直接指定、またはキー コンテナーのシークレットを参照)

つまりACAでは、機密でない設定は普通の環境変数として渡し、機密な値だけをSecretsという専用の仕組みに寄せる。複数のアプリで設定値を一元管理したい場合は、Azure App Configurationのようなサービスと別途、組み合わせる。

設定箇所:

  • コンテナー アプリ → セキュリティ → シークレット
  • コンテナー アプリ ジョブ → 設定 → シークレット

信頼性

ここから可用性・信頼性、セキュリティ、運用性と云った非機能要件に対応する部分を、重要度が高そうな順に見ていく。まず信頼性から。

アプリのヘルスチェック

ACAには、アプリが正常に動いているかを定期的にチェックする仕組みが用意されている。

チェックの種類 確認すること 失敗したときの挙動
起動(Startup) 起動が無事に完了したか 完了するまで次の2つのチェックは始まらない
稼働(Liveness) 動き続けているか・応答できているか コンテナーを自動で再起動する
対応性(Readiness) 今リクエストを受けてよい状態か 再起動はせず、一時的にアクセスを振り分けない

Azure Container Apps の正常性プローブ

何も設定しなくても、Ingressを有効にしていればアプリに最低限のチェックが自動で付く。ただし、コンテナーが複数ある構成の場合はメインのコンテナー以外には自動で付かないため、必要なら自分で追加する。

設定箇所:

  • コンテナー アプリ → アプリケーション → コンテナー → 正常性プローブ
  • コンテナー アプリ ジョブ → 設定 → コンテナー → [デプロイ済みのコンテナー名] → 正常性プローブ

全断させない仕組み

k8sでは、レプリカを複数のマシン(ノード)へ分散配置したり、保守作業中も一定数のレプリカを稼働させ続けたりするための設定があり、代表的なものが PodAntiAffinity と PodDisruptionBudget である。
が、ACAにはこれらに相当するユーザーが設定する項目はない。
その代わり、最小レプリカ数を満たしながら複数のコピーをなるべく別の場所に分散させる処理や、アップグレード・メンテナンス時には新しいコピーを先に用意してからトラフィックを切り替え、古いコピーを後から片付ける処理をプラットフォーム側が自動で行う。
Azure Container Apps の信頼性
開発者が細かく設定できない代わりに、何も設定しなくても一定の安全策が標準で効いている。

認証まわり、機密性

続いて認証まわりとシークレットに関わる部分で、Azureにおけるk8s実装であるAKS(Azure Kubernetes Service)との違いに焦点を当てて見てみる。

アプリへの権限付与

コンテナアプリやジョブから他のAzureサービスにアクセスする際に「どのアプリやジョブに何を許可するか」を管理するためには、実行主体を識別する仕組みが必要になる。

ACAではシステム割り当てマネージド ID またはユーザー割り当てマネージド ID を利用できる。コンテナー アプリやコンテナー アプリ ジョブにマネージド ID を割り当てると、Microsoft Entra ID 上の識別情報が付与され、その識別情報に対して Azure RBAC で権限を割り当てられる。

このマネージド ID に、例えば ACR Pull ロールを付与すればコンテナーイメージを取得でき、Key Vault Secrets User ロールを付与すればシークレットを参照できる。

なお、AKSでは同じ目的を実現する仕組みとして Microsoft Entra Workload ID が利用できる。Workload ID は Kubernetes の Pod と Microsoft Entra ID を関連付け、Azure リソースへのアクセス権を付与する。
ACAを利用するうえで Workload ID を意識する場面はほとんどなく、Azure リソースへのアクセス制御は主にマネージド ID を利用して行う。

設定箇所:

  • コンテナー アプリ → セキュリティ → ID
  • コンテナー アプリ ジョブ → 設定 → ID

利用者認証

前節のマネージド ID は、アプリ自身が Azure サービスへアクセスするための仕組みである一方、アプリの利用者を認証する仕組みとして OpenID Connect(OIDC)がある。
ACA、App Service、関数アプリ では認証機能(いわゆる Easy Auth)を利用でき、Microsoft Entra ID、Google、GitHub などの認証プロバイダーや、任意の OIDC 対応 ID プロバイダーと連携できる。

設定箇所:

  • コンテナー アプリ → セキュリティ → 認証

シークレットの扱い方

k8sにはSecrets Store CSI Driverという、キー コンテナのような外部の秘密情報管理サービスに預けた値を、Podの中にファイルとして届ける仕組みがある。AKSではこの仕組み用の追加機能が用意されており、専用の身分証を自動で作ってキーコンテナにアクセスし、値の自動更新にも対応している。
ACAではこの「Secrets Store CSI Driver」という仕組み自体が存在しない代わりに、アプリのSecrets機能の中でキー コンテナの値を直接参照できる機能を持っており、キーコンテナのURLと前述のマネージドIDを指定するだけで、環境変数やファイルとして秘密情報を使える。
Azure Container Appsでシークレットを管理する

設定箇所:

  • コンテナー アプリ → セキュリティ → シークレット
  • コンテナー アプリ ジョブ → 設定 → シークレット

ネットワークセキュリティ

エンタープライズでは必須のネットワークセキュリティを少し見ていく。

通信要件制御

k8sにはNetworkPolicyという、どのアプリ同士が通信してよいかを細かく制御する仕組みがある。これによりアプリ単位の非常に細かい粒度で通信の可否を決められる。
が、ACAにはこの粒度での細かい通信制御機能はなく、Container Apps 環境単位・サブネット単位という、もう少し大きな単位で通信を分離する必要がある。

閉域構成の基本

ACAをインターネットに出さない閉域構成にする場合の基本方針は、

  1. 仮想ネットワークに参加させて通信経路を制御すること
  2. Private Endpointを使ってインターネットを経由せずにアクセスできるようにすること
  3. Container Apps 環境を内部公開にして仮想ネットワーク内のアクセスだけに限定すること

を行う。仮想ネットワーク統合を行うため、他のサービスと共用不可のContainer Apps 環境専用のサブネットが必要である。
Azure Container Apps環境でのネットワーク

クロスオリジンの許可設定

CORS(Cross-Origin Resource Sharing)は、ブラウザから別オリジン(スキーム・ホスト名・ポートのいずれかが異なるURL)へアクセスする際に、そのアクセスを許可するかどうかをブラウザへ通知するための仕組みである。
例えば、利用者が フロントエンドhttps://portal.contoso.com にアクセスし、その画面上の JavaScript が別オリジンである https://app.contoso.com 上の ACA へアクセスする場合を考える。

CORS エラーは、ACA が正常に応答を返していても、ブラウザが Access-Control-Allow-Origin ヘッダーを確認した結果、アクセスを遮断する場合がある。
そのため、Postman や curl では正常にアクセスできるにも関わらず、ブラウザからは CORS エラーになるケースが発生する。

ACA ではポータルから以下の項目を設定できる。

設定項目 内容
資格情報の許可 Cookie などを含むリクエストを許可するか
キャッシュ時間 プリフライトリクエストの結果を保持する時間
許可するアクセス元 どのオリジンからのアクセスを許可するか
許可するメソッド GET、POST などの許可対象メソッド
許可するヘッダー 利用可能な HTTP ヘッダー
公開するヘッダー ブラウザへ公開する HTTP ヘッダー

実運用のシーンでは許可するアクセス元を*にせず、必要なドメインだけを明示的に許可する。

設定箇所:

  • コンテナー アプリ → ネットワーク → CORS

運用性

最後に、オペレーションエクセレンスにつながる運用の観点を見てみる。

利用リソースの閾値

k8sにはLimitRangeという、ある単位の中でアプリが使ってよいCPU・メモリの上限や、設定し忘れたときの初期値を一括で決めておく仕組みがある。これにより、1つのアプリが使えるリソースを無制限にしてしまい、他のアプリに影響を与えることを防ぐ。
ACAにはLimitRangeに相当する「一括設定」の仕組みはなく、代わりに2つのレベルでリソースを管理する。

  1. アプリ(コンテナー)単位:CPU・メモリの使用量をアプリごとに直接指定
  2. Container Apps 環境・サブスクリプション単位:Azure Container Apps のクォータ
    における上限

「グループ単位での自動的な初期値・上限の割り当て」をしてくれるk8sに対し、ACAはアプリごとに自分で指定することになる。

設定箇所:

  • コンテナー アプリ → アプリケーション → コンテナー → プロパティ → コンテナー リソースの割り当て
  • コンテナー アプリ ジョブ → 設定 → コンテナー → [デプロイ済みのコンテナー名] → プロパティ → コンテナー リソースの割り当て

ログ・メトリックの送信先

ACA および ACA Jobs では、ログ・メトリック・トレースを収集できる。

種類 主な内容 主な保存先
ACAプラットフォームログ コンテナ起動、スケール、Ingress、KEDA、ヘルスチェック等 Log Analytics
アプリケーションログ アプリやジョブが stdout / stderr に出力したログ Log Analytics
OpenTelemetryログ SDKから送信したログ Application Insights、Datadog等
OpenTelemetryメトリック カスタムメトリック Datadog等
OpenTelemetryトレース 分散トレーシング Application Insights、Datadog等

ACAプラットフォームログやアプリケーションログは Container Apps 環境に紐付けた Log Analytics ワークスペースへ送信される。一方、OpenTelemetry で収集するログ・メトリック・トレースは送信先を選択できる。

送信先 ログ メトリック トレース
Application Insights ○ × ○
Datadog、New Relic等 ○ ○ ○

上表にある通り、Application Insights は OpenTelemetry メトリックを受け取れない。メトリックも含めて一元管理したい場合は、Datadog など OpenTelemetry メトリックに対応したバックエンドを検討する必要がある。

また、機能を有効化しただけではトレースやカスタムメトリックは収集されない。アプリケーションやジョブ側で OpenTelemetry SDK を利用し、ログ・メトリック・トレースを送信するための計装を実装する必要がある。

設定箇所:

  • Container Apps 環境 → 監視 → ログオプション
  • Container Apps 環境 → 監視 → OTel エンドポイント

メトリックの可視化(Grafanaダッシュボード)

ACA には Azure Portal から利用できる事前構築済みの Grafana ダッシュボード(プレビュー)が用意されている。

利用できるダッシュボードは次の 2 種類である。

ダッシュボード 内容
Container App Dashboard コンテナーアプリ単位の CPU 使用率、メモリ使用量、リクエスト数、レプリカ数などを表示
Environment Dashboard Container Apps 環境全体の利用状況やリビジョン情報、レプリカ数などを表示

Grafana ダッシュボードは Azure Monitor Metrics を可視化する機能であり、Log Analytics 上のログを表示しているわけではない。

そのため Grafana は負荷状況やスケール動作の確認に利用し、アプリケーションログやシステムログの分析には Log Analytics を利用する、という使い分けになる。

設定箇所:

  • Container Apps 環境 → 監視 → Grafana を使用したダッシュボード
  • コンテナー アプリ → 監視 → Grafana を使用したダッシュボード

負荷に応じた自動増減

k8sにはHorizontalPodAutoscalerという、CPU使用率などの指標をもとにアプリのコピー数を自動で増減させる仕組みがある。
ACAではこの仕組みをそのまま使うのではなく、KEDA(Kubernetes Event-driven Autoscaling)という拡張の仕組みを採用している。

Azure Container Appsでスケーリング ルールを設定する

スケールの判断材料は、同時アクセス数・同時接続数・キューのメッセージ数などのイベント・CPUやメモリの使用率、と幅広く選べる。k8s標準の仕組みとの大きな違いは、アクセス数やイベントを基準にする場合はコピー数をゼロまで減らせる点である。(CPU・メモリの使用率だけを基準にする場合、最低1つは動かしておく必要がある)。
また、1つのコピーに割り当てるリソースを動的に増やす、という方向のスケールはできず、増減は常にコピーの数で行う。

設定箇所:

  • コンテナー アプリ → アプリケーション → スケーリング
  • コンテナー アプリ ジョブ → スケーリングとレプリカ

まとめ

今回あらためて整理して個人的にも、ACA、ACA Jobsの理解が進みました。多くの機能が簡素化、あるいはプラットフォームが裏側で自動的にやってくれる挙動として組み込まれています。
コンテナアプリケーションまたはジョブ実行基盤として選択する際に設計の一助になってくれたら幸いです。

ここまでお読みくださりありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?