コンテンツにスキップ
ドキュメントAspire を試す
ドキュメント試す

Aspire のアーキテクチャ

Aspire は、開発者にシームレスで直感的な体験を提供するために設計された、強力なツール群とライブラリ群を結集しています。そのモジュール化され拡張可能なアーキテクチャにより、サービス、コンテナー、実行可能ファイルで構成される複雑なシステムをオーケストレーションしながら、アプリケーション モデルを正確に定義できます。コンポーネントが異なるプログラミング言語、プラットフォーム、スタック、オペレーティング システムにまたがっていても、Aspire はそれらを調和して動作させ、最新のクラウドネイティブ アプリ開発の複雑さを簡素化します。

アプリ モデルのアーキテクチャ

Section titled “アプリ モデルのアーキテクチャ”

リソースは、アプリ モデルの構成要素です。これらは、サービス、コンテナー、実行可能ファイル、外部統合といった抽象的な概念を表現するために使われます。特定のリソースを使用すると、開発者はこれらの概念の具体的な実装に対する依存関係を定義できます。たとえば、Redis リソースは Redis キャッシュを表現するために使え、Postgres リソースは PostgreSQL データベースを表現できます。

アプリ モデルは、リソースの集合とほぼ同義で語られることが多い一方で、アプリケーション全体のトポロジを高レベルで表現したものでもあります。これは重要です。なぜなら、アプリ モデルは lowering を前提として設計されているからです。この意味で、Aspire はアプリケーション トポロジのためのコンパイラーと考えることができます。

従来のコンパイラーでは、「lowering」のプロセスは、高水準プログラミング言語を段階的により単純な表現へ変換することを意味します:

  • 中間表現 (IR): 最初の段階では、言語固有の機能を抽象化して、プラットフォームに依存しない表現を作成します。
  • 機械語: その後 IR は、特定の CPU アーキテクチャに合わせた機械固有の命令へ変換されます。

同様に、Aspire はこの概念をアプリケーションに適用し、アプリ モデルを高水準言語として扱います:

  • 中間構成: まずアプリ モデルは、cloud development kit (CDK) スタイルのオブジェクト グラフのような中間構成へ lowering されます。これらの構成はプラットフォームに依存しない場合もあれば、特定のターゲット向けに部分的に調整されている場合もあります。
  • ターゲット ランタイム表現: 最後に、パブリッシャーがターゲット プラットフォームで必要となるデプロイ可能な成果物、つまり YAML、HCL、JSON、またはその他の形式を生成します。

この多層アプローチにより、いくつかの重要な利点が得られます:

  • 検証と拡張: 変換プロセスの途中でモデルを検証および拡張できるため、正確性と完全性を確保できます。
  • マルチターゲット サポート: Aspire は複数のデプロイ ターゲットをサポートし、多様な環境に柔軟に対応できます。
  • カスタマイズ可能なワークフロー: 開発者はプロセスの各段階にフックして動作をカスタマイズし、特定の要件に合わせて出力を調整できます。
  • クリーンで移植可能なモデル: 高レベルのアプリ モデルは、表現力と移植性を保ちながら、プラットフォーム固有の懸念から切り離されたままです。

最も重要なのは、変換プロセス自体の拡張性が非常に高いことです。独自の変換、拡張、出力形式を定義できるため、Aspire は固有のインフラストラクチャ要件やデプロイ要件にもシームレスに適応できます。この拡張性により、Aspire はアプリケーションのニーズとともに進化できる、強力で汎用的なツールであり続けます。

Aspire は、後続のセクションで詳しく説明するように、特定のニーズを効率化するための 2 つの主要モードで動作します。どちらのモードでも、使い慣れた API 群と、豊富な統合エコシステムを利用します。各統合により、Redis、PostgreSQL、Azure サービス、Orleans など、一般的なサービス、フレームワーク、プラットフォームを簡単に扱えます。これらの統合はパズルのピースのように連携し、ローカル実行でも本番デプロイでも、リソースの定義、依存関係の表現、動作の構成を容易に行えるようにします。

