

# Amazon ECS コンテナイメージのベストプラクティス
<a name="container-considerations"></a>

コンテナイメージは、コンテナの構築方法に関する一連の指示です。コンテナイメージには、アプリケーションコードと、アプリケーションコードの実行に必要なすべての依存関係が保持されます。アプリケーションの依存関係には、アプリケーションコードが依存するソースコードパッケージ、インタープリタ型言語の言語ランタイム、および動的にリンクされたコードが依存するバイナリパッケージが含まれます。

コンテナイメージを設計および構築する際には、次のガイドラインに従ってください。
+ すべてのアプリケーションの依存関係をコンテナイメージ内に静的ファイルとして保存することで、コンテナイメージを完成させます。

  コンテナイメージ内の何かを変更する場合は、変更内容を反映した新しいコンテナイメージを構築します。
+ コンテナ内で単一のアプリケーションプロセスを実行します。

  コンテナの有効期間は、アプリケーションプロセスが実行されている期間です。Amazon ECS は、クラッシュしたプロセスを置き換えると共に、置き換え後のプロセスをどこで起動するかを決定します。適切に完成されたイメージは、デプロイ全体の耐障害性を高めます。
+ アプリケーションが `SIGTERM` を処理できるようにします。

  Amazon ECS は、タスクを停止する場合、まず SIGTERM シグナルをそのタスクに送信し、アプリケーションを終了してシャットダウンする必要があることを通知します。その後、Amazon ECS は `SIGKILL` のメッセージを送信します。アプリケーションが `SIGTERM` を無視した場合、Amazon ECS サービスはしばらく待ってからプロセスを終了する `SIGKILL` シグナルを送信する必要があります。

  アプリケーションが作業を完了するまでにかかる時間を特定して、アプリケーションが確実に `SIGTERM` シグナルに対応できるようにしてください。アプリケーションによるシグナル対応においては、アプリケーションがそれ以上新しい作業を取得するのをストップするとともに、進行中の作業を完了するか、または完了までに長い時間がかかる場合は、タスクの外部のストレージに未完了の作業を保存する必要があります。
+ ログを `stdout` および `stderr` に書き込むように、コンテナ化されたアプリケーションを設定します。

  ログ処理をアプリケーションコードから分離することで、ログ処理をインフラストラクチャレベルでより柔軟に調整できるようになります。その一例として、ロギングシステムの変更があります。サービスを変更したり、新しいコンテナイメージを構築してデプロイする代わりに、設定の調整により対応できます。
+ タグを使用してコンテナイメージをバージョニングします。

  コンテナイメージはコンテナレジストリに保存されます。レジストリ内の各イメージはタグによって識別されます。`latest` というタグがあります。このタグは、git リポジトリの `HEAD` と同様に、アプリケーションコンテナイメージの最新バージョンに対するポインターとして機能します。`latest` タグはテストのみに使用することが推奨されます。ベストプラクティスとして、ビルドごとにコンテナイメージに一意のタグを付けます。イメージの構築に使用された git コミットの git SHA を使用してイメージにタグ付けすることをお勧めします。

  コミットごとにコンテナイメージを構築する必要はありません。ただし、特定のコードコミットを本番環境にリリースするたびに、新しいコンテナイメージを構築することをお勧めします。また、イメージに対して、イメージ内のコードの git commit に対応するタグを付けることをお勧めします。イメージに git commit のタグを付けた場合、イメージが実行しているコードのバージョンをより迅速に見つけることができます。

  また、Amazon Elastic Container Registry でイミュータブルなイメージタグをオンにすることをお勧めします。この設定では、タグがポイントするコンテナイメージを変更することはできません。代わりに、Amazon ECR は、新しいイメージを新しいタグにアップロードするよう強制します。詳細については、「*Amazon ECR ユーザーガイド*」の「[イメージタグの変更可能性](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-tag-mutability.html)」を参照してください。

AWS Fargate で実行されるアプリケーションを構築する場合には、複数のコンテナを同一のタスク定義にデプロイするか、あるいは複数のタスク定義に個々のコンテナを別々にデプロイするかのいずれかを選択する必要があります。以下のような要件がある場合には、1 つのタスク定義にコンテナを配置することをお勧めします。
+ 各コンテナが同じライフサイクルを共有している (つまり、起動と終了が同時に行われる)。
+ 実行基盤となるホストが同じになるようにコンテナを実行する (つまり、あるコンテナが、localhost ポート上の別のコンテナを参照する) 必要がある。
+ 各コンテナがリソースを共有している。
+ コンテナでデータボリュームを共有している。

上記の要件がない場合は、複数のタスク定義でコンテナを個別にデプロイすることをお勧めします。これにより、各コンテナを個別にスケーリング、プロビジョニング、およびデプロビジョニングできます。