Amazon ECSの基礎知識と役割

こんにちは。BinaryBudです。 AWSを触り始めると「ECS(イーシーエス)」という言葉をよく耳にするようになります。最初は「なんだか難しそう」と敬遠しがちですが、一度考え方の核心をつかめば、「なるほど、そういうことね」とすっと腑に落ちるはずです。 このセクションでは、ECSがそもそも何のために存在し、私たちにどんな恩恵をもたらしてくれるのか、その基礎知識と役割を一緒に紐解いていきましょう。

Amazon ECSとは

ECS(Elastic Container Service)は、AWS上でDockerコンテナを実行・管理するための「フルマネージド」なサービスです。

一口にコンテナと言っても、ただDockerを使って「箱(コンテナ)」を作るだけなら、自分のPC上で十分可能です。しかし、それをインターネットに公開するような本番環境で動かそうとすると話は別です。「どのサーバーにいくつ配置するか」「障害時にどう復旧させるか」といったインフラの管理が必要になります。

ここで登場するのがECSです。ECSは、コンテナを動かすための土台となるサーバー管理や、コンテナの配置・監視といった面倒な作業をAWS側で肩代わりしてくれます。私たちは「どんなアプリを動かしたいか」という開発に集中できるのが最大の特徴です。

[NOTE] 「フルマネージド」とは、サーバーのOSアップデートやソフトウェアのメンテナンスなど、裏側の地味ですが重要な運用作業をすべてAWSが自動でやってくれる状態を指します。そのため、利用者はインフラの構築や保守から解放されます。

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

「フルマネージド」の良さを理解するために、ECSのようなサービスがなかったらどうなるかを考えてみましょう。

開発環境であれば、docker runコマンドを1回叩けばアプリが動きます。しかし、本番環境ではユーザーからのアクセスが集中するため、コンテナを数個〜数十個と増やす必要があります。たとえば、Webアプリのコンテナを10個、DBのコンテナを2個動かしている状態を想像してみてください。

この状態で「サーバーAが壊れた」「アクセスが急増してコンテナを5個増やしたい」といった事態が起きた場合、手動で対応しようとすると途端に破綻します。人間が「サーバーBにコンテナを移動しよう」「サーバーCを新しく追加して…」と考えて操作していたら、復旧や対応が間に合わず、サービスが長時間止まってしまう可能性が高いからです。

ここで必要になるのが「オーケストレーション(管弦楽法・指揮)」という考え方です。ECSはまさにオーケストラの指揮者のように、コンテナの自動配置や、死んでしまったコンテナの自動復旧、アクセス増加に合わせた自動スケーリングを一手に引き受けてくれます。これにより、コンテナ運用が人間の手作業から完全に解放されるのです。

AWSにおけるマネージドサービスの利点

コンテナのオーケストレーションソフトウェアには、世界的に有名な「Kubernetes」などもありますが、それを自分で構築・運用するのは非常に手間がかかります。AWSのマネージドサービスとしてECSを使うことには、具体的にいくつかの利点があります。

まず1つ目は、AWSのセキュリティ機能とネイティブに統合されている点です。代表的なものがIAM(Identity and Access Management)との連携です。ECSでは、動いているコンテナ(タスク)自体にIAMロールを付与できます。これにより、「このコンテナはS3(ストレージ)の特定のフォルダだけ読み込み可能」といった細かな権限設定が簡単にできるため、セキュリティの基本である「最小権限の原則」を守りやすくなります。

2つ目は、可用性と信頼性です。AWSが管理される基盤上で動くため、マルチAZ(複数のデータセンター)を使った可用性の高い構成を意識せずとも、標準機能として回復力のあるシステムを構築できます。

3つ目は、コスト面でのメリットです。ECS自体の利用に追加料金はかかりません。課金はコンテナを動かすためのインフラに対して発生します。EC2起動タイプを選択した場合は起動したEC2インスタンスへの課金となり、Fargate起動タイプを選択した場合は実際にタスクが動いている時間とリソース(CPUやメモリ)の量に対して従量課金されます。これにより、自前でサーバーを常時稼働させておく場合と比べると、無駄なリソースを削減でき、総所有コスト(TCO)を大幅に抑えることができます。

Amazon ECSを支える4つのコア概念

ECSの内部で実際にどのようなことが行われているのかを見ていきましょう。

ECSを触り始めると、「クラスター」「タスク定義」「タスク」「サービス」といった聞き慣れない言葉が次々と出てきて、混乱してしまうことがあります。実は私も最初は「どれがどれだっけ?」と何度も調べ直していました。でも、これらは全部で4つだけです。それぞれの役割を順番に追っていけば、決して複雑ではありません。