なぜ AppHost の実行コンテキストにおいてモダリティが重要なのでしょうか。これは、アプリ モデルを一度定義すれば、適切な API を用いて、各モードでリソースがどのように動作するかを指定できるからです。次のようなリソース群を考えてみてください:

  • データベース: PostgreSQL
  • キャッシュ: Redis
  • AI サービス: Ollama または OpenAI
  • バックエンド: ASP.NET Core minimal API
  • フロントエンド: React アプリ

モードによって、AppHost はこれらのリソースを異なる方法で扱うことがあります。たとえば run mode では、AppHost はコンテナーを使ってローカルの PostgreSQL データベースと Redis キャッシュを使用する一方で、publish mode では Azure Database for PostgreSQL や Azure Cache for Redis 向けのデプロイ成果物を生成する場合があります。

既定のモードは run mode で、ローカル開発とテストに最適です。このモードでは、Aspire AppHost がプロセス、コンテナー、クラウド エミュレーターを含むアプリケーション モデルをオーケストレーションし、高速で反復的な開発を支援します。リソースは本番環境を反映したライフサイクルを持つ、実際のランタイム エンティティのように振る舞います。単に F5 を押すだけで、AppHost はアプリ モデル内のあらゆるもの、つまりストレージ、データベース、キャッシュ、メッセージング、ジョブ、API、フロントエンドを起動し、すべてが構成済みでローカル デバッグ可能な状態になります。前のセクションのアプリ モデルを考えると、AppHost はローカルで次のリソースをオーケストレーションします:

開発時オーケストレーション向けのローカル アプリ トポロジ

run mode の動作の詳細については、開発時のオーケストレーションを参照してください。

publish mode では、ターゲット環境に合わせたデプロイ可能な成果物を生成します。Aspire AppHost は、アプリ モデルを Kubernetes マニフェスト、Terraform 構成、Bicep/ARM テンプレート、Docker Compose ファイル、CDK 構成などの出力へコンパイルし、任意のデプロイ パイプラインに組み込めるようにします。出力形式は選択したパブリッシャーによって決まるため、さまざまなデプロイ シナリオに柔軟に対応できます。前のセクションのアプリ モデルを考えると、AppHost は何もオーケストレーションしません。その代わり、クラウド プロバイダーへアプリケーションをデプロイするために使える publish 成果物を出力します。たとえば Azure にデプロイしたいとすると、AppHost は次のリソースを定義する Bicep テンプレートを出力します:

公開済みアプリ トポロジ

開発時のオーケストレーション

Section titled “開発時のオーケストレーション”

run mode では、AppHost はアプリ モデルで定義されたすべてのリソースをオーケストレーションします。では、これはどのように実現されるのでしょうか。

このセクションでは、AppHost がアプリ モデルをどのようにオーケストレーションするのかを理解できるよう、いくつかの重要な問いに答えます:

  • オーケストレーションを支えているものは何ですか。

    オーケストレーションは Microsoft Developer Control Plane (DCP) に委譲されており、DCP がアプリ トポロジ全体にわたってリソースのライフサイクル、起動順序、依存関係、ネットワーク構成を管理します。

  • アプリ モデルはどのように使われますか。

    アプリ モデルは、コンテナー、プロセス、データベース、外部サービスを含む IResource 実装を通じてすべてのリソースを定義し、オーケストレーションの設計図を形成します。

  • AppHost の役割は何ですか。

    AppHost は、望ましいアプリケーション状態を高レベルに宣言します。実行は DCP に委譲され、DCP がアプリ モデルを解釈してそれに応じたオーケストレーションを実行します。

  • 監視されるリソースは何ですか。

    宣言されたすべてのリソース、つまりコンテナー、実行可能ファイル、統合が監視され、正しい動作を保証するとともに、高速で信頼性の高い開発ワークフローを支援します。

  • コンテナーと実行可能ファイルはどのように管理されますか。

    コンテナーとプロセスは、それぞれの構成で初期化され、アプリ モデルで定義された依存関係グラフに従って同時に起動されます。DCP は、依存関係で定められた正しい順序を維持しつつ、できるだけ速くリソースを起動しながら、オーケストレーション中の準備完了状態と接続性を保証します。

  • リソース依存関係はどのように処理されますか。

    依存関係はアプリ モデルで定義され、DCP がそれを評価して正しい起動順序を決定し、依存先が依存元より先に利用可能になるようにします。

  • ネットワークはどのように構成されますか。

    ポート バインドなどのネットワークは、明示的に定義しない限り自動構成されます。DCP が競合を解決し、可用性を確保することで、サービス間のシームレスな通信を可能にします。

