Amazon Web Services ブログ

詳細: Fargate データプレーン

本日、AWS Fargate の新しいプラットフォームバージョン (1.4) をリリースしました。これには、お客様のための数多くの新しい機能が含まれています。これらの機能の詳細については、こちらのブログ記事をご覧ください。プラットフォームバージョン 1.4 で導入された変更点の 1 つは、Fargate のコンテナ実行エンジンとして、Docker Engine を Containerd に置き換えたことです。  このブログ記事では、お客様のコンテナのワークロードにとってこれが何を意味するか、この変更の背後にある動機、およびこの再設計されたコンテナ実行環境 (Fargate データプレーンとも呼ばれます) の内情について詳しく説明します。

用語集

ブログの本編で使用する用語と概念を確認してみましょう。

  • コンテナランタイム/実行エンジン: これは、コンテナの作成、起動、停止に使用するソフトウェアの一部で、一般的には「コンテナランタイム」とも呼ばれます。それには、たとえば、Docker Engine、Containerd、CRI-O などがあります。
  • runC: これは、Open Containers Initiative (OCI) ランタイム仕様に基づいてコンテナを生成および実行するためのツールです。
  • Containerd: これは、通常 runC を使用して、ホスト上のコンテナのライフサイクルを管理するデーモンです。runC と Containerd がどのように相互に作用するかの詳細については、Michael Crosby のブログ記事をご覧ください。
  • Docker Engine: Docker が提供するコンテナエンジン。通常、これには、コンテナを実行する必要があるホストにインストールする必要がある Docker デーモンバイナリが含まれます。Docker Engine は、runC の上に構築される Containerd に構築されます。

Containerd への切り替えは、Fargate で実行されているコンテナにとってどのような意味があるのか?

端的に言うと、この切り替えにより、ワークロードに何も影響はありません

Fargate はコンテナの管理に Containerd を使用するように切り替えましたが、アプリケーション自体の実行方法に違いはありません。Containerd は、Fargate データプレーンアーキテクチャを簡素化し、柔軟性を高めることで、アーキテクチャの改善に役立ちます (詳細は以下のセクションを参照)。お使いのアプリケーション自体は、この変更にとらわれません。これは、主に次の 3 つの理由によるものです。

  1. OCI 互換性: Containerd は、OCI イメージと Docker イメージを完全にサポートしています。つまり、Dockerfiles と Docker ツールチェーンで構築されたすべてのコンテナイメージは、Fargate でシームレスに実行し続けられます。実際、これは、Containerd を採用する際の前提条件の 1 つでした。すべてのお客様の既存のツールチェーンから構築されたアプリケーションと CICD 統合が Fargate で引き続き機能することを保証したかったからです。
  2. オーケストレーターの抽象化: Fargate のワークロードは、Amazon Elastic Container Service (ECS) タスク定義または Amazon Elastic Kubernetes Service (EKS) ポッド仕様を使って指定されます。このオーケストレーターはコンテナ自体よりも高いレベルの抽象化を提供するため、Fargate がこの抽象化をサポートしている限り、コンテナのワークロードは影響を受けません。たとえば、ECS も EKS も、Docker CLI の Run Comand パラメータによってサポートされる方法では、コンテナのログ記録オプションを指定することをサポートしていません。ECS はタスク定義のログドライバー設定と FireLens 設定をサポートしていますが、EKS はログ記録エージェントと統合しています。Fargate で現在サポートされているすべての機能とコンテナインターフェイスが、この切り替え後もシームレスに機能し続けられるように注意を払いました。
  3. マネージドインフラストラクチャ: Fargate は、インフラストラクチャのセットアップと実行中のコンテナのメンテナンスという、未分化の負荷のかかる作業を行っているため、これらのコンテナのライフサイクルを維持する役割も担っています。これには、コンテナイメージのブートストラップ、適切な宛先へのコンテナログのキャプチャとストリーミング、それにストレージ、ネットワーク、IAM ロールの認証情報、およびこれらのコンテナのメタデータ取得に適切なインターフェイスを利用できるようにすることが含まれます。Fargate はこの統合ポイントの互換性を維持しているため、お客様のアプリケーションが影響を受けることはありません。

Containerd を使う理由

Fargate データプレーンのコンポーネントを簡単に見てみましょう。図 1 は、プラットフォームバージョン 1.4 より前の過程を示しています。詳細については、re:Invent 2019 のこの講演の動画をご覧ください。

