👻

ECSを最近触ってみたので、改めて整理する

に公開

AWSが提供するフルマネージド型のコンテナオーケストレーションサービスで、Dockerなどのコンテナ技術を簡単かつ安全に実行・管理できるように設計されています。AmazonECS (Elastic Container Service) を利用すれば、仮想サーバーであるEC2上にコンテナをデプロイする場合と比べて、以下のように運用管理の負担を減らすことが可能です。

  • サーバー管理の簡略化
  • 柔軟なスケーリングと自動復旧
  • AWSとのシームレスな統合

コンテナ実行基盤としてEC2をそのまま使う場合、OSの管理やセキュリティパッチの適用など、管理者が担う領域が多く残ります。一方、ECS (特にFargate) であればコンテナのみを意識して動かすことができ、下層のインフラ負担を大幅に軽減できます。

なぜ今コンテナなのか?

新規アプリケーションのデファクトスタンダードになりつつある

State of Cloud Native Application Securityという記事によると、新規のアプリの78%がコンテナまたはサーバレスで構築されており、うちコンテナは58%を占めているそうです。これらの数字が示すとおり、コンテナは新規アプリケーションのデファクトスタンダードになりつつあります。

コンテナとは何か?

コンテナは、ホスト OS のカーネルを共有しながら、アプリケーションごとに独立した環境で実行できるようにする OS レベルの仮想化技術です。
具体的には、Linux の cgroups (control groups) や namespaces といった機能を組み合わせ、アプリケーション同士のリソース管理やプロセス空間を分離します。これにより、ホスト OS や他のアプリケーションに影響を与えずに動作可能な環境が実現されます。

Docker との関係

コンテナ自体は Linux カーネルの機能である cgroups や namespacesによって実装できますが、直接扱うには設定・管理が複雑になりがちです。そこで、Dockerのようなコンテナランタイム兼管理ツールが登場しました。Dockerは、コンテナに必要な設定をまとめたイメージを管理・配布しやすくし、手軽にコンテナを起動・停止できるコマンドやAPIを提供します。これによって、コンテナ技術を使ったアプリケーション開発・運用が飛躍的に簡易化されました。

コンテナのメリット

  1. 軽量かつ高速な起動

    • ホスト OS のカーネルを共有しているため、仮想マシンのように OS 全体を起動する必要がなく、起動時間が短くリソース消費も少なめです。
  2. リソースを効率的に利用

    • cgroups により CPU・メモリなどを制御・監視できるほか、namespaces によるプロセス空間の分離でリソースの衝突を低減。仮想マシンより無駄が少なく運用できます。
  3. 環境の移植性(ポータビリティ)

    • コンテナイメージにアプリケーションと依存関係をまとまった形で保持するため、開発環境・本番環境・他のクラウドなど、どこでも同様に動作を再現できます。
  4. デプロイの容易さ

    • コンテナイメージ単位でデプロイできるため、コードの修正からアプリケーション反映までの手順が単純化されます。CI/CD
      との連携もしやすく、リリースサイクルを短縮可能です。
  5. アプリケーションの独立性

    • cgroups や namespaces による隔離機能のおかげで、あるコンテナの不具合が他のコンテナへ波及しにくく、障害時の切り分けが容易になります。

上記のように、コンテナは OS レベルの仮想化により軽量かつ高速な環境を提供し、Docker のようなツールが設定やイメージ管理を支援することで、近年のアプリケーション開発・運用には欠かせない存在となっています。

コンテナオーケストレーションの必要性

コンテナは軽量かつ高速な起動や環境の移植性といったメリットを備える一方で、複数のコンテナを本番環境で安定的に稼動させたり、スケールに応じて自動化・管理したりするには、コンテナオーケストレーションが必要です。