クラスター(リソースの論理的なまとまり)

まずは「クラスター」です。クラスターは、タスクやサービスが実行される基盤となる、リソースの論理的なグループです。

「論理的」という言葉が少し難しく聞こえるかもしれませんが、物理的なサーバーそのものを指しているわけではありません。例えるなら、会社の中の「部署」や「チーム」のようなものです。例えば、「開発用クラスター」と「本番用クラスター」のように分けておけば、開発中のアプリが誤って本番環境のリソースを消費してしまう事故を防ぐことができます。

クラスターを作成する際には、どのネットワーク(VPC)に配置するかを決めます。これにより、クラスターは「このネットワークの範囲内でコンテナを動かすための境界線」として機能するようになります。中身には後述するタスクがどんどん起動してくるのですが、クラスター自身は「それらを収める器」に徹します。

[NOTE] クラスター自体には料金が発生しません。実際の課金は、クラスター内で動いているコンテナ(タスク)が使ったCPUやメモリの量、あるいは起動したインスタンスに対して行われます。

タスク定義(コンテナの設計図)

次に「タスク定義」です。これは、アプリケーションを実行するための設計図(ブループリント)です。

クッキー作りに例えると、タスク定義は「レシピ」です。「小麦粉100g、バター50g、180度で15分焼く」という指示書のように、コンテナを動かすためのすべての条件をここで定義します。

