Amazon ECS によるコンテナオーケストレーション - タスク定義とサービス設計

タスク定義の設計からサービスのデプロイ戦略、Fargate と EC2 の使い分け、Auto Scaling の設定パターンまでを体系的に紹介します。

タスク定義とクラスター設計

ECS のタスク定義はコンテナの実行仕様を JSON で記述するテンプレートです。1 つのタスク定義に複数のコンテナを含めることができ、サイドカーパターンでログ収集やプロキシコンテナを同一タスク内に配置します。起動タイプは EC2Fargate の 2 種類があり、EC2 起動タイプではインスタンスの管理が必要ですが GPU やカスタム AMI を利用できます。Fargate 起動タイプではインフラ管理が不要で、タスク単位の CPU・メモリ指定のみで実行できます。タスク定義のリビジョン管理により、過去のバージョンへのロールバックも容易です。タスク定義では ephemeralStorage (最大 200 GiB) を指定して一時ストレージを拡張でき、大量の中間データを生成するバッチ処理に有用です。また、タスクロール (taskRoleArn) とタスク実行ロール (executionRoleArn) を分離し、コンテナが利用する AWS API 権限とイメージのプルやログ出力に必要な権限を最小権限の原則で管理します。

サービスとデプロイ戦略

ECS サービスはタスクの希望数を維持し、異常終了したタスクを自動的に再起動します。ALB のターゲットグループと統合することで、ヘルスチェックに失敗したタスクを自動的にドレインし新しいタスクに置き換えます。ローリングアップデートでは minimumHealthyPercent と maximumPercent を設定し、段階的にタスクを入れ替えます。例えば minimumHealthyPercent=50、maximumPercent=200 とすれば、既存タスクの半数を維持しながら新タスクを起動し、ヘルスチェック通過後に旧タスクを停止する流れになります。CodeDeploy 統合による Blue/Green デプロイでは、新バージョンのタスクセットを作成し、トラフィックを段階的に切り替えることでゼロダウンタイムデプロイを実現します。CodeDeploy のフック (BeforeAllowTraffic / AfterAllowTraffic) で自動テストを挟み、テスト失敗時に 5 分以内で旧バージョンへ自動ロールバックさせる構成が本番運用では推奨されます。ECS Service Connect を使えば、サービス間のサービスディスカバリと負荷分散を ECS ネイティブで完結でき、App MeshCloud Map の個別設定を省略できます。

Fargate と EC2 の使い分け

Fargate はサーバーレスのコンピューティングエンジンで、EC2 インスタンスの管理が不要です。タスクごとに vCPU とメモリを指定し、実行時間分のみ課金されます。EC2 起動タイプはインスタンスの選択、GPU の利用、カスタム AMI の使用が必要な場合に適しています。Fargate Spot はバッチ処理や耐障害性のあるワークロード向けで、通常の Fargate より最大 70% 安価です。ECS Exec でタスク内のコンテナにインタラクティブシェルを起動し、デバッグやトラブルシューティングを実行できます。Fargate は 2024 年にタスクあたり最大 16 vCPU / 120 GB メモリまでサポートされ、大半の Web アプリケーションやデータ処理に十分なスペックを提供します。一方 EC2 起動タイプは p5 インスタンスで NVIDIA H100 GPU を利用した ML 推論、あるいは inf2 で AWS Inferentia2 を使う場合など、特殊なハードウェアが必要なワークロードに限定して選択するのが合理的です。 コンテナのオーケストレーションを網羅的に学ぶなら、技術書 (Amazon)を参照してください。

ECS のコスト最適化

Fargate の料金は vCPU (1 時間あたり約 0.04048 ドル) とメモリ (1 GB 時間あたり約 0.004445 ドル) の従量課金です。Compute Savings Plans で最大 50% の割引が適用されます。EC2 起動タイプではスポットインスタンスを活用し、タスクの配置戦略 (binpack) でインスタンスの使用率を最大化します。タスク定義の CPU とメモリを Container Insights のメトリクスに基づいて適正化し、過剰なリソース割り当てを削減します。サービスの Auto Scaling でターゲット追跡ポリシーを設定し、CPU 使用率に基づいてタスク数を自動調整します。見落としがちなコスト要因として、CloudWatch Logs のデータ取り込み料金があります。コンテナが大量のログを出力する場合、awslogs ドライバーのログレベルを適切に制御するか、FireLens (Fluent Bit) で不要なログをフィルタしてから CloudWatch へ送ることで月額数十ドルの削減につながります。

設計のベストプラクティスと落とし穴

タスク定義で healthCheck を設定する際、startPeriod (猶予期間) を十分に確保しないと、起動に時間のかかるアプリケーションが起動直後にヘルスチェック失敗として再起動ループに陥ります。Java や .NET のように JIT コンパイルでウォームアップが必要な言語では startPeriod を 60-120 秒に設定するのが実践的です。タスク間通信では awsvpc ネットワークモードが推奨され、各タスクに固有の ENI が割り当てられるためセキュリティグループでタスク単位のアクセス制御が可能です。ただし ENI の密度制限 (インスタンスタイプごとの ENI 上限) により、小規模インスタンスに多数のタスクを詰め込めない点に注意が必要です。シークレット管理では Secrets Manager や SSM Parameter Store の値をタスク定義の secrets フィールドで直接参照し、環境変数へのハードコードを避けます。また、ECS の execute-command を本番で安易に有効にすると、SSM セッション経由で任意のコマンド実行が可能になるため、IAM ポリシーで利用者を厳格に制限してください。

ECS と EKS の使い分け

ECS は AWS 固有のオーケストレーターであり、EKS は Kubernetes のマネージド版です。チームに Kubernetes の運用経験がなく、AWS サービスとの緊密な統合 (ALB Controller 不要の ALB 統合、CloudFormation/SAM でのネイティブ定義) を重視する場合は ECS が適しています。一方、マルチクラウドやオンプレミスとのポータビリティ、Helm チャートで公開された OSS ツール群 (Argo CD、Istio、Prometheus Operator 等) を活用したい場合は EKS が有利です。運用負荷の観点では、ECS + Fargate は Control Plane もデータプレーンも AWS が管理し、YAML の学習コストも低いため小規模チームに向いています。EKS は Control Plane こそマネージドですが、ノードグループやアドオンのバージョンアップ、RBAC 設計、NetworkPolicy の管理といった Kubernetes 固有の運用が発生します。コスト面では、EKS は Control Plane に月額 0.10 ドル/時間 (約 74 ドル/月) のクラスター料金がかかりますが、ECS にはこの固定費がありません。ワークロードの特性とチームのスキルセットに合わせて選定するのが実践的です。

まとめ

ECS はタスク定義による宣言的なコンテナ管理と、サービスによる自動復旧・スケーリングを提供します。Fargate でサーバーレスにコンテナを実行し、Fargate Spot で最大 70% のコスト削減を実現します。ローリングアップデートと Blue/Green デプロイでダウンタイムゼロのリリースを行い、Container Insights でパフォーマンスを可視化します。healthCheck の startPeriod や ENI 密度制限といった実運用上の落とし穴を押さえ、ECS Service Connect でサービス間通信をシンプルにすることが、安定した本番運用の鍵です。