ここで役立つのが Amazon Elastic Container Service (ECS) です。ECS は AWS が提供するフルマネージドのコンテナオーケストレーションサービスであり、以下のような利点があります。

  1. クラスタ管理の自動化
    ECS はコンテナを実行するためのクラスタ(EC2、または Fargate のようなサーバレス実行環境)を自動的に管理します。コンテナをどのサーバに配置するか、どれだけの数を起動するかなどを
    ECS が担うため、開発者はアプリケーション実装に集中できます。
  2. AWS との統合が容易
    AWS の他のサービス(EC2、Load Balancer、CloudWatch Logs、IAM、Secrets Manager
    など)とシームレスに連携できるため、認証・権限管理やログ取得、スケーリングなどの運用が一元化しやすくなります。
  3. スケーリング機能
    需要に応じてコンテナ数を自動的に増減するオートスケーリング機能が備わっており、アクセス集中にも柔軟に対応可能です。無駄なリソースを抱え込むことなく、必要なときに必要なだけコンテナを起動できます。
  4. 運用負荷の軽減
    コンテナが増えてくると、手動で管理・デプロイ・スケールを行うのは困難です。ECSはタスク定義(コンテナ設定)やサービスという概念を用いてコンテナを制御し、障害時の再起動も自動化します。これにより運用負荷が大幅に下がります。
  5. 高い可用性
    AWS インフラ上で複数のアベイラビリティーゾーンにわたってコンテナを配置でき、コンテナのヘルスチェックや再起動を自動化することで、サービスダウンを最小限に抑えられます。

このように、コンテナ技術の利点を最大限に活かしつつ、運用管理をシンプルにするために、ECSのようなコンテナオーケストレーションサービスが不可欠です。Dockerで作成したイメージをそのままECSにデプロイすることができ、AWSの他のサービスとも簡単に連携しながら、安全かつ効率的にコンテナアプリケーションを運用できます。

ECS on Fargate と EC2 の比較

1. 軽量性と起動速度

EC2インスタンスを利用する場合、
OSが起動するまでに数十秒から数分程度かかることが一般的です。特に初回の起動時はユーザーデータスクリプトの実行やAMIの特性などによって、さらに時間がかかる場合があります。ただし、一度OSが稼働してしまえば、アプリケーションの再起動や更新はOSブートが不要であるぶん比較的短時間で済むため、アプリケーションの再デプロイはスムーズに行えます。
一方、スケールアウト目的で新規にインスタンスを立ち上げる場合は、再度OSのブートとアプリケーションセットアップが必要になるため、起動完了まで数分程度の遅延が生じる可能性があります。

ECS on Fargateでは、 ホストOSの管理をユーザーが行う必要がないサーバーレス形態を採用していますが、実際にはENI(Elastic
Network Interface)のアタッチやDockerイメージのプルなどの処理が内部的に行われます。
タスクの起動には数秒から数分程度の時間がかかる場合があり、イメージサイズの大きさや同時に起動するタスク数によってはさらに時間が延びることがあります。
また、タスク単位で柔軟にスケールアウトが可能なため、小刻みなスケーリングがしやすいという利点がありますが、大量のタスクを一度に起動する際にはリソース待ちなどで起動時間にばらつきが生じる可能性がある点に留意が必要です。

2. リソース効率

EC2では、 インスタンス単位でCPUやメモリなどのリソースが割り当てられます。オートスケーリングを使ってインスタンスを追加・削除できるものの、リソースの単位が大きいため、需要の変動に対して細かな最適化は難しい面があります。結果として、必要以上のリソースを抱える過剰プロビジョニングが発生しやすくなる可能性があります。
また、インスタンスを増減させるオートスケーリングでは、どうしても単一のインスタンス単位での管理になるため、細かいリソース管理が煩雑になる場合があります。

ECS on Fargateでは、 タスクごとに必要なCPUやメモリ量を指定し、利用した分だけ課金されます。そのため、過剰なリソースを事前に確保する必要がなく、コストを抑えながら効率的に運用できます。
また、需要に合わせてタスク単位で増減できるため、小規模・短時間のワークロードなど変動が激しいシナリオにも柔軟に対応できる点が魅力です。

3. デプロイと移植性