Containerd 統合により、このスタックの柔軟性が高まり、さらに簡素化、信頼性の向上、Fargate が所有するコンポーネントのフットプリントの最小化により、少ないオーバーヘッドで新機能が提供されます。次に、これらの側面をさらに詳しく見ていきましょう。

最小限のコンテナランタイムの必要性

Fargate が提供する機能セットを拡張するにつれて、このスタックのさまざまなコンポーネントのカスタマイズを続けてきました。たとえば、次のようなものがあります。

  • コンテナのネイティブ VPC ネットワーキングサポート: awsvpc ネットワーキングモードのサポートを有効にするために、Docker Engine が提供するすべてのネットワーキング機能をバイパスし、代わりに Container Networking Interface (CNI) プラグイン (amazon-ecs-cni-plugins GitHub repo で入手可能) を利用して、この機能を Fargate に実装しました。これは、当社が選べた最もメンテンナンスしやすく、お客様に不便をかけない方法でした。このネットワークプラグインは、Docker エンジンのコンテキスト外で実行され、Fargate でコンテナネットワークをセットアップします。
  • FireLens を介した拡張ログ記録: Fargate で ECS タスクのログ記録機能を拡張するために、FireLens のサポートを追加しました。FireLens は、複数の宛先へのログの送信やソースでのフィルタリングなどの高度な機能を有効にします。当社は、FireLens ログ記録ドライバーを、お客様のタスクのコンテナと一緒に実行されるサイドカーコンテナとして実装することにしました。繰り返しになりますが、ここでの機能強化は Docker Engine 外で行われました。
  • ECS タスクのメタデータエンドポイント: 一部のコンテナとアプリケーションは、タスク内の他のコンテナに関するメタデータと統計をクエリする必要があります。Fargate の外でこれを行う最も一般的な方法は、コンテナランタイムに直接アクセスすることです。ただし、ワークロードのセキュリティと権限の分離は、Fargate の最大の懸念事項の 1 つです。基盤となるコンテナランタイム (Docker エンジンなど) へのアクセスを提供すると、セキュリティポスチャが弱まり、悪意のある攻撃者が「特権の昇格」攻撃を行うのが比較的簡単になる恐れがあります。そこで、アクセスを提供するのではなく、コンテナで利用できるようにしたローカルの HTTP エンドポイントを介してこのデータを自ら提供することにしました。

これは、当社が構築してきた多くの機能に共通する傾向です。上の図のレイヤー #3 と #2 で最も必要な変更が示されています。Fargate には最小限のコンテナランタイムエンジンのみが必要で、コンテナランタイムから基本的なコンテナ CRUD API のみが必要です。その他はすべて、Fargate データプレーンスタックの他のコンポーネントによってすでに処理されています。

Containerd は非常に最小限の状態を維持し、Fargate が必要とするものを正確にサポートするため、このモデルにうまく適合します。それ以上でも、それ以下ではありません。たとえば、Containerd は、コンテナの起動時に外部で作成されたネットワーク名前空間の使用をサポートしています。これは、Fargate がプラットフォームバージョン 1.4 で ECS タスクの一時停止コンテナを実行する必要がなくなったことを意味します。一時停止コンテナが必要だったのは、Docker を使用してネットワーク名前空間を作成し、アプリケーションコンテナを開始する前にネットワークが適切に設定されていることを確認できる唯一の方法であったためです。Fargate データプレーンでは、もう必要ないため、管理するコンテナが 1 つ少なく、さらに維持するコンテナイメージが 1 つ少なくなっています。

最小限の管理オーバーヘッド

Containerd のフットプリントは、実行時に消費されるリソースの点でも、インストールする必要のある追加のパッケージの点でも最小限です。たとえば、プラットフォームバージョン 1.4 では、どの VM 上でもコンテナまたはコンテナイメージを管理するためのクライアント向け CLI をインストールする必要はありません。これは、Fargate ではそもそもそのような CLI を使用したことがなかったためです (Fargate は、プログラムでそれぞれの SDK と統合してコンテナを管理します)。同様に、Fargate は、コンテナイメージの構築に必要なコンポーネントを取り除くことができます。それは、Fargate はそのようなコンポーネントも必要ないためです。Fargate はお客様に代わって実行環境を管理するので、ソフトウェアのフットプリントを最小限に抑えるメリットを常に受けられます。インストールするパッケージが少ないほど、維持およびパッチを適用するパッケージが少なくなり、その結果、プラットフォームがより堅牢になり、運用状態が改善されます。

拡張可能なアーキテクチャ

