Amazon Web Services ブログ

Amazon EFS を Amazon ECS と AWS Fargate で使用するための開発者ガイド – パート 2

Amazon EFS を Amazon ECS と AWS Fargate で使用する方法に関するこのブログ記事シリーズのパート 2 へようこそ。参考までに、このブログ記事シリーズは次のように構成されています。

  • パート 1: このブログ記事は、この統合の必要性とその範囲に関する背景情報を提供し、この機能により道が開かれ、お客様に役立つユースケースとシナリオの概要を示します
  • パート 2: [このブログ記事] ECS と Fargate に基づきコンテナをデプロイする際の EFS のセキュリティの仕組みの詳細と、リージョンごとの ECS と EFS のデプロイのベストプラクティスに関する高レベルの考慮事項を扱います
  • パート 3: コンテナ化されたアプリケーションの再利用可能なコードとコマンドを含む実用的な例を紹介します。アプリケーションは EFS を使用した ECS タスクにデプロイされたものです

このブログ記事は、Amazon ECS と AWS Fargate を使用している開発者で、Amazon EFS との統合を使用して、各リージョンで弾力性があり、スケーラブルなステートフルサービスをデプロイする方法を学びたい方を対象としています。

パート 3 は、このすべての理論を実践するパートです!

可用性、コスト、拡張性のための Amazon ECS と AWS Fargate アーキテクチャ

Amazon ECS は、リージョン別に分散されたコンテナオーケストレーターで、AWS が完全に管理しています。ECS コントロールプレーンは、リージョンエンドポイントを公開します。これは、唯一注意する必要がある点です。このため、弾力性とスケールアウトについて考えなくてもすぐに使用できます。

このシリーズのパート 1 で触れたように、ECS は、顧客管理の Amazon EC2 インスタンスと AWS Fargate の両方でタスクをデプロイすることをサポートしています。EC2 と Fargate のどちらのリソースも、節約プランとスポットキャパシティを使用してプロビジョニングでき、アーキテクチャオプションと購入オプションを柔軟に組み合わせることができます。ECS と EFS の統合は、これらすべてのオプション全体で機能します。

以下は、EC2 インスタンスと Fargate フリートの両方に ECS タスクをデプロイする、リージョンごとの (フルマネージドの) ECS 一元制御プレーンを視覚的に表現したものです。デプロイは、弾力性とスケーリングの目的でアベイラビリティーゾーンをまたいで発生し、料金最適化のためにスポットリソースとオンデマンドインスタンスリソースを混ぜ合わせることができます。

可用性、コスト、拡張性のための Amazon EFS アーキテクチャ

Amazon ECS と同様に、Amazon EFS はリージョンごとのサービスです。これは、分散管理された、完全に弾力性のあるマネージド型ファイル共有ソリューションで、AWS が完全に管理しています。EFS のお客様は、インフラストラクチャコンポーネントについて心配する必要はありません。

構築する EFS ファイルシステムは、耐久性のために複数のアベイラビリティーゾーン (少なくとも 3 つ) にまたがるインフラストラクチャ上に構築されます。ただし、これはファイルシステムへのアクセス方法から影響を受けることはありません。可用性の点に関しては、ファイルシステムを同時にマウントでき、リージョン内のすべてのアベイラビリティーゾーンからアクセスできます。このファイルシステムは、EFS マウントターゲットを介してユーザーに公開されます。マウントターゲットは、(そのように選択した場合) VPC のすべてのサブネットで作成できるファイルシステムの論理エンドポイントです。ファイルシステムの作成時に適切なサブネットを選択することにより、マウントターゲットを作成するアベイラビリティーゾーンを選択します。このようなマウントターゲットには、独自の VPC IP アドレスと内部 DNS 名があります。

EFS の本領が発揮されるのがコストと規模の場面です。EFS は、インフラストラクチャ容量を完全に抽象化することにより、お客様は無限に拡張でき、さらに実際に使用した分に対してのみ料金が発生するようにできます。ファイルシステムのサイズには、上限も下限もありません。ソリューションを設計するときは、さまざまな正接の EFS クォータと制限を考慮することが重要です。コンテナと EFS を一緒に使用する際の、パフォーマンスに関するベストプラクティスと一般的なベストプラクティスについてさらに詳しく知りたい場合は、こちらをお読みください。

以下は、EFS を利用した ECS デプロイの全体像を示しています。さまざまなアベイラビリティーゾーンにデプロイされたタスクは、同じアベイラビリティーゾーン内の最も近いマウントターゲットに接続されます。

Amazon EFS セキュリティモデルの詳細

