Azure Container Apps での .NET の概要

Azure Container Apps のようなクラウド ネイティブ環境に .NET アプリケーションをデプロイするには、アプリケーションが円滑で安全に実行されるよう、いくつかのことを決める必要があります。 このガイドでは、Azure Container Apps への .NET アプリケーションのデプロイに関連する主要な概念について説明します。

Azure Container Apps はフル マネージドのサーバーレス コンテナー サービスであり、基になるインフラストラクチャを管理する必要なしに、コンテナー化されたアプリケーションを実行できます。 Container Apps には、自動スケーリング、正常性チェック、トランスポート層セキュリティ (TLS) 証明書などの機能が組み込まれています。

この記事では、Azure Container Apps に .NET アプリケーションをデプロイするときに重要な概念と留意すべきことについて詳しく説明します。

リソースの種類を選択する

Container Apps では、アプリとジョブの 2 種類のリソースがサポートされています。 アプリが継続的に実行されるサービスであるのに対し、ジョブは短時間で実行が完了するように設計されたタスクです。

これらの動作は .NET アプリケーションの管理方法に影響するので、アプリのデプロイを準備するときは、これら 2 つのアプリケーションの種類の違いを考慮してください。 次の表では、アプリとジョブでのユース ケースの違いについて説明します。

ユース ケース リソースの種類
HTTP 要求を処理する ASP.NET Core Web API アプリ
何らかのデータを処理してから終了する .NET Core コンソール アプリケーション ジョブ
キューからのメッセージを処理する継続的に実行されるバックグラウンド サービス アプリ
大きなイメージがストレージ アカウントに保存される場合にのみ実行されるイメージ最適化サービス。 ジョブ
Hangfire、Quartz.NET、Azure WebJobs SDK などの、フレームワークを使用するアプリケーション アプリ

.NET アプリケーションをコンテナー化してデプロイする

アプリでもジョブでも、.NET アプリケーションをパッケージ化するにはコンテナー イメージをビルドする必要があります。 コンテナー イメージのビルドについては、「ASP.NET Core 向けの Docker イメージ」をご覧ください。

セットアップが済んだら、次のガイドに従って、アプリケーションを Azure Container Apps にデプロイできます。

HTTP イングレスを使用する

Azure Container Apps に組み込まれている HTTP イングレスを使うと、コンテナーの外部からのトラフィックにアプリを公開できます。 Container Apps のイングレスは、アプリとエンド ユーザーの間に配置されます。 イングレスは仲介役として機能するため、エンド ユーザーが目にするものは最後にイングレスを通過し、アプリが認識するものは最初にイングレスを通過します。

イングレスが TLS 終端とカスタム ドメインを管理するので、ユーザーがアプリでそれらを手動で構成する必要はありません。 イングレスを介して、HTTPS トラフィックにはポート 443 が公開され、HTTP トラフィックが必要な場合はポート 80 が公開されます。 イングレスは、アプリにそのターゲット ポートで要求を転送します。

アプリで元の要求に関するメタデータが必要な場合は、X-forwarded ヘッダー を使用できます。

詳しくは、Azure Container Apps での HTTP イングレスに関する記事をご覧ください。

ターゲット ポートを定義する

トラフィックを受信するには、アプリがトラフィックをリッスンするターゲット ポートでイングレスを構成します。

ASP.NET Core がコンテナーで実行されている場合、アプリケーションはコンテナー イメージで構成されているポートをリッスンします。 正式な ASP.NET Core イメージを使うときは、アプリは既定のポートで HTTP をリッスンするように構成されます。 既定のポートは、ASP.NET Core のバージョンによって異なります。

Runtime ターゲット ポート
ASP.NET Core 7 以前 80
ASP.NET Core 8 以降 8080

イングレスを構成するときに、使っているコンテナー イメージに対応する番号にターゲット ポートを設定します。

X-forwarded ヘッダーを定義する

イングレスが元の HTTP 要求を処理するので、アプリからはイングレスはクライアントに見えます。 アプリで元のクライアントの IP アドレスまたは元のプロトコル (HTTP または HTTPS) を知る必要がある場合があります。 プロトコルと IP の情報には、要求の X-Forwarded-* ヘッダーを介してアクセスできます。

ForwardedHeaders オブジェクトにアクセスして、これらのヘッダーから元の値を読み取ることができます。

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

要求のヘッダーの処理について詳しくは、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」をご覧ください。

クラウドネイティブの .NET アプリケーションを構築する

多くの場合、Container Apps にデプロイされるアプリケーションは、クラウドネイティブの原則の基礎に基づいて構築すると最適に動作します。 次のセクションでは、クラウドネイティブ アプリケーションについて留意すべき一般的な事柄について詳しく説明します。

アプリケーションの構成