オーケストレーション プロセスは多層アーキテクチャに従います。その中核では、AppHost が分散アプリケーション リソースに対する開発者の望ましいビューを表現します。DCP は、リソースをオーケストレーションして整合性を維持することで、その望ましい状態を実現します。

アプリ モデルは、DCP がアプリケーションをオーケストレーションするための設計図として機能します。内部的には、AppHost は 📦 Aspire.Hosting.AppHost NuGet パッケージによって支えられた .NET コンソール アプリケーションです。このパッケージには、オーケストレーション依存関係を登録するビルド ターゲットが含まれており、開発時オーケストレーションをシームレスに有効化します。

DCP は Kubernetes 互換の API サーバーです。つまり、Kubernetes と同じネットワーク プロトコルおよび規約を使用します。この互換性により、Aspire AppHost は通信に既存の Kubernetes ライブラリを活用できます。具体的には、AppHost には k8s.KubernetesClient の実装が含まれており、これは .NET 向けの Kubernetes クライアントである 📦 KubernetesClient NuGet パッケージから提供されます。このクライアントを使って DCP API サーバーと通信し、AppHost はオーケストレーション タスクを DCP に委譲します。

AppHost を実行すると、最初の「lowering」ステップとして、汎用的な Aspire アプリ モデルが run mode でのローカル実行向けに調整された DCP 固有モデルへ変換されます。この DCP モデルは DCP に渡され、DCP がそれを評価してリソースを適切にオーケストレーションします。この分離により、AppHost は Aspire アプリ モデルをローカル実行向けに適応させることに集中し、DCP はその調整済みモデルの実行に特化できます。次の図は、このオーケストレーション プロセスの視覚化に役立ちます:

AppHost が DCP に委譲するフローを示す図

DCP は、Aspire AppHost のオーケストレーション機能の中核にあります。これは、アプリ モデルで定義されたすべてのリソースをオーケストレーションし、開発者ダッシュボードを起動し、ローカル開発とテストに向けてすべてが正しくセットアップされていることを保証します。DCP はリソースのライフサイクルを管理し、ネットワーク構成を適用し、依存関係を解決します。

DCP は Go で記述されています。これは、同じく Go ベースである Kubernetes とそのエコシステムに沿った選択です。この選択により、Kubernetes API との深いネイティブ統合、効率的な並行処理、Kubebuilder のような成熟したツール群へのアクセスが可能になります。DCP は 2 つの実行可能ファイルとして提供されます:

  • dcp.exe: AppHost が通信するための Kubernetes 風 API エンドポイントを公開する API サーバーです。さらに、AppHost に対するログ ストリーミングも公開し、そのログは最終的に開発者ダッシュボードへストリームされます。
  • dcpctrl.exe: API サーバーを監視して新しいオブジェクトや変更を検出し、実世界の環境が指定されたモデルと一致するように保つコントローラーです。

