メインコンテンツへスキップ
友田 陽大
Azure Container Apps 本番運用
Azure
Container Apps
KEDA
サーバーレス
オートスケール
コスト最適化
信頼性
アーキテクチャ設計

Azure Container Apps オートスケール完全ガイド:KEDAによるゼロスケールとイベント駆動(HTTP・キュー・CPU)

Azure Container AppsのKEDAオートスケールを実コードで徹底解説。HTTP/TCP/カスタム(CPU・メモリ・Service Bus・Event Hubs・Kafka・Redis)の各スケールルール、ゼロスケールの設計と自爆の罠、スケールアルゴリズムによる容量計画、マネージドID認証、ジョブのScaledJobまでを、Microsoft Learn公式に忠実にBicep/az CLIで示します。

公開日
読了時間
10分
著者
友田 陽大
シェア

オートスケールは「設定したつもり」で事故が起きやすい領域です。ゼロスケールしたワーカーが二度と起き上がらない急増トラフィックに台数が追いつかない接続文字列をアプリに直書きしてしまう——どれも、KEDAの挙動を正確に理解していれば防げます。

この記事は、Microsoft Learnの公式スケーリングドキュメントに忠実に、Azure Container Apps(ACA)のオートスケールを容量計画の数式まで踏み込んで解説します。私はAWSでSQS駆動の冪等ワーカーをFargateで本番運用し、本番二重課金0件の決済基盤を作ってきました。スケールはプラットフォームが、正しさはコードの構造(冪等性)が保証する——この分担はAzureでも同じです。ACA全体の本番運用は Azure Container Apps 本番運用ガイド を参照してください。


KEDAとは:ACAのスケールの頭脳