.NET アプリケーションを Azure Container Apps にデプロイする場合は、構成情報の格納には、appsettings.json ではなく環境変数を使います。 この方法を使うと、アプリケーションを異なる環境では異なる構成にできます。 さらに、環境変数を使うと、コンテナー イメージをリビルドして再デプロイする必要がなくなり、構成値の管理が容易になります。

Azure Container Apps では、アプリまたはジョブのコンテナーを定義するときに環境変数を設定します。 機密の値は、シークレットに格納し、環境変数としてそれを参照します。 シークレットの管理について詳しくは、「Azure Container Apps でシークレットを管理する」をご覧ください。

マネージド ID

Azure Container Apps ではマネージド ID がサポートされており、アプリでそれを使うと、資格情報を交換することなく、他の Azure サービスにアクセスできます。 Azure サービス間での安全な通信について詳しくは、「Azure Container Apps のマネージド ID」をご覧ください。

ログ機能

クラウドネイティブ環境でのアプリケーションの監視とトラブルシューティングには、ログが不可欠です。 既定では、Azure Container Apps は Azure Log Analytics を使ってコンテナーからログを収集します。 他のログ プロバイダーを構成できます。 アプリケーションのログについて詳しくは、「Azure Container Apps のログ ストレージと監視オプション」をご覧ください。

コンソールにログを書き込むログ プロバイダーを構成すると、Azure Container Apps によって自動的にログ メッセージが収集されて格納されます。

正常性プローブ

Azure Container Apps に組み込まれている正常性プローブのサポートを使うと、アプリケーションの正常性を監視できます。 プローブによってアプリケーションが異常な状態であると判断された場合、コンテナーは自動的に再起動されます。 正常性プローブについて詳しくは、「Azure Container Apps の正常性プローブ」をご覧ください。

アプリケーションの正常性を判断するためのカスタム ロジックを実装するには、正常性チェック エンドポイントを構成できます。 正常性チェック エンドポイントについて詳しくは、「ASP.NET Core の正常性チェック」をご覧ください。

自動スケーリングに関する考慮事項

既定では、Azure Container Apps は、着信した HTTP 要求の数に基づいて、ASP.NET Core アプリを自動的にスケーリングします。 CPU やメモリの使用量など、他のメトリックに基づくカスタム自動スケーリング ルールを構成することもできます。 スケーリングについて詳しくは、「Azure Container Apps でスケーリング ルールを設定する」をご覧ください。

.NET 8.0.4 以降では、データ保護を使用する ASP.NET Core アプリは、アプリケーションがスケーリングされる中で、保護されたデータが常にすべてのレプリカからアクセスできるよう、自動的に構成されます。 アプリのスケーリングが開始されると、キー マネージャーで、複数のリビジョンにわたってキーの書き込みと共有が行われます。 アプリがデプロイされると、この機能を有効にするために、環境変数 autoConfigureDataProtection が自動的に true に設定されます。 この自動構成の詳細については、こちらの GitHub pull request を参照してください。

自動スケーリングでは、ユーザーが定義したルールに基づいて、アプリのレプリカの数が変更されます。 既定では、Container Apps は着信トラフィックを ASP.NET Core アプリのレプリカにランダムにルーティングします。 トラフィックが異なるレプリカに分かれる可能性があるため、アプリケーションで状態関連の問題が発生しないように、アプリはステートレスにする必要があります。

偽造防止、認証、SignalR、Blazor Server、Razor Pages など、データ保護に依存する機能では、複数のレプリカにスケーリングしても正しく機能するように追加の構成が必要です。

データ保護を構成する

ASP.NET Core には、セッション データや偽造防止トークンなど、データの保護と保護解除を行う特別な機能があります。 既定では、データ保護キーは、クラウドネイティブ環境には適さないファイル システムに格納されます。

.NET Aspire アプリケーションをデプロイする場合、データ保護は自動的に構成されます。 それ以外のすべての状況では、データ保護を手動で構成する必要があります。

ASP.NET Core SignalR を構成する

ASP.NET Core SignalR では、複数のサーバー レプリカにメッセージを分散させるためにバックプレーンが必要です。 SignalR を使って Azure Container Apps に ASP.NET Core アプリをデプロイするときは、Azure SignalR Service や Redis など、サポートされているバックプレーンのいずれかを構成する必要があります。 バックプレーンについて詳しくは、「ASP.NET Core SignalR のホスティングとスケーリング」をご覧ください。

Blazor Server を構成する

ASP.NET Core Blazor Server アプリはサーバーに状態を格納します。つまり、各クライアントは、セッションの間、同じサーバー レプリカに接続されている必要があります。 Blazor Server アプリを Azure Container Apps にデプロイするときは、スティッキー セッションを有効にして、クライアントが同じレプリカに確実にルーティングされるようにする必要があります。 詳しくは、「Azure Container Apps でのセッション アフィニティ」をご覧ください。