BackEnd

Amazon ECSのタスク定義について

投稿日:

はじめに

前回の記事ではAmazon ECSの機能を全般的に広く浅く紹介しました。今回はAmazon ECSのタスク定義について詳しく調べてみました。

Amazon ECSのタスク定義についておさらい

Amazon ECSには大きく分けて4つの概念があります。

  • クラスター: タスクまたはサービスの論理グループ
  • サービス: タスクのスケジューラ
  • タスク: タスク定義を元に作られるアプリケーションの実行単位
  • タスク定義: DockerイメージやCPU、メモリの量などタスクの定義

クラスターの中にサービスがあり、サービスがタスクを立ち上げて維持します(サービスを介せずにタスクを直接立ち上げることもできます)。

Amazon ECSの概要については前回の記事をご覧ください。

タスク定義

タスク定義では以下のような内容を定義します。

  • タスクの各コンテナで使用するDockerイメージ
  • タスク及び各コンテナで使用するCPUやメモリの量
  • タスクの起動タイプ(Fargate、EC2など)
  • タスクのコンテナで使用するDockerネットワークモード
  • タスクで使用するロギング設定
  • タスクで使用されるIAMロール

1つのタスク定義の中に複数のコンテナを定義することができます。ただし、ECSでは1つのタスク定義だけでアプリケーションを構築するのではなく、複数のタスク定義を組み合わせてアプリケーションを構築することを推奨しています。

コンテナをどのようにタスク定義に振分けるかについては次で解説します。

アプリケーションのアーキテクチャ

タスク定義では、FargateもしくはEC2どちらかの起動タイプを選択します。

Fargate起動タイプ

公式ドキュメントによると、Fargate起動タイプは以下のワークロードに適しています。

  • 運用上で低いオーバーヘッドを必要とする大規模なワークロード
  • 時折バーストが発生する小さなワークロード
  • 小さなワークロード
  • バッチワークロード

AWS Fargateを使用する場合、複数をコンテナを単一のタスク定義に配置するか、それとも複数のタスク定義に分けて配置するか、どちらかを選択することになります。

以下のような要件がある場合は、同一のタスク定義にコンテナを配置するのが良いようです。

  • 各コンテナが同じライフサイクルを共有している(起動と終了が同時)
  • 実行基盤となるホストが同じになるようにコンテナを実行する(localhostポート上の別のコンテナを参照する)必要がある
  • コンテナがリソースを共有する必要がある
  • コンテナがデータボリュームを共有している

上記の要件が当てはまらない場合は、複数のタスク定義でコンテナを個別にデプロイするのが良いようです。別々にすることで、スケーリング、プロビジョニング、プロビジョニング解除を個別に行えるメリットがあります。

EC2起動タイプ

公式ドキュメントによると、EC2起動タイプは料金を最適化する必要があるような大規模なワークロードに適しています。他にも、GPUを使いたいケースの場合は、現状ではEC2起動タイプを選択する必要がありそうです。

タスク定義パラメータ

タスク定義は、タスクファミリ、IAMタスクロール、ネットワークモード、コンテナ定義、ボリューム、タスク配置の制約事項、起動タイプの各部分に別れています。この内、タスクファミリとコンテナの定義は必須項目ですがそれ以外の項目は省略することができます。

タスク定義はJSON形式で記述されます。ここではその内のいくつかを紹介します。

family

文字列型の必須項目です。

タスク定義を登録するときにはファミリー(複数バージョンのタスク定義の名前のようなもの)を指定する必要があります。登録したタスク定義にはリビジョン番号が与えられ、 ファミリー:リビジョン番号 の形式で表示されます。

taskRoleArn

文字列型の非必須項目です。

タスク定義を登録するときにIAMロールを割り当てることができ、タスクのコンテナにポリシーに指定されたAWS APIを呼び出すためのアクセス権限を付与できます。

詳しくはこちらをご覧ください。

executionRoleArn

文字列型の非必須項目です。