具体的には、以下のような内容をJSON形式というデータ形式で記述します。

  • コンテナイメージ: どのDockerイメージを使うか(例:nginx:1.25
  • CPUとメモリ: コンテナにどれくらいのリソースを割り当てるか(例:CPUは「256」タスク単位=0.25 vCPU、メモリは「512」MBなど)
  • ポート番号: 外部との通信にどのポートを使うか(例:80番ポート)
  • 環境変数: データベースの接続先など、アプリに渡す設定情報

なぜJSON形式なのかというと、AWSのシステムがプログラムから読み書きしやすく、バージョン管理(変更履歴を残すこと)としやすいからです。一度タスク定義を作成して保存すると、後からメモリを増やしたりイメージのバージョンを上げたりした際には、自動的に新しい「リビジョン(改訂版)」として保存されていきます。

タスク(コンテナの実行単位)

設計図(タスク定義)ができたら、次はそれをもとに実際にコンテナを動かします。この「起動した実体」が「タスク」です。

先ほどのクッキーの例えでいくと、レシピ(タスク定義)をもとに焼き上がった「実際のクッキー」がタスクに当たります。1つのタスク定義から、必要な数だけタスクを生み出すことができます。

ECSの面白いところは、1つのタスクの中に複数のコンテナをまとめて入れられる点です。例えば、「Webアプリケーションのコンテナ」と「そのログを別のサーバーに転送し続けるコンテナ」を1つのタスクとして一緒に起動させることで、これらのライフサイクルを完全に同期させることができます。これを「サイドカーパターン」と呼んだりします。

タスクには明確なライフサイクルがあります。PROVISIONING、PENDING、ACTIVATINGを経て「実行中(RUNNING)」となり、処理が終わったりエラーが起きたりするとDEACTIVATING、STOPPINGを経て消滅します。つまり、タスクは長生きするものではなく、必要な時に生まれて、役目を終えたら消える「使い捨ての実行単位」として設計されています。

サービス(タスクの管理・維持)

最後は「サービス」です。個人的に、ECSを本番環境で運用する上で一番重要だと思っているのがこの概念です。

タスクは「使い捨て」だとお話ししました。では、Webサイトのように24時間365日動き続けなければならないアプリケーションをどうやって守るのでしょうか。もしタスクがエラーで停止してしまったら、手動で「タスクを起動して!」と指示を出し続ける必要があるのでしょうか。

それを自動でやってくれるのがサービスです。サービスは「タスクの管理者」として働きます。「このタスク定義を使って、常に3つのタスクを起動しておいて」という指示(希望数)をサービスに渡しておきます。すると、サービスは定期的に状況を監視し、もし1つタスクが異常終了して2つになってしまったら、自動的に新しいタスクを起動して3つの状態を維持してくれます。これを「セルフヒーリング」と呼びます。

また、サービスはロードバランサー(ALBなど)との連動も担います。アクセスが増えて「5つに増やして」と希望数を変更すると、サービスが新しいタスクを2つ起動し、自動的にロードバランサーの配信先に追加してくれます。逆に減らすときも、安全に通信を切り離してからタスクを停止させます。新しいバージョンのアプリをデプロイする際の入れ替え作業(ローリングアップデート)も、このサービスの機能でスムーズに行われます。

[IMPORTANT] 一時的なバッチ処理などでない限り、本番環境で継続して動かし続けるアプリケーションをECSで運用する場合は、単発のタスク実行ではなく、必ず「サービス」として作成・管理するようにしてください。サービスを使わないと、障害時の自動復旧やトラフィックの分散が行われません。

この4つのコア概念は、以下のような関係性で成り立っています。

  1. クラスターという大きな器を用意する
  2. タスク定義でコンテナのレシピを作る
  3. レシピをもとにタスクという実体を動かす
  4. サービスがタスクを監視し、必要な数を維持する

この流れが頭に入ると、ECSのコンソール画面を見たときにも「今はどの部分を設定しているんだな」と迷わずに操作できるようになります。続いて、このタスクを実際に動かすための「土台」である実行環境の選択肢について見ていきましょう。

コンテナ実行環境の選択肢:EC2 vs Fargate

ECSでコンテナを動かそうとしたとき、「あれ、コンテナを乗せるサーバーはどうするんだっけ?」と疑問に思うかもしれません。実はECSには、コンテナを実行する環境として「EC2」「Fargate」「External」という3つの起動タイプが用意されています。Externalはオンプレミス環境などのAWS外のインフラでコンテナを管理したい場合に利用しますが、今回はAWS上で動かす基本的な2つ(EC2とFargate)を中心に、それぞれの特徴と使い分けについて整理していきます。

EC2起動タイプの特徴と考え方

EC2起動タイプは、あなた自身がAWS上の仮想サーバー(EC2インスタンス)を手配して、そこにコンテナを載せるという従来型のアプローチです。「プロビジョニング」と呼ばれる、サーバーを準備して設定する作業からすべて自分で行います。

この方式の最大の魅力は、何と言っても自由度の高さです。サーバーのOSやスペックを完全にコントロールできるため、例えば「特定のLinuxカーネルのバージョンを使いたい」「GPUを使って機械学習の処理を回したい」「特殊なネットワークインターフェースやストレージを直接アタッチしたい」といった要件がある場合には、EC2起動タイプが圧倒的に有利になります。

ただし、その分、運用の責任も自分にのしかかってきます。OSのセキュリティパッチの適用や、サーバーの障害対応、トラフィックが増えたときのサーバー増減(スケーリング)の設定など、インフラの管理作業が必要です。

[WARNING] EC2起動タイプを選ぶ場合、OSのパッチ適用やセキュリティアップデートを定期的に行う必要があります。これを怠るとセキュリティリスクが高まるため、SSM(Systems Manager)などの仕組みを使って更新を自動化しておくことが推奨されます。

Fargate起動タイプの特徴と考え方

一方でFargate(ファーゲート)起動タイプは、「サーバーの管理をAWSに完全に任せて、コンテナの実行だけに集中できる」サーバーレスなアプローチです。

Fargateを使う場合、裏側でどんなサーバーが動いているかを意識する必要がありません。タスク定義(前のセクションで説明した設計図)の中で、「このコンテナには0.5 vCPU(仮想CPU)と、1GBのメモリを割り当てて」と指定するだけで、AWSが自動的にそれに合った環境を用意してコンテナを起動してくれます。

インフラエンジニアがいない小さなチームや、できるだけ運用の手間を減らしたいプロジェクトにとっては、とても心強い味方になります。「サーバーを立てる」という概念自体がなくなるため、OSのアップデートや障害時のサーバー交換といった面倒な作業から完全に解放されるのが大きなメリットです。

[TIP] 「インフラの管理はしたくないけれど、コンテナは動かしたい」という場合は、迷わずFargateを選ぶのがおすすめです。開発者はアプリケーションのコードに集中できるようになります。

運用コストとカスタマイズ性による使い分け

では、実際のプロジェクトではどちらを選べばいいのでしょうか。ここでは「運用コスト」と「カスタマイズ性」という2つの軸で判断していくことになります。

まず、コストの面で比較してみましょう。一般的に、コンテナを24時間365日フル稼働させるような長期運用のシステムであれば、EC2起動タイプの方が安く済むことが多いです。特に、1年以上使うことが決まっているなら「リザーブドインスタンス(予約インスタンス)」を購入することで最大72%程度の割