EC2に対するデプロイは、 手動でファイルを配置してアプリを起動する方法や、Chef、Ansible、Puppet、AWS CodeDeployなどの構成管理ツールを活用する方法など、複数のアプローチがあります。手軽に始められる反面、OSやライブラリのバージョン差異が発生しやすく、運用手順を統一していない場合は環境の不整合がリスクとなります。
構成管理ツールを使えば、より安定した再現性の高い運用が可能ですが、その分セットアップやメンテナンスの手間がかかります。

ECS on Fargateでは、 Dockerイメージとしてアプリケーションと依存関係を一元化し、コンテナとしてデプロイを行います。このため、同一のコンテナイメージをどの環境にデプロイしても基本的には同じ動作が期待でき、移植性が高いのが特徴です。
具体的なデプロイ手順は、イメージをビルドし、レジストリにプッシュし、タスク定義を更新した後にECSで新しいタスクを起動するというフローとなります。
CI/CDパイプラインを整備することで、環境の再現性を高めつつ、ロールバックも容易に行え、安定した運用を実現できます。

4. 運用負荷と自動化

EC2の場合、 OSのパッチ適用やセキュリティ設定、モニタリングなどのOSレイヤー管理をユーザー自身が行う必要があります。これらは一定の運用コストを伴い、特に台数が増えると管理の手間も大きくなります。
また、スケーリングがインスタンス単位で行われるため、リソースの過不足を細かく調整しづらく、場合によってはリソース配分に偏りが生じる可能性があります。

ECS on Fargateは、 フルマネージドのサービスであり、ホストOSの管理やパッチ適用といった作業はAWS側が担うため、利用者はアプリケーションやコンテナの管理に集中できます。その結果、運用負荷が大幅に軽減されるのがメリットです。
さらに、タスクごとの自動再起動やスケーリングが容易に設定できるため、障害や負荷変動に対して素早く対応でき、システム全体としての安定性や効率性を向上させられます。

5. 高い可用性とセキュリティ

EC2では、 Auto Scaling Groupを用いてインスタンスが障害を起こした場合に自動的に置き換える機能を提供しており、高可用性の構築が可能です。ただし、OSやミドルウェアのメンテナンスやセキュリティパッチ適用は、各インスタンスで個別に行う必要があります。このため、インスタンス数が多いほど管理コストが増大するリスクがあります。
また、セキュリティ設定やパッチ適用が漏れると脆弱性が残りやすい点にも注意が必要です。

ECS on Fargateでは、 AWSがホストOSやネットワークなどのインフラレイヤーを管理・保守しているため、利用者はアプリケーションレイヤーに集中できます。このフルマネージド環境によって可用性が高く保たれ、ホストOSの障害対応やセキュリティパッチの適用を意識する必要が少ないという利点があります。
一方で、コンテナのベースイメージ更新や再ビルドは利用者の責任範囲になるため、これらのメンテナンス作業を怠るとセキュリティリスクを残す可能性がある点には注意が必要です。

その他の考慮点

  • コスト面

    • Fargateは特に小規模・短時間のワークロードで従量課金のメリットを活かしやすい反面、長時間・大規模ワークロードにおいてはEC2(リザーブドインスタンスやSavings
      Plans)の方がコストメリットが大きくなる場合があります。
    • EC2であればリザーブドインスタンスやSavings Plansなどを活用して、長期利用を見越したコスト最適化が可能です。
  • ECS on EC2 という選択肢

    • ECSはFargateだけでなく、EC2をクラスターとして利用する「ECS on EC2」という形態も選択可能です。
    • ホストOSの管理負荷はあるものの、ECSのコンテナオーケストレーション機能を活用できるため、柔軟性が高まるケースがあります。
    • 一部のタスクをFargateで運用し、別のタスクをECS on EC2で運用するハイブリッド構成も可能です。
  • 起動時間のばらつき

    • Fargateのタスク起動時にはENIのアタッチやイメージプルなどが行われ、数秒~数分とばらつきが出る場合があります。
    • EC2インスタンスの場合も、AMIの内容やユーザーデータの処理時間によって数十秒~数分の起動時間の差が生じる可能性があります。

まとめ