こちらもタスク定義を登録する際にIAMロールを割り当てるでき、Amazon ECSコンテナエージェントに権限を付与することができます。

詳しくはこちらをご覧ください。

networkMode

文字列型の非必須項目です。

タスクのコンテナで使用するDockerネットワークモードを指定することができます。有効な値としては nonebridgeawsvpchost があり、デフォルトは bridge です。Fargate起動タイプを使用する場合は awsvpc を指定する必要があります。

awsvpc を指定する場合は、タスクにElastic Network Interfaceが割り当てられます。そのため、タスク定義を使用したサービスの作成時、または、タスクの実行時にNetworkConfiguration(VPCやサブネット)を指定する必要があります。

cpuとmemory

どちらも文字列型の必須項目(Fargate起動タイプの場合)です。

cpu はタスクに適用されるCPUユニットの制限で、CPUユニット数(256など)またはvCPU(.25 vCPUなど)で表します。

memory はタスクに適用されるメモリの制限で、MiBを使用した整数(512など)またはGBを使用した文字列(0.5 GBなど)で表されます。

cpu の値ごとにとれる memory の値の範囲が決まっていますので注意してください。

containerDefinitions

コンテナの定義に関わるオブジェクトの配列です。

Dockerイメージ、環境変数、secrets、ポートマッピングなど様々な設定項目があります。非常に多くの項目があるため詳細は割愛します。詳しくはこちらをご覧下さい。

定義例

参考までに前回の記事で作成したタスク定義のJSONを載せます。

余談ですが、タスク定義のJSONを取得する方法はいくつかあります。例えば、既存のタスク定義の「新しいリビジョンの作成」画面の下部にある「JSONによる設定」を開くと表示されるもの。タスク定義の「JSON」タブに表示されているもの。 aws cli で取得できるものなどです。これらはいずれも表示される項目が微妙に異なります(cliで取得できる値は特に異なる)。ここで表示しているのは「JSONによる設定」で表示されたJSONです。

ちなみに、JSONからタスク定義を作成する方法は2種類あります。1つ目は「JSONによる設定」に貼り付ける方法。2つ目は aws cliaws ecs describe-task-definition コマンドで登録する方法です。

タスクでのデータボリュームの使用

ECSでは以下のデータボリュームをサポートしています。

  • Fargate タスクストレージ
  • Amazon EFS ボリューム
  • FSx for Windows File Server ボリューム
  • Docker ボリューム
  • バインドマウント

ただし、Fargate起動タイプを選ぶ場合は、タスクストレージ、EFS、バインドマウントのみ利用できるようです。

Fargate タスクストレージ

Fargateでホストされている各タスクは、プロビジョニングされる際にバインドマウントのためのエフェメラル (ローカル)ストレージを受け取ります。これらをマウントし、タスク定義内で volumesmoutPoints および volumesFrom パラメータを使用しているコンテナ間で共有することができます。

ECSタスクはデフォルトで20GiBの(最大200GiBまで増やせる)エフェメラルストレージを受け取ります。

pull、compress、uncompressされたコンテナイメージはエフェメラルストレージに保存されます。つまり、コンテナイメージの容量+指定したエフェメラルストレージの容量がコンテナの総容量になります。

Amazon EFS ボリューム

EFS(Elastic File System)では、ECSタスクで使用するためのシンプルでスケーラブルなファイルストレージを提供します。このストレージ容量は伸縮性があり、ファイルの追加や削除に伴って自動的に拡大、縮小されます。

EFSを使用すると各タスクは配置されているインスタンスに関わらず、常に同じ永続ストレージにアクセスできます。

Docker ボリューム

組み込みの local ドライバー、またはサードパーティのボリュームドライバーを使用できます。Docker ボリュームはDocker で管理され、ディレクトリはボリュームデータを含むコンテナインスタンスの /var/lib/docker/volumes に作成されます。

Docker ボリュームを使用するには、タスク定義で dockerVolumeConfiguration を指定します。

バインドマウント