AppHost の実行時には、Kubernetes クライアント ライブラリを使って DCP と通信します。アプリ モデルのリソースを仕様へ変換することで、DCP が処理できる形式へアプリ モデルを変換します。具体的には、アプリケーションの望ましい状態を表す Kubernetes の Custom Resource Definitions (CRD) を生成します。

DCP は次のタスクを実行します:

  • 実行に向けてリソースを準備します:
    • サービス エンドポイントを構成します。
      • 明示的に設定されていない限り、名前とポートを動的に割り当てます (DCP は、そのポートが利用可能で他のプロセスで使われていないことを保証します)。
    • コンテナー ネットワークを初期化します。
    • 適用された ImagePullPolicy に基づいてコンテナー イメージをプルします。
    • コンテナーを作成して起動します。
    • 必要な引数と環境変数を指定して実行可能ファイルを起動します。
  • リソースを監視します:
    • DCP 内で管理されるオブジェクトに関する変更通知を提供します。これにはプロセス ID、実行状態、終了コードが含まれます (AppHost はこれらの変更を購読して、アプリケーションのライフサイクルを効果的に管理します)。
  • 開発者ダッシュボードを起動します。

前のセクションの図に続いて、DCP の責務を視覚化する次の図を見てみましょう:

DCP コンポーネントを示すアーキテクチャ図

DCP のログは AppHost にストリーム バックされ、そこから開発者ダッシュボードへ転送されます。開発者ダッシュボードは start、stop、restart などのコマンドを公開しますが、これらのコマンド自体は DCP の一部ではありません。代わりに、これらはアプリ モデル ランタイム、具体的にはその「dashboard service」コンポーネント内で実装されています。これらのコマンドは、DCP オブジェクトを操作することで機能します。たとえば、新しいオブジェクトを作成したり、古いものを削除したり、そのプロパティを更新したりします。たとえば .NET プロジェクトを再起動するには、そのプロジェクトを表す既存の ExecutableResource を停止して削除し、同じ仕様を持つ新しいものを作成します。

Aspire 開発者ダッシュボードは、ローカル開発とリソース管理を簡素化するために設計された強力なツールです。スタンドアロン モードもサポートしており、Azure Container Apps への発行時にもシームレスに統合されます。直感的なインターフェイスにより、ダッシュボードは開発者がアプリケーション リソースを簡単に監視、管理、操作できるようにします。

ダッシュボードは、リソース状態の確認、ログの表示、コマンドの実行を行うための使いやすいインターフェイスを提供します。ローカルでデバッグしている場合でも、クラウドにデプロイしている場合でも、ダッシュボードによりアプリケーションの動作を完全に可視化できます。

組み込みコマンドとカスタム コマンド

Section titled “組み込みコマンドとカスタム コマンド”

ダッシュボードには、start、stop、restart など、リソースを管理するための一連のコマンドが用意されています。これらのコマンドはダッシュボード UI では直感的な操作として表示されますが、内部では DCP オブジェクトを操作して動作します。詳細については、「リソースを停止または開始する」を参照してください。

これらの組み込みコマンドに加えて、アプリケーションのニーズに合わせたカスタム コマンドを定義することもできます。これらのカスタム コマンドはアプリ モデルに登録され、ダッシュボードにシームレスに統合されるため、柔軟性と制御性がさらに高まります。

リアルタイム ログ ストリーミング

Section titled “リアルタイム ログ ストリーミング”

ダッシュボードのリアルタイム ログ ストリーミング機能により、常に状況を把握できます。アプリ モデル内のすべてのリソースのログは DCP から AppHost にストリームされ、ダッシュボードに表示されます。リソースの種類、重大度などによる高度なフィルター オプションにより、関連情報をすばやく絞り込み、効果的にトラブルシューティングできます。

開発者ダッシュボードは単なるツールではありません。これは、Aspire アプリケーションを自信を持って容易に構築、デバッグ、管理するためのコマンド センターです。