ECS on Fargate はホストOSの管理が不要なサーバーレス型のコンテナ実行環境であり、タスク単位の柔軟なスケーリングや従量課金によるリソース効率の高さが魅力です。一方、EC2
を用いた場合は OS レイヤーの管理やパッチ適用といった運用負荷が増えますが、リザーブドインスタンスや Savings Plans
などを活用することで大規模・長期のワークロードではコストを最適化しやすい利点があります。

また、Fargate ではアプリケーションを Docker イメージとして一元化するためデプロイや移植性に優れる一方、EC2
では構成管理ツールによる柔軟なカスタマイズが可能です。用途や規模、予算、既存の運用体制に応じて Fargate と EC2
を使い分けたり、ハイブリッド構成を検討すると良いでしょう。

ECSの主な構成要素

ECSはコンテナオーケストレーションサービスであり、以下のような構成要素から構成されています。

クラスター(Cluster)

ECS でコンテナを実行するリソースをグルーピングする単位が クラスター です。 Fargate では、クラスターの作成時にインフラを意識せず、単に論理的な入れ物としてクラスターを定義するだけで運用を始められます。

後述のタスクやサービスは、どのクラスター上で稼働させるのかを指定して起動します。
クラスターはアプリケーションごとに分けたり、環境(開発・ステージング・本番など)ごとに分けたりするなど、運用ポリシーに合わせて設計します。

タスク定義(Task Definition)

Fargate でコンテナを起動するための設定情報をまとめた「設計図」が タスク定義 です。コンテナイメージの参照先や必要な CPU、メモリ量、ポート設定、環境変数、ログ設定などを記述します。

1 つのタスク定義で複数のコンテナを定義することも可能です(サイドカーコンテナなど)。タスク定義はバージョン管理されており、更新のたびにリビジョンが上がります。問題があった場合でも過去のリビジョンへロールバックしやすい構造です。

タスク(Task)

タスク定義を元に実行されるコンテナ群の単位をタスクと呼びます。タスクが起動されると、設定されたコンテナイメージが必要なCPU、メモリ量を確保して動き始めます。

Fargateでは、必要なコンピューティングリソースが自動で割り当てられるため、インスタンス管理は不要です。タスクが停止した場合なども、サービス設定によっては自動的に再起動されます(後述のサービス機能と組み合わせる場合)。

サービス(Service)

タスクを必要な数だけ常時稼働させたり、スケーリングルールに従って増減させたりする仕組みが
サービスです。サービスに「最小タスク数」や「最大タスク数」を設定しておくと、一定の数を常に維持するよう ECS が監視・制御します。
アプリケーション負荷の増減に応じてタスクを自動的にスケーリングさせることも可能です。

Fargateでは障害やタスク停止が発生した場合にサービスが自動リカバリし、新しいタスクを起動して可用性を担保します。

ネットワーク (awsvpc)

Fargate のネットワークモードは awsvpc のみで、タスクごとに独立した Elastic Network Interface (ENI) とプライベート IPアドレスが割り当てられます。各タスクが VPC 内で固有の IP を持つため、セキュリティグループやネットワーク ACL を細かく制御できます。コンテナごとの通信制御が簡易化され、ほかのタスクとの IP やポートの衝突リスクを減らせます。

IAM とセキュリティ

Fargate タスクが外部サービス(S3 や Secrets Manager など)にアクセスする際は、IAM ロール や IAM ポリシー を正しく設定することで必要最小限の権限を与えられます。 サービスごとにロールを分けることで、セキュリティリスクを局所化できます。
Fargate ではホスト OS の管理が AWS によって行われるため、OSレベルのパッチ適用などは不要ですが、タスク定義で指定したコンテナイメージの更新やベースイメージの脆弱性対策は利用者の責任範囲となります。

ログとモニタリング

Fargate タスクで発生するログは、CloudWatch Logs などに簡単に送信・保管できます。タスク定義にてログドライバ(awslogs など)を設定するだけで、コンテナの標準出力が自動的に収集されます。ログの集中管理を行うことで、トラブルシューティングや監視が容易になり、別の監視ツールとの連携もシンプルになります。

参考

Discussion