この記事では、AppHost プロジェクトでコードを記述して、リソースの動作をさらにカスタマイズする方法について説明します。 Aspireでは、リソースはクラウドネイティブ アプリケーションの依存部分です。 リソースの種類は次のとおりです。
- .NET プロジェクト: カスタム マイクロサービス。クラウドネイティブ アプリケーションの特定の機能を担当し、多くの場合、別の開発者チームによって構築されます。
- 実行可能ファイル: Node.js や Orleansなどのツールを使用してマイクロサービスを構築する必要がある場合は、実行可能リソースとして実行されます。
- コンテナー: 特定のイメージに基づいて Docker コンテナーを Aspire ソリューションに追加できます。
- 統合リソース: 多くの場合、統合によって、データベース、キャッシュ、メッセージング サービスなどのリソースがアプリケーションに追加されます。
- 外部サービス: アプリケーションが依存しているが、 Aspireによって管理されていないサードパーティの API またはサービスを表します。 これは、パブリック API や SaaS エンドポイントなどのリソースに使用します。
Aspireオーケストレーションの基礎とリソースの管理方法については、オーケストレーションの概要Aspire参照してください。
リソースの名前付け規則
Aspire内のリソースは、Aspireによって設定された名前付け制限と、リソースが表すテクノロジに従う必要があります。 たとえば、 Aspire リソースの名前の最大長は 64 文字ですが、 Azure Container App の最大長は 32 です。 AspireのAzure コンテナー リソースを発行する場合、名前の長さは 32 文字以下にする必要があります。
Aspire リソース名は、次の基本規則に従う必要があります。
- 長さは 1 ~ 64 文字にする必要があります。
- ASCII 文字で始まる必要があります。
- ASCII 文字、数字、ハイフンのみを含める必要があります。
- ハイフンで終わる必要はありません。
- 連続するハイフンを含めてはなりません。
明示的なリソース開始を設定する
既定では、プロジェクト、実行可能ファイル、およびコンテナー リソースは、分散アプリケーションで自動的に開始されます。 リソースは、WithExplicitStart メソッドを使用して明示的なスタートアップ命令を待機するように構成できます。 WithExplicitStart で構成されたリソースは、KnownResourceStates.NotStartedで初期化されます。
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
builder.AddProject<Projects.AspireApp_DbMigration>("dbmigration")
.WithReference(postgresdb)
.WithExplicitStart();
上記のコードでは、 "dbmigration" リソースは、分散アプリケーションで自動的に開始されないように構成されています。
明示的に開始されたリソースは、 Aspire ダッシュボードで [開始] コマンドをクリックして開始できます。 詳細については、「 Aspire ダッシュボード: リソースの停止または開始」を参照してください。
リソース待ち
場合によっては、別のリソースを開始する前に、リソースの準備が整うのを待つ必要がある場合があります。 たとえば、データベースに依存する API を開始する前に、データベースの準備が整うのを待つ必要がある場合があります。 この依存関係を表すには、WaitFor メソッドを使用します。
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(postgresdb)
.WaitFor(postgresdb);
前のコードでは、"apiservice" プロジェクト リソースは、"postgresdb" データベース リソースが KnownResourceStates.Running 状態になるまで待機します。 コード例は、AspirePostgreSQL 統合を示していますが、同じパターンを他のリソースに適用できます。
その他のケースでは、依存リソースが開始される前に、KnownResourceStates.Exited または KnownResourceStates.Finished のいずれかで、リソースの実行が完了するまで待機することが必要になる場合があります。 リソースの実行が完了するまで待機するには、WaitForCompletion メソッドを使用します。
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
var migration = builder.AddProject<Projects.AspireApp_Migration>("migration")
.WithReference(postgresdb)
.WaitFor(postgresdb);
builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(postgresdb)
.WaitForCompletion(migration);
前のコードでは、"apiservice" プロジェクト リソースは、"移行" プロジェクト リソースが完了するまで待機してから開始します。 "移行" プロジェクト リソースは、"postgresdb" データベース リソースが KnownResourceStates.Running 状態になるまで待機します。 これは、たとえば、API サービスを開始する前にデータベース移行を実行するシナリオで役立ちます。
ダッシュボードでリソースを強制開始する
リソースの待機は、ダッシュボードの [開始 ] コマンドを使用してバイパスできます。 ダッシュボードで [待機中のリソースで 開始 ] を選択すると、リソースが正常または完了するのを待たずにすぐに開始するように指示されます。 これは、リソースをすぐにテストし、アプリが正しい状態になるまで待たないようにする場合に便利です。
リソースを追加および表現するための API
Aspire ホスティング統合 と クライアント統合は どちらも NuGet パッケージとして提供されますが、さまざまな目的に対応します。 クライアント統合では AppHost の範囲外でアプリを使用するためのクライアント ライブラリ構成が提供されますが、ホスティング統合では、AppHost 内のリソースと依存関係を表現するための API が提供されます。 詳細については、「 Aspire 統合の概要: 統合の責任」を参照してください。
エクスプレス コンテナ リソース
ContainerResource を表現するには、IDistributedApplicationBuilder メソッドを呼び出して AddContainer インスタンスに追加します。
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithBindMount("ollama", "/root/.ollama")
.WithBindMount("./ollamaconfig", "/usr/config")
.WithHttpEndpoint(port: 11434, targetPort: 11434, name: "ollama")
.WithEntrypoint("/usr/config/entrypoint.sh")
.WithContainerRuntimeArgs("--gpus=all");
詳細については、
上記のコードは、イメージ ollama/ollamaを持つ "ollama" という名前のコンテナー リソースを追加します。 コンテナー リソースは、複数のバインド マウント、名前付き HTTP エンドポイント、Unix シェル スクリプトに解決されるエントリ ポイント、および WithContainerRuntimeArgs メソッドを使用したコンテナー実行引数で構成されます。
コンテナー リソースをカスタマイズする
すべての ContainerResource サブクラスは、特定の要件を満たすようにカスタマイズできます。 これは、コンテナー リソースをモデル化するが変更が必要な ホスティング統合 を使用する場合に便利です。
IResourceBuilder<ContainerResource> がある場合は、使用可能な API の呼び出しをチェーンしてコンテナー リソースを変更できます。
Aspire コンテナー リソースは通常、ピン留めされたタグを指しますが、代わりに latest タグを使用することもできます。
これを例示するために、AspireRedis 統合を使用しているシナリオを想像してください。
Redis 統合が 7.4 タグに依存していて、代わりに latest タグを使用する場合は、WithImageTag API の呼び出しをチェーンできます。
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache")
.WithImageTag("latest");
// Instead of using the "7.4" tag, the "cache"
// container resource now uses the "latest" tag.
使用可能なその他の API の詳細については、「ContainerResourceBuilderExtensions」を参照してください。
コンテナー リソースのライフサイクル
AppHost を実行すると、 ContainerResource を使用して、作成して開始するコンテナー イメージが決定されます。 内部 Aspire、Docker または Podmanのいずれかの適切な OCI 準拠コンテナー ランタイムへの呼び出しを委任することで、定義されたコンテナー イメージを使用してコンテナーを実行します。 次のコマンドが使用されます。
まず、docker container create コマンドを使用してコンテナーを作成します。 次に、docker container start コマンドを使用してコンテナーが開始されます。
- docker コンテナーの作成: 指定したイメージから開始せずに新しいコンテナーを作成します。
- docker コンテナを起動: 1つ以上の停止したコンテナを起動します。
これらのコマンドは、接続されたコンテナー ネットワーク、ボリューム、ポートを管理するために docker run の代わりに使用されます。 これらのコマンドをこの順序で呼び出すと、初期起動時に IP (ネットワーク構成) が既に存在できるようになります。
基本リソースの種類、 ProjectResource、 ContainerResource、 ExecutableResource以外にも、 Aspire では、アプリ モデルに共通のリソースを追加するための拡張メソッドが提供されます。 詳細については、「ホスティング統合」を参照してください。
コンテナー リソースの有効期間
既定では、コンテナー リソースはコンテナーの有効期間
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithLifetime(ContainerLifetime.Persistent);
上記のコードでは、イメージ "ollama/ollama" と永続的な有効期間を持つ "ollama" という名前のコンテナー リソースが追加されます。
Express 外部サービス リソース
外部サービスは、アプリケーションが依存するサードパーティの API とサービスですが、 Aspire ソリューションの外部に存在します。 これらのサービスは既に他の場所で実行されており、 Aspireによって管理されていません。 ExternalServiceResourceを表現するには、IDistributedApplicationBuilder メソッドを呼び出してAddExternalService インスタンスに追加します。
var builder = DistributedApplication.CreateBuilder(args);
var nuget = builder.AddExternalService("nuget", "https://api.nuget.org/")
.WithHttpHealthCheck(path: "/v3/index.json");
var frontend = builder.AddProject<Projects.Frontend>("frontend")
.WithReference(nuget);
上記のコードは、NuGet API を指す "nuget" という名前の外部サービス リソースを追加します。 外部サービスは、その可用性を監視するために HTTP 正常性チェックを使用して構成されます。 フロントエンド プロジェクトは、この外部サービスを参照してサービスの検出を行うことができます。
外部サービスでは、いくつかの構成方法がサポートされています。
静的 URL の構成
文字列または URI を使用して、静的 URL を使用して外部サービスを構成できます。
var builder = DistributedApplication.CreateBuilder(args);
// Using a string URL
var nuget = builder.AddExternalService("nuget", "https://api.nuget.org/");
// Using a URI
var uri = new Uri("https://api.example.com/");
var api = builder.AddExternalService("external-api", uri);
パラメーターベースの URL 構成
外部サービス URL が環境によって異なる場合や構成可能である必要があるシナリオでは、パラメーターを使用できます。
var builder = DistributedApplication.CreateBuilder(args);
var externalServiceUrl = builder.AddParameter("external-service-url");
var externalService = builder.AddExternalService("external-service", externalServiceUrl);
var frontend = builder.AddProject<Projects.Frontend>("frontend")
.WithReference(externalService);
パラメーターベースの構成を使用する場合、URL 値は構成、環境変数、またはユーザー シークレットを使用して設定できます。 開発中に、 Aspire は URL 値の指定を求めるメッセージを表示する場合があります。 詳細については、「外部パラメーター
外部サービス URL の要件
外部サービス URL は、特定の要件を満たしている必要があります。
- 絶対 URI (スキーム、ホスト、および省略可能なポートを含める) である必要があります。
- 絶対パスを "/" に設定する必要があります (追加のパス セグメントはありません)。
- クエリ パラメーターまたはフラグメントを含めてはなりません。
次は有効な例です。
https://api.example.com/http://localhost:8080/https://service.example.com:9443/
無効な例:
-
https://api.example.com/v1/api(パスを含む) -
https://api.example.com/?version=1(クエリを含む) -
https://api.example.com/#section(フラグメントを含む)
外部サービスの健康診断
外部サービスは、HTTP 正常性チェックを使用して構成して、その可用性を監視できます。
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddExternalService("api", "https://api.example.com/")
.WithHttpHealthCheck(path: "/health", statusCode: 200);
WithHttpHealthCheck メソッドは、外部サービスを定期的にポーリングするヘルスチェックを追加します。 以下を指定できます。
-
path: 正常性チェック エンドポイントの相対パス (省略可能、既定では追加パスなし)。 -
statusCode: 予想される HTTP 状態コード (省略可能、既定値は 200)。
外部サービスを使用したサービス検出
別のリソースから外部サービスを参照する場合、 Aspire は、標準形式の環境変数を挿入することによって、サービス検出を自動的に構成します。
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddExternalService("api", "https://api.example.com/");
var frontend = builder.AddProject<Projects.Frontend>("frontend")
.WithReference(api);
この構成により、 API_HTTPS=https://api.example.com/ や services__api__https__0=https://api.example.com/ などの環境変数がフロントエンド プロジェクトに挿入され、簡略化されたサービス検出メカニズムと .NET固有のサービス検出メカニズムの両方を通じてサービス検出が可能になります。
外部サービスのライフサイクル
外部サービスは IResourceWithoutLifetimeを実装します。つまり、 Aspireのライフサイクル システムでは管理されません。 これらは独立して実行されることが期待されます。 開発中は、外部サービスが到達可能な場合は "実行中" 状態の Aspire ダッシュボードに表示され、使用できない場合は正常性チェックエラーが表示されます。
リソースのリレーションシップ
リソースリレーションシップは、リソースをリンクします。 リレーションシップは情報であり、アプリのランタイム動作には影響しません。 代わりに、ダッシュボードにリソースに関する詳細を表示するときに使用されます。 たとえば、リレーションシップは ダッシュボードのリソースの詳細に表示され、Parent リレーションシップはリソース ページでのリソースの入れ子を制御します。
リレーションシップは、一部のアプリ モデル API によって自動的に作成されます。 例えば次が挙げられます。
-
WithReference は、種類が
Referenceのターゲット リソースにリレーションシップを追加します。 -
WaitFor は、種類が
WaitForのターゲット リソースにリレーションシップを追加します。 - データベースを DB コンテナーに追加すると、データベースからコンテナーへのリレーションシップが
Parent型で作成されます。
リレーションシップは、WithRelationship と WithParentRelationshipを使用してアプリ モデルに明示的に追加することもできます。
var builder = DistributedApplication.CreateBuilder(args);
var catalogDb = builder.AddPostgres("postgres")
.WithDataVolume()
.AddDatabase("catalogdb");
builder.AddProject<Projects.AspireApp_CatalogDbMigration>("migration")
.WithReference(catalogDb)
.WithParentRelationship(catalogDb);
builder.Build().Run();
前の例では、WithParentRelationship を使用して、catalogdb プロジェクトの親として migration データベースを構成します。
Parent リレーションシップは、リソース ページでのリソースの入れ子を制御するため、特別です。 この例では、migration は catalogdbの下に組み込まれています。
Note
親リレーションシップのバリデーションがあります。これにより、リソースが複数の親を持ったり、循環参照を作成したりすることが防止されます。 これらの構成は UI 上でレンダリングされないため、アプリ モデルがエラーを発生させます。
こちらも参照ください
Aspire