ECS 再入門 vol.1 ECS とは

Wed, 11 Dec 2019


この記事は Fusic その 2 Advent Calendar 2019 11 日目の記事です。

はじめに

今日から5日間、5回に分けて自分が案件で得たECSの知識について、整理がてら記事に起こしたいと思います。
第1回は、ECSの基本的な概念について説明したいと思います。

ECS とは

まずは、公式ドキュメントから説明文を引用します。

Amazon Elastic Container Service (Amazon ECS) は、クラスターで Docker コンテナを簡単に実行、停止、管理できる非常にスケーラブルで高速なコンテナ管理サービスです。
(中略)
Amazon ECS があれば、独自のクラスター管理システムや設定管理システムを運用する必要も、管理インフラストラクチャのスケーリングを心配する必要もなくなります。

要するに、Dokcer 使うために必要な基盤をいい感じに用意したよ! ってことですね。

前職でオンプレミスでクラスターを組んでいた身としては、こんなにありがたいことはありません。クラウドさまさまです。

ECS を構成する要素

ECS は主に下記の要素で構成されています。

  • クラスター
  • コンテナインスタンス
  • サービス
  • タスク定義
  • タスク

1つずつ簡単な説明をしていきます

クラスター

ECSクラスターの説明は、公式ドキュメントには、下記のように書かれています。

Amazon ECS クラスターは、タスクまたはサービスの論理グループです。 EC2 を使用してタスクまたはサービスを実行している場合、クラスターはコンテナインスタンスのグループ化でもあります。

ECSクラスターは、つまるところ リソースを管理する単位 です。
1つのリソースとして管理したいコンテナの集合を、クラスターとして設定することが重要です。

例えば、WEBとAPIのコンテナを同時に動かす といった状況を考えてみます。
この場合、下記2つのスケールパターンがあるかと思います(2の逆のパターンもありますが、条件は同じなので割愛しています)。

  1. WEBの負荷 ≒ APIの負荷 なので、コンテナはどちらも同じようにスケールさせる
  2. WEBの負荷 > APIの負荷 なので、コンテナそれぞれにスケールルールが必要

1. の場合、WebとDBのクラスターは同じで良いと思います。同じリソースの集合体に所属させ、負荷が上がったらリソースを増強することで、負荷上昇に対応することができます。

2. の場合、同じクラスタに所属させると、WEBの負荷が上がって、インスタンスを増やした際、WEB用のコンテナをスケールさせているので、本来API用のコンテナが起動するためのリソース分が浮いてしまう可能性があります。
そのため、2. の場合は、WEB用のクラスターと、API用のクラスターを作成して、それぞれのリソースを別々に管理した方が、適切なリソース管理ができると思います。

この辺りは、後述する Fargate起動タイプ を利用すると解決できるかもしれませんが、2019年12月11日現在、EC2起動タイプ に比べてFargate起動タイプにはいくつか制限が存在しているので、求められている要件によっては使用できない可能性もあります。

コンテナインスタンス

コンテナインスタンスは、書いて字の通り、コンテナが実際に動作するインスタンス です。 EC2起動タイプFargate起動タイプ の2つの種類があり、それぞれ特徴を持っています。

全てではないですが、表にまとめてみました。

項目 EC2 起動タイプ Fargate 起動タイプ
料金 動作させるEC2の料金(RIも買える) CPU, メモリによって決まる。同等のスペックのEC2と同じ設定であれば、オンデマンド料金の 1.1 ~ 1.3倍 程度の割増料金になる。
インスタンスの管理 ECS最適化イメージが提供されているのでミドルウェアの管理は不要だが、定期的なAMIのアップデートは必要 OS含めてマネジメントなので、一切のインフラ管理が不要。
スペックの指定 動作させるインスタンスが選べるので、チップの種類やネットワーク帯域の種類が選べる 指定できるのは vCPU とメモリの数値のみ。CPUチップの種類は選べない。
ネットワーク bridge(ホスト経由での通信), host(ホストネットワークにぶら下がる)、awsvpc(各コンテナが独自のENIを持つ)、なし(外部通信なし)が選択可能 awsvpc、なしが選択可能
リソース管理 先述の通り、リソース割当の計算を適切に行わないと、無駄なリソースが生まれやすい。 適切なサイズで設定を行っていれば、インスタンス = コンテナなので、無駄なリソースは生まれない。
オートスケール インスタンスのスケール + コンテナのスケールなのでやや煩雑 コンテナのスケール時にインスタンスが勝手に起動するので、コンテナのスケールのみ設定すればOK。ただし、コンテナのキャッシュが効かないので、意外と起動に時間はかかる。コンテナイメージを小さくするのが肝。
共有ストレージ ホストのディレクトリをコンテナにマウント可能なので、永続データボリュームが使用可能。また、EC2に事前にマウントすることで、S3やEFSを共有ストレージとして使用可能。 非永続ストレージボリュームのみサポート(2019年12月11日現在)

オートスケールと共有ディレクトリに関しては、後々サンプルも交えてもう少し詳細に解説したいと思います。

サービス

ECS サービスは、

  • タスクの実行/停止の管理
  • タスクの実行数の管理
  • タスクのオートスケールの管理
  • タスクとロードバランサーとの紐付け

など、コンテナの実行に関わるあらゆる管理を司ります。 ECS におけるDockerデーモン だと思っておけば良いでしょう。

ECSを利用するにあたって、単体で完結するバッチ処理のような使い方をする場合を除いて、基本的には外部ネットワークとの通信を行うことになると思います。
そんな時は、サービスとロードバランサーを紐づけて、サービス内のコンテナに対してリクエストを振り分けられるようにします。
具体的には、対象のタスクをターゲットとしたターゲットグループを作成して、そのターゲットグループをロードバランサーとECSサービスそれぞれに紐付けます。

タスク定義

コンテナを動作させるための環境についての情報を記載した定義ファイルで、JSON形式で記載します。
コンテナを材料とすれば、タスク定義は コンテナを起動する際のレシピ とでも言うべきものです。

使用イメージ、vCPU数、メモリ、ログの出力先・出力方法、ボリューム、マウントポイントなどなど・・・
項目をあげればキリがないほど、かなり細かい設定が可能です。

タスク定義に関しては、公式ドキュメントを参考に構築されることをお勧めします。

タスク

実際に動作するコンテナの集合になります。
1タスク1コンテナではなく、1つタスクに対して、コンテナは複数定義可能です。
イメージとしては、タスク定義をdocker-compose.ymlとした時に、 docker-compose up で実行されるコンテナ群 になります。

ECS サービスはコンテナ単位ではなく、タスク単位で色々な管理を行うので、複数コンテナが存在しているタスクをオートスケールすると、その中に含まれている全コンテナが実行されます。
そのため、細かいリソースの調整が必要な場面では、極力1タスク1コンテナにしておくのが無難だと思います。

まとめ

ECS再入門1日目は、ECSを取り巻く環境について解説しました。
この記事を読んで、ECSをなんとなく理解できる方が増えることを祈っています。


← back