これは、このブログ記事でこれから突き詰めていく分野です。セキュリティが私たちの最優先事項であることに加えて、EFS セキュリティモデルは非常に豊富で柔軟です。

EFS セキュリティモデルには、次の 2 つのマクロディメンションがあります。

  • ネットワークセキュリティ。これは、「ネットワークルーティングとネットワークセキュリティの観点から、タスクから EFS マウントターゲットの Elastic Network Interface (ENI) にアクセスできますか?」という質問に対する回答です。
  • クライアントセキュリティ。これは、「自分のタスクに EFS ファイルシステムを読み書きする権限はありますか?」という質問に対する回答です。

以下の 2 つのセクションでは、これら 2 つのディメンションを詳しく説明します。

EFS ネットワークセキュリティモデル

EFS ネットワークセキュリティモデルは、標準の AWS ネットワークセキュリティ構成 (つまり、セキュリティグループネットワークアクセスコントロールポリシー) に基づいており、その構成をすでに知っている場合はすぐに理解できます。

上記で概説したように、各 EFS マウントターゲットは、VPC サブネットに接続される Elastic Network Interface (ENI) です。お客様は、必要に応じてサブネットをオプトインおよびオプトアウトできます。これにより、EFS マウントターゲットを有効にするアベイラビリティーゾーンを選択できます。各マウントターゲットには、最大 5 つのセキュリティグループを割り当てることができます。デフォルトでは、他の SG が指定されていない場合、デフォルトの VPC セキュリティグループが選択されます。

以下は、新しい EFS ファイルシステムを作成したときにデフォルト設定がどのように見えるかの例です。

つまり、簡単に言えば、同じデフォルトのセキュリティグループを使用する同じ VPC 内のすべての ECS タスクがこのマウントポイントにアクセスできるということです。デフォルトでは、VPC の外部からのネットワークアクセスはすべて拒否されます。

ネットワークセキュリティ体制にはより高度な技術が必要になる可能性が非常に高いですが、EFS マウントターゲットと ECS タスク間のネットワークフローを保護する方法は、VPC 内の他の構造を保護する方法と何も変わりません。覚えておくべき重要な点は、マウントターゲットに割り当てるセキュリティグループが NFS プロトコル (ポート 2049) のインバウンドトラフィックを許可する必要があることです。この側面の詳細については、EFS のドキュメントを参照してください。

セキュリティグループと同様に、ネットワーク ACL (ネットワークアクセスコントロールリスト) を使用して、さまざまなサブネットとの間のトラフィックを制御できます。特定の VPC 中の NACL はデフォルトですべてのトラフィックを許可することに注意してください。

EFS クライアントセキュリティモデル

このセクションでは主に EFS セキュリティプリミティブに焦点を当てていますが、これについては、ECS タスクから EFS を使用するコンテキストで見ていきます。このセクションが終わる頃までには、タスク定義で EFS ストレージを設定するためのオプションの理解が深まっていることでしょう。

まず、EFS クライアントのセキュリティの仕組みに適用される主要な中心原則から始めましょう。このセクションをさらに詳しく見ていくと、これらの原則を参考資料として用いていることに気付くことでしょう。

  • EFS クライアントのセキュリティは階層化されています。これは AWS アクセスポリシー (つまり、リソースベースのポリシーと IAM ポリシーのマージ) と標準の POSIX ファイルシステムレベルのアクセス許可の両方が交わった結果です。
  • 両方の階層を使用して、特定の EFS オブジェクトへの readwriteroot アクセスを拒否または許可できます。常に勝つのは「拒否」の方です (本来そうあるべきです)。
  • EFS は、アプリケーションベースのパターンを可能にする EFS アクセスポイントと呼ばれるファイルシステムへのアクセス抽象化を実装しています。EFS アクセスポイントにより、ファイルシステムのフォルダレベルで細かく AWS ポリシーアクセス許可を割り当てることができます (これについては後で詳しく説明します)。
  • EFS は、適切な AWS アクセスロールがそのレベルのアクセスを許可しない場合 (たとえば、sudo touch filename.txt を実行しようとしている場合)、root ユーザーを押しつぶすことができます。

主な原則を説明したので、それらすべてがどのように組み合わされるかを見てみましょう。

AWS ポリシー

AWS ポリシーから始めましょう。IAM およびリソースベースのポリシーには、EFS リソースへのアクセスを制御する 3 つのアクションがあります。

  • elasticfilesystem:ClientMount (読み取り専用アクセス)
  • elasticfilesystem:ClientWrite (読み取り/書き込みアクセス)
  • elasticfilesystem:ClientRootAccess (root アクセス)