ホスト(FargateまたはEC2インスタンス)上のファイルまたはディレクトリがコンテナにマウントされます。

デフォルトではバインドマウントは、それらを使用しているコンテナのライフサイクルに紐付けられています。タスクが停止するなど、バインドマウントを使用するすべてのコンテナが停止すると、データが削除されます。

環境変数の引き渡し

環境変数は以下の方法でコンテナに渡すことができます。

  • コンテナ定義パラメータの environment に個別に定義する
  • コンテナ定義パラメータの environmentFiles にファイルを指定する

environmentに個別に定義する

以下のように namevalue を定義します。これは docker run--env オプションにマッピングされます。

environmentFilesにファイルを指定する

S3にホストされている.envファイルを指定します。これは docker run--env-file オプションにマッピングされます。

コンテナへの機密情報の受け渡し

AWS Secret Managerのsecrets、またはAWS System Manager Parameter Storeのパラメータに機密情報を保存した上で、コンテナ定義から参照することによってコンテナに機密情報を取り込む事ができます。

以下の方法でsecretsををコンテナに公開できます。

  • containerDefinitionsのsecretsパラメータを使用して、機密情報を環境変数としてコンテナに挿入する
  • containerDefinitionsのsecretOptionsを使用して、ログ設定へ機密情報を挿入する

タスク定義でSecret Managerシークレットを参照する

コンテナ定義でSecret Managerシークレットを参照する方法を示します。

ほかにも、シークレット内の特定のキーの参照や特定のバージョンシークレットを参照することもできます。詳しくはこちらをご覧下さい。

環境変数として機密情報を挿入

コンテナ定義でコンテナに設定する環境変数名と、コンテナに渡す機密情報が含まれているSystems Manager Parameter Storeのパラメータの完全なARNを使用してsecretを指定します。

Secrets ManagerとParameter Storeどちらが良いか

本記事の内容から外れている為多くは語りませんが、小規模Webシステムなどパラメータへのアクセス頻度が少ない場合はParameter Storeを使い、より多くの取得リクエストがある場合はSecrets Managerを使うのが良さそう(ただし有料)です。

この2つの比較についてはこちらの記事をご覧ください。

さいごに

ECSのタスク定義について深堀りしました。次回は同じくECSのサービスについて調べみたいと思います。

おすすめ書籍

AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解) AWSコンテナ設計・構築[本格]入門 AWS認定資格 ソリューションアーキテクトアソシエイトの教科書: 合格へ導く虎の巻

blog-page_footer_336




blog-page_footer_336




-BackEnd
-

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

php logo

PHPでGmail APIを利用してメールデータを取得してみる

1 はじめに2 Gmail API の有効化3 OAuthクライアントの作成4 Google Clientライブラリのインストール5 OAuth認証6 メールデータの取得7 さいごに8 おすすめ書籍 ...

laravel logo

コードでわかるLaravelのブラウザ認証

1 はじめに1.1 認証機能の概要2 Controller3 SessionGuard3.1 fireAttemptEvent3.2 retrieveByCredentials3.3 hasValid ...

rails

Shrineを使って画像をアップロードする

1 はじめに2 Shrineとは2.1 簡単な説明2.2 作者2.3 特徴3 下準備3.1 Gemを追加3.2 初期設定3.3 テーブルを作成する4 実装4.1 Uploaderの実装4.2 Mode ...

Go言語

goroutineとchannelとContext

1 はじめに2 並行処理と並列処理3 goroutine4 channel4.1 channelからデータ受信4.2 for-range でのデータ受信4.3 複数のchannelを受信4.4 buf ...

rails

RailsでAjax処理で画面を更新する

1 はじめに2 View(遷移元)の設定3 Controllerの実装4 View(遷移先)の実装5 参考6 さいごに はじめに RailsでAjax処理で画面を更新する方法を簡単に紹介します。 Vi ...

フォロー

blog-page_side_responsive

2022年12月
 123
45678910
11121314151617
18192021222324
25262728293031

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。