To support this scaling behavior, Azure Container Apps uses KEDA (Kubernetes Event-driven Autoscaling). KEDA supports scaling against a variety of metrics like HTTP requests, queue messages, CPU and memory load, and event sources like Azure Service Bus, Azure Event Hubs, Apache Kafka, and Redis.(— Scaling in Azure Container Apps

ACAのスケールは、レプリカ(リビジョンの実行インスタンス)を水平に増減させること。その判断を KEDA が担います。スケールは3要素の組み合わせです。

  • Limits(上下限):最小・最大レプリカ数(既定0〜10、最大1,000まで設定可)
  • Rules(条件):いつ増減するか(HTTP / TCP / カスタム)
  • Behavior(挙動):ポーリング・クールダウン・刻みなどの時間特性

注意:Vertical scaling isn't supported. 1台を大きくする垂直スケールは不可。負荷対応は台数(水平)だけです。


スケールルール3種:使い分け

カテゴリスケール基準代表的な用途ゼロスケール
HTTP同時HTTPリクエスト数(concurrentRequests、既定10)Web API・Webアプリ
TCP同時TCP接続数(concurrentConnectionsRedis等のTCPプロトコル
Custom(CPU/メモリ)CPU・メモリ負荷計算主体のサービス
Custom(イベント)KEDAスケーラー(Service Bus等)キュー駆動ワーカー

複数ルールを定義すると、the container app begins to scale once the first condition of any rule is met.——どれか1つの条件が満たされた時点でスケール開始します。

HTTPスケール(最も一般的)

15秒ごとに「過去15秒のリクエスト数÷15」で同時リクエスト数を算出します。az CLIなら1行:

az containerapp create \
  --name web-api --resource-group my-rg --environment my-env \
  --image myregistry.azurecr.io/web-api:2026-06-26-a1b2c3d \
  --min-replicas 1 --max-replicas 20 \
  --scale-rule-name http-rule --scale-rule-type http \
  --scale-rule-http-concurrency 100   # 1レプリカあたり同時100リクエストを目標

「1レプリカが快適に捌ける同時リクエスト数」を負荷試験で測り、それをhttp-concurrencyにします。憶測で大きくすると詰まり、小さくすると過剰にスケールしてコストが膨らみます。


ゼロスケール:最大の魅力と2つの罠

ACAの目玉はゼロスケール——アイドル時にレプリカを0にし、その間は課金されません。ただし2つの罠を知らないと事故ります。

罠①:CPU/メモリスケールはゼロにできない

Applications that scale on CPU or memory load can't scale to zero.(— overview

CPU/メモリ負荷を計測するには、そもそもレプリカが動いている必要があるため。ゼロに落としたいなら、HTTPまたはイベント駆動ルールを使う。CPU/メモリルールは「常時最低1台」を前提にします。

罠②:Ingress無効ワーカーの自爆

これが最も多い事故です。

Make sure you create a scale rule or set minReplicas to 1 or more if you don't enable ingress. If ingress is disabled and you don't define a minReplicas or a custom scale rule, your container app scales to zero and has no way of starting back up.(— scale-app

Ingressを無効にしたバックグラウンドワーカーで、最小レプリカ0かつスケールルール無しにすると、0に落ちた後で二度と起き上がれません(リクエストという起こすトリガーが無いから)。対策は2択:

  1. イベント駆動ルールを付ける(キューにメッセージが来たら起きる)← 推奨
  2. minReplicasを1以上にする(常駐させる)
# ✅ 正しい:イベント駆動ワーカーはスケールルールで0から起こす
az containerapp create \
  --name worker --resource-group my-rg --environment my-env \
  --image myregistry.azurecr.io/worker:2026-06-26-a1b2c3d \
  --min-replicas 0 --max-replicas 30 \
  --scale-rule-name sb-rule --scale-rule-type azure-servicebus \
  --scale-rule-metadata "queueName=orders" "namespace=my-sb" "messageCount=5" \
  --scale-rule-identity system   # マネージドIDで認証

容量計画:アルゴリズムを使って逆算する

KEDAのスケールアルゴリズムは公開されており、容量計画に直結します。

挙動
ポーリング間隔30秒(HTTP/TCPには非適用)
クールダウン期間300秒(最後のイベント後、最小レプリカへ落ちるまで)
スケールアップ安定化ウィンドウ0秒
スケールダウン安定化ウィンドウ300秒
スケールアップ刻み1, 4, 8, 16, 32, ...(最大まで)
スケールダウン刻み落とすべきレプリカの100%
アルゴリズムdesiredReplicas = ceil(currentMetricValue / targetMetricValue)

worked example:キュー駆動ワーカーの台数

Service BusキューでmessageCount: 5(1レプリカが捌く目標=5メッセージ)、キュー長が50なら:

desiredReplicas = ceil(50 / 5) = 10 レプリカ

スループット目標から逆算するなら——「1メッセージの処理に2秒」「ピークで毎秒100メッセージ来る」なら、必要スループット=100 msg/s。1レプリカは0.5 msg/s(2秒/件)しか捌けないので、理論上200レプリカ必要。messageCountを小さくすると速く台数が増え(応答性↑・コスト↑)、大きくすると緩やかに増えます(応答性↓・コスト↓)。SLAとコストのトレードオフをmessageCountで調整します。

急増・急減の読み方

  • 急増1 → 4 → 8 → 16 → 32 ... と倍々で増える(安定化0秒なので即応)。
  • 急減スケールダウンは300秒の安定化ウィンドウを満たして初めて起こる。瞬間的な谷では台数を維持し、フラッピング(増減の振動)を防ぐ。
  • ゼロへ:最後のイベントからクールダウン300秒待ってから0に落ちる。

この「上げは即・下げは慎重」という非対称が、可用性を守りつつコストを抑えるKEDAの設計です。AWS Application Auto Scalingのスケールイン保護と同じ思想です。


イベント駆動スケール:KEDAスケーラーの移植

任意のKEDAスケーラーを、ACAのスケールルールに移植できます。KEDAのScaledObject仕様のtypemetadataを、ACAのcustom.typecustom.metadataに写すだけ。

scale: {
  minReplicas: 0
  maxReplicas: 50
  rules: [
    {
      name: 'eventhub-rule'
      custom: {
        type: 'azure-eventhub'         // KEDAスケーラーのtype
        metadata: {
          eventHubName: 'telemetry'
          consumerGroup: '$Default'
          unprocessedEventThreshold: '64'   // 1レプリカあたりの目標未処理イベント数
        }
        identity: 'system'             // マネージドIDで認証
      }
    }
  ]
}

対応イベントソースの例:Azure Service Bus / Event Hubs / Storage Queue / Apache Kafka / Redis ほか多数。

重要:Set the properties.configuration.activeRevisionsMode property of the container app to single when using non-HTTP event scale rules.——**非HTTPのイベントルールではactiveRevisionsModesingle**にします。


認証:シークレットよりマネージドID

KEDAスケーラーは認証情報を必要とします。ACAは2方式をサポートしますが、マネージドIDを優先するのが公式の推奨です。

Where possible, use managed identity authentication to avoid storing secrets within the app.(— scale-app

マネージドID(推奨)

スケールルールにidentityプロパティを指定するだけ。接続文字列をどこにも保存しません。

rules: [
  {
    name: 'azure-queue'
    custom: {
      type: 'azure-queue'
      metadata: {
        accountName: 'mystorage'
        queueName: 'jobs'
        queueLength: '1'
      }
      identity: 'system'   // または ユーザー割当IDのリソースID
    }
  }
]

あとは、そのマネージドIDに対象リソースのデータ権限ロール(例:Azure Service Bus Data ReceiverStorage Queue Data Reader)を付与すれば完了。接続文字列の管理・ローテーションが不要になり、漏洩面が消えます。

シークレット(やむを得ない場合)

接続文字列をアプリのsecretsに置き、スケールルールのauth配列で参照します。Key Vault参照と組み合わせれば、値の直書きは避けられます(詳細は シークレット管理)。


ジョブのスケール:ScaledJob

イベント駆動ジョブも同じKEDAスケーラーを使いますが、使い方が違います

In an app, each replica continuously processes events, and a scaling rule determines the number of replicas to run to meet demand. In event-driven jobs, each job execution typically processes a single event, and a scaling rule determines the number of job executions to run.(— Jobs

  • アプリ:1レプリカが継続的にイベントを処理。スケールルールがレプリカ数を決める。
  • ジョブ:1実行が1イベントを処理して終わる。スケールルールが実行数を決める。

「1イベントごとに専用リソースの新インスタンスが要る」「処理が長時間に及ぶ」ならジョブ、「常駐して流し続ける」ならアプリ、という使い分けです。


スケールの落とし穴と既知の制限

公式が挙げる既知の制限(scale-app):

  • 垂直スケール非対応(台数だけ)。
  • レプリカ数は目標値であって保証ではないReplica quantities are a target amount, not a guarantee.)。
  • Daprアクターで状態管理する場合、ゼロスケール非対応(インメモリ表現がIDと結びつくため)。
  • 複数リビジョンモードでは、新しいスケールトリガーの追加は新リビジョンを作る。旧リビジョンは旧ルールのまま残る。

スケールが効かないときの診断

「スケールしない」と感じたら、システムログで Error fetching scaler metrics を確認します。これはスケールの信号源(DB・Event Hub・別アプリ)に到達できていないサイン。VNet・DNS・ファイアウォール・権限を確認します(トラブルシューティングガイド)。


本番設計:スケール×冪等性

オートスケールを本番品質にする鍵は、スケールと正しさを分けて設計することです。

  • スケールはプラットフォーム:KEDAが台数を決める。あなたはmessageCountやHTTP同時実行数という「1台あたりの目標」を測って設定するだけ。
  • 正しさはコードの構造:スケールイン(SIGTERMで30秒以内に終了)やリトライでメッセージが再配信されても壊れないよう、ワーカーを冪等に作る。同じメッセージを2回処理しても二重課金しない——冪等性キーで重複を吸収します。

この分担を徹底すれば、ゼロスケールしても取りこぼしも二重実行も起きない。決済基盤で本番二重課金0件を達成した設計の核がこれです。


まとめ

ACAのオートスケールはKEDAが担い、HTTP・TCP・CPU/メモリ・多数のイベントソースで水平スケールします。本番で効かせる勘所は4つ——

  1. ゼロスケールの2つの罠(CPU/メモリは0不可、Ingress無効ワーカーの自爆)を回避する。
  2. アルゴリズムで容量を逆算する(messageCountがSLAとコストの調整ノブ)。
  3. 認証はマネージドID優先で接続文字列をアプリから消す。
  4. スケール×冪等性——スケールはKEDA、正しさはコードの構造で。

オートスケールの設計・チューニングから、キュー駆動ワーカーの冪等化まで、ご相談はお問い合わせへ。本番運用全体は Azure Container Apps 本番運用ガイド をどうぞ。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事で解説した技術の適用事例

経済産業大臣賞受賞 | 木材流通業界のDXを実現したB2BサブスクリプションSaaS

ケーススタディを見る