これらのアクションはそれ自体が階層化され、互いに上乗せして構築されます (たとえば、ClientWrite は ClientMount を想定していないため、具体的にリストする必要があります)。

このようなアクションは、クライアントレベル (ECS タスクに割り当てられた IAM ロールに関連付けられた IAM ポリシーを介して) または EFS ファイルシステムレベル (リソースベースのポリシーを介して) の両方で、ポリシー内で定義できます。リソースアクセスベースのポリシーが存在しない場合、デフォルトでは、ファイルシステムの作成時にすべてのプリンシパル (*) にアクセスが許可されます。

クライアントポリシー (タスクロールを介して IAM ポリシーとしてタスクに関連付けられている) は、上記のスクリーンショットのフラグ「EFS IAM 承認」を使用して (または同等の API を介して) 明示的に有効にする必要があります。「EFS IAM 承認」が有効になっている場合、タスクのロールに関連付けられたポリシーと EFS リソースベースのポリシーがマージされ、標準のポリシーのマージが適用されます。このフラグは IAM ポリシーを EFS だけに渡すのではなく、タスクの ID (つまり、IAM ロール) も渡すことに注意してください。これは、リソースベースのポリシーに、特定の IAM ユーザーまたはロールにリソースへのアクセスを許可するルールがある可能性があるためです。「EFS IAM 承認」にフラグを立てることは、IAM ポリシーに加えて、IAM ユーザーまたはロールコンテキストを EFS に渡す方法です。これを有効にしない場合、EFS リソースベースのポリシーにより「匿名」として識別されます。

POSIX アクセス許可

AWS ポリシーに加えて、EFS クライアントアクセスセキュリティは、標準の POSIX アクセス許可モデルによって管理されます。読み取り、書き込み、実行のアクセス許可は、ユーザー、ユーザーが属するグループ、およびその他すべてのユーザーに対して定義されます。20 年以上前に Unix のシステム管理者として働いた経験がある方は、漠然と覚えているかもしれません (私がどうしてそれを知っているかはお尋ねください)。

このようなアクセス許可をチェックするために使用する UID:GID は、クライアントで定義されます。EC2 シナリオでは、これは EFS ファイルシステムにアクセスしようとする Linux ユーザー (/etc/passwd で定義) です。ECS タスクのシナリオでは、これは、ECS タスクの一部として使用するコンテナイメージの Dockerfile で定義されたユーザーになります。これは、root (デフォルト) または明示的に定義されたユーザーである可能性があります。

注目する価値がある重要な点に、自分を root (または sudo を使用した偽装 root) として提示し、AWS ポリシーで ClientRootAccess アクションを許可すると、ファイルシステムへの完全な特権アクセスが付与されることがあります。

ただし、AWS ポリシーで ClientRootAccess アクションが許可されていない場合、ユーザーは事前定義された UID:GID である 65534:65534 に押しつぶされます。これ以降は、標準の POSIX アクセス許可が適用されます。そのため、このユーザーが実行できることは、POSIX ファイルシステムの権限によって決まります。たとえば、666 (所有者は rw、かつ全員は rw) を持つ 65534:65534 以外の UID:GID が所有するフォルダでは、このリザーブされたユーザーがファイルを作成できます。ただし、644 (所有者は rw、全員は r) を持つ 65534:65534 以外の UID:GID が所有するフォルダでは、この押しつぶされたユーザーはファイルを作成できません。

AWS ポリシーと POSIX アクセス許可の操作に関する考慮事項

先ほど触れたように、AWS ポリシーと POSIX アクセス許可は、ECS タスクが実行する必要があることを実行できるように調整する必要があります。たとえば、ECS タスクが EFS ファイルシステムの root ディレクトリ (「/」) に書き込む必要があるとします。POSIX アクセス許可が適切であり、すべてのユーザーに rwx を許可するが、AWS ポリシーでは ClientWrite を許可しない場合、タスクにはファイルシステムへの書き込み権限がありません。

この時点で理解したかもしれませんが、AWS ポリシーレベルでのクライアントアクセスの管理は割と簡単でスケーラブルです。また、これは非常に「AWS ネイティブ」です。 ただし、クラウド環境で、具体的にはコンテナのコンテキストで POSIX アクセス許可を操作することは、それほど多くありません。

POSIX アクセス許可は、自分のコンピュータ (/etc/passwd 内) または (NIS などのツールを介して) ローカルネットワークでユーザーを定義する方法を厳密に制御することを前提としています。クラウドにはこのようなものはありません (または少なくとも、クラウドでこれを適切にスケーリングできるものはありません)。また、コンテナイメージは、焼き込まれた root ユーザー (非常に悪い習慣) またはランダムで特権の少ないユーザーによって作成されます。後者は間違いなくより良い方法ですが、EFS ファイルシステムを使用しているときに、これらのユーザーがコンテナイメージの作成者によってランダムに選択された場合、エンドツーエンドで適切な POSIX アクセス許可をどのように設定したら良いでしょうか? 特定のコンテナが使用する UID:GID に基づいて POSIX アクセス許可を設定する必要があります。

全体として、このアプローチは 20 年前の小規模な LAN ネットワークでは問題なく機能した可能性がありますが、クラウドスケールで、コンテナエコシステムの現在のアプリケーションデプロイパターンで管理することは悪夢です。

EFS アクセスポイント

POSIX アクセス許可は、以前は、厳格に制御された環境の小規模な LAN ネットワークで奏功し、一部の EC2 ベースのユースケースでは今も意味があります。ただし、そのようなアクセス許可は、コンテナなどの最近のアプリケーション中心のデプロイモデルの後塵を拝するようになりました。NFS プロトコルの動作を尊重しながら、不要になった NFS ファイルアクセス権を抽象化するにはどうしたらよいでしょうか?

EFS アクセスポイントを入力します。昨年、EFS チームは、EFS ファイルシステムアクセスパターンを全体的に簡素化できる新機能を導入しました。これにより、EFS を使用するアプリケーションファーストのアプローチでセキュリティの粒度を向上させられます。この機能は EFS アクセスポイントと呼ばれ、次の 2 つの主要な点を改善できました。

  • EFS ファイルシステムディレクトリレベルで細かく IAM ポリシーアクセスを付与できる
  • 事前に一連の UID:GID と POSIX ファイルシステムアクセス許可を適用できる

細かく IAM ポリシーを設定できる利点は明白です。ユーザーは、単一の EFS ファイルシステム内のフォルダレベルで AWS プリンシパルを許可/拒否するオプションを利用できるようになりました。これは、異なるユーザープロファイルで単一のファイルシステムを使用する場合に便利です。

UID:GID とファイルシステムのアクセス許可の事前設定により、POSIX アクセス許可レイヤーを完全に抽象化できます。

次のような簡単な EFS アクセス戦略を実装できます。

  • 任意の UID:GID が所有するディレクトリを作成する
  • ニーズごとに rwx アクセスを割り当てる (例:755)
  • 上記の任意の UID:GID へのクライアント POSIX ユーザーのマッピングを有効にする
  • ECS タスクに割り当てられた AWS ポリシーを介してこの特定のアクセスポイントへのアクセスを制御する

この場合、EFS クライアント (コンテナ) 内で設定されている POSIX ユーザーに関係なく、すべての EFS 呼び出しは、アクセスポイントで設定されている任意の UID:GID を偽装して行われます。ある意味、アクセスポイントは、実際のコンテナユーザーをアクセスポイントで設定したユーザーでマスクし、必要な設定を大幅に簡素化しています。コンテナが使用する POSIX ユーザーに関係なく、設定した任意の UID:GID ユーザーを常に偽装していることを実質的に宣言したことになります。

これは極端な例に過ぎません。EFS アクセスポイントは、複数のシナリオを可能にする設定をサポートしています。

EFS アクセスポイントは、以下のように、ECS の 3 つの高レベルのユースケースを可能にします。

  • 複数のアプリケーション間でファイルシステムを共有する (たとえば、スループットを共有する)。この場合、各アクセスポイントは、アプリケーションごとに個別の jail 化されたディレクトリを提供するため、互いを見ることができません。
  • データを共有する必要があるサービス間でファイルシステムを共有する。これにより、ECS タスクレベルで IAM ポリシーを作成できるため、1 つのサービスはディレクトリへの書き込み専用アクセス権を持ち、別のサービスは読み取り専用アクセス権を持ち、別のサービスは読み取り/書き込みアクセス権を持つことができます。
  • トレーニングコンテナへの ML データセットに対する制限付きアクセスを安全にプロビジョニングする。たとえば、/noPII ディレクトリへの読み取り専用アクセスを許可するアクセスポイントを作成できます。

まとめ

これで、このシリーズのパート 2 は終了です。このブログでは、可用性、コスト、拡張性、それにセキュリティの特定の側面を深掘りすることに焦点を当てて、EFS および ECS テクノロジーがどのように機能するかの背景を示しました。パート 3 では、この記事で学んだ理論をうまく活用します。パート 3 は重要な局面です。パート 1 で紹介したユースケースに触れた簡単な例を実装し、このブログで説明した多くの技術的側面を扱います。パート 3 でお会いしましょう。