AWS ECSを構成する3つの概念(Cluster, Service, Task)
AWS上でDockerコンテナを動かそうとすると、いくつか選択肢がある(2018/6/24現在
ECS
on EC2
on Fargate(バージニア、オレゴン、オハイオ、アイルランド)
EKS(バージニア、オレゴン)
EC2
この中で一番ラクそうに見えるのがECS
しかし実際は全然楽でもない。EKS、EC2はもっと難しい。
なにが難しいのだろうか?
Dockerのおかげでアプリケーションのポータビリティが上がったはずなのに、なぜ即デプロイできないのか?
というわけでECSへのデプロイがなぜ難しいのか解説していこうと思う
ECS的概念
ECSは、コンテナのデプロイサービスであるがその中でコンテナという単語はめったに出てこない
ECSには、3つの概念が存在する
Cluster
Service
Task/Task Definition
それぞれ説明していく
Task/Task Definition
Task(タスク)
ECSにおけるコンテナに相当する
後述のClusterを構成するノード(EC2インスタンス)上で起動する
これを「タスクを配置」と表現する
Task Definition(タスク定義)
Dockerコンテナの起動設定に相当する
docker-compose.ymlのようなもの
起動するコンテナが1つでも2つでも設定ファイルは書く
Service
サービスは、ALBとAutoScaling Groupに紐付けられたタスク群である
一般的なWebサービスであれば、HTTPのポートが空いていて、デーモンとして起動しているタスクの集合のこと
注意が必要なのは、タスクと違ってサービスはあくまで仮想的な概念でしかないということ
ここがすこし変なところで、ECSがコンテナをTaskと名付けたのはWebサービスよりもむしろCronのようなワンオフの(それこと)タスクを実行する環境として用意された感があるところだ
なので、タスクは「起動して何かをして終了する」ということを指している気がする
しかし、Webサービスは起動したあと終了することはないので、混乱してくる
1行目に書いたが、サービスはタスクの上位概念ではない
タスクはタスク単体で配置することができる
サービスを用いずにタスクだけでWebサービスを動かすこともできる
ECSノードのポートを自分で開けて、自分でALBのターゲットグループに登録すればいい
サービスはあくまでタスクをデーモンとして管理しやすくしようとした仮想的な概念に過ぎない
しかし、それにしては機能が渋いのでは?と思ったりもする(後述)
Cluster
クラスターは、タスクを配置するEC2インスタンス群である
タスクは通常ECSエージェントが起動したEC2インスタンスのどれかに配置される
これはplacement strategyというようなもので管理される
クラスターはECSの中で最も仮想的なもので、実体はないに等しい
異なるVPCやサブネットでクラスターの中身を構成することができる
VPCがなくても作成できる
通常はECSエージェントが起動したただのEC2インスタンスがノードになる
EC2インスタンスの起動データ(userdata)にECS_CLUSTER=という環境変数を書き込むと、その名前のクラスターに所属する
つまり、ECSの管理外から自由にクラスターのノードを管理できる
Fargateの場合、クラスターはほとんど何でもない
Fargateのタスクは、どこのどんなEC2インスタンスで起動しているのか隠蔽されている
正確にはEC2インスタンスで動いているとも明言されていない
でもまぁ多分そうなんでしょという感じ
Fargate Serviceの場合、VPCとサブネットを設定した場合は一応その中のAvailability Zoneの中でプライベートIPが割り当てられた場所でタスクが配置されているようだ
Private IPはわかるが、当然SSHなどはできない
ECSコンソールからは見られないが、EC2のALBのターゲットグループのところで見られる
大体デフォルトだと常に各AZに13個のFargateノードが存在しているようだ
単にECSエージェントが起動しているEC2インスタンス所属する場所を表している
一応クラスタ全体を通したリソースのメトリクスも見られるので、そういう管理用途の概念にすぎない
Kubernetesみたいなガチなクラスタよりはゆるふわである