Containerd は最小限のコンテナ実行エンジンとして機能し、Fargate データプレーンを簡素化しますが、プラグインベースのアーキテクチャを介した拡張性も提供します。Containerd を使用すると、クライアントはプラグインを介してコンテナ実行ライフサイクルのほぼすべての部分を設定できます。これは、Fargate で機能するコンテナに価値を提供する意味のある方法で機能セットを拡張できるため、Fargate にとって非常に望ましいものです。

たとえば、Fargate ですでにサポートされているさまざまな宛先へのストリーミングコンテナログのサポートを追加したいと考えました。これを行うのは非常に簡単で、Containerd の shim ログ記録プラグインを拡張するだけでした。コンテナログのルーティング向けの shim logger プラグインのセットを作成しました。これは、今日オープンソースで提供しています。これは、GitHub の amazon-ecs-shim-loggers-for-containerd リポジトリにあります。このプラグインは、Docker Engine のプロセス内のログ記録ドライバーに取って代わります。Fargate はこのログ記録ドライバーをプラットフォームバージョン 1.4 より前に使用していて、同じ機能セットを提供していました。Containerd を実験または使用していて、拡張可能なログ記録ソリューションを探している場合は、Container の実装でこのプラグインを使い始めることができます。このプラグインの使用の詳細については、こちらをご覧ください。

他の例として、Fargate は、Containerd のランタイムプラグインを runC の代わりに firecracker-containerd に切り替えるだけで、Firecracker VMM などのコンテナ向けの VM ベースのランタイムを活用できます。このプラグインにより、Containerd はコンテナを Firecracker microVM として管理できます。最小限の設定変更でコンテナランタイムを切り替える柔軟性は、Fargate で現在サポートされているさまざまな種類のユースケースを満たす上で非常に望ましいものです。

Fargate データプレーンアーキテクチャ

Containerd を採用することを決定したら、その先の自然な成り行きは、ECS エージェントを使用して Fargate インスタンスでコンテナを調整する代わりに、Fargate データプレーン固有のコンポーネントを作成することでした。この目的のために新しい Fargate エージェントを作成しました。これは、VM 上のコンテナを調整するために Containerd と対話し、ECS エージェントに取って代わる役割を果たします。この新しい Fargate エージェントは Containerd と統合されるだけでなく、Fargate 用に最適化されています。これにより、Fargate は、Fargate 上の EKS ポッドのサポートなどの機能をシームレスに提供できるようになりました。この新しいアーキテクチャにより、Fargate は Firecracker microVM を利用して、firecracker-containerd ランタイムを介してコンテナを実行することもできます。図 2 は、Fargate データプレーンスタックの新しいアーキテクチャを示しています。

図 3 は、ECS タスクを開始するときに Fargate エージェントが VM 上でお客様のコンテナを実行する際の大まかな一連のイベントを示しています。

  1. Fargate エージェントは、タスクを開始する必要があるというメッセージを受け取ります。このメッセージには、タスク用にプロビジョニングされた Elastic Network Interface (ENI) に関する詳細も含まれています。
  2. 次に、新しいネットワーク名前空間を作成し、この新しく作成されたネットワーク名前空間にネットワークインターフェイスをプロビジョニングすることで、そのタスクのネットワークをセットアップします (下の図 3 を参照)。
  3. 次に、お客様のアカウントから ENI を使用して、コンテナイメージ、シークレット、それにコンテナのブートストラップに必要な設定をダウンロードします。
  4. 次に、コンテナ化された API を使用してお客様のコンテナが開始されます。
  5. Containerd は、コンテナの親プロセスとして機能する shim プロセスを作成されます。この shim プロセスは、runC を使用してコンテナを起動するためにも使用されます。
  6. Fargate エージェントは、お客様が指定した設定に基づいて、どの種類の Containerd logger shim を開始する必要があるかも指定します。Containerd はこれを使用して、コンテナのプラグインのログ記録を開始します。

図 4 は、これらのコンポーネントのレイアウトの概要を示しています。

まとめ

AWS は Fargate プラットフォームを継続的に革新し、お客様にとって新しいユースケースの扉が開かれるような機能を加えることを常に目指しています。そのため、この新しいアーキテクチャで堅牢性、シンプルさ、そして柔軟性をもたらすことができることを大変嬉しく思います。これらの変更点についてのフィードバックと、shim logger リポジトリをコメント欄でお寄せください。また、GitHub のコンテナロードマップリポジトリからお問い合わせいただくこともできます。