Amazon EC2 Container Service(ECS)のデータモデルについて整理した

2017.06.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Amazon EC2 Container Service(以降ECS)はAmazon EC2上でDockerコンテナを稼働・管理するためのサービスです。私は最近ECSをよく触っており社内外の啓蒙活動も行っているのですが、「TaskとServiceってどう違うの?」「ECSのデータモデルがよくわからない」といったフィードバックを何度かもらいました。今日はECS学習のとっかかりとして、ECSで使われる概念について整理してみました。

概念

Task

前述の通り、ECSはDockerコンテナを起動、管理するためのサービスです。Dockerのベストプラクティスとして、基本的には1コンテナ1サービスであることが公式に推奨されています。

It is generally recommended that you separate areas of concern by using one service per container.

例えば、WEB + APサーバの構成があったとします。WebサーバとしてNginx, APサーバとしてSpring bootを採用した場合、サービスが2つ存在することになるため、それぞれを分離したコンテナとして起動すべきです。そしてそれぞれのコンテナは協調して動作することになるため、どちらかが欠けていても動く、というものではなく、一つのかたまりとして稼働するものです。そういった1つ以上の、協調して動作するコンテナ群をECSではTaskと呼びます。

Task Definition

Task Definitionは、名前の通りTaskの定義を示すもので、どのDocker ImageをどういったCPU/メモリ/環境変数等の設定で機動するかを定義します。Task Definitionはかなり複雑なデータモデルなのでここで詳細に解説することは避けますが、ECS公式ドキュメントに記載されたJSONを見ていただくと、雰囲気は伝わってくるのではないかと思います。

前述の通り、1つのTaskでは1つ以上のコンテナを起動する事が可能です。ですのでTask Definitionにも複数のコンテナを記述することができます。

EC2はよく触る、ということであれば「ServiceはAutoScalingのLaunchConfigurationのようなもの」だと考えるとイメージしやすいと思います。

Service

前述したTaskは、Task Definitionを元に実際に起動されたコンテナ群一式を指しています。このコンテナ群を起動する数を調整したり、ELB/ALBとの連携を行ってくれるのがServiceという概念です。Serviceは作成時に起動するタスクの数や紐付けるロードバランサの指定を行います。Service内で起動するべきTaskの数をDesired Countという名前で管理しています。ですので、例えばTaskが何らかの理由で異常終了してしまった場合はServiceが新たにTaskを起動して、Taskの数をDesiredCountに保ってくれます。

AutoScalingの例えでいうと、ServiceはAutoScalingGroupに該当するものになります。

Cluster

これまで述べてきた概念は全てコンテナに関するものでした。当然ですがコンテナを起動するにはコンテナを動作させるためのOSが必要です。AWSにおけるOSとはEC2のことですね。ClusterというのはECSのTaskを稼働させるための1つ以上のEC2のかたまりを指します。ClusterというとなんとなくAutoScalingのEC2を想像しますが、別にAutoScalingではない複数のEC2インスタンスでも、なんなら単独のEC2インスタンスでもClusterとしては成立します。

EC2をClusterに参加させるためには、ecs-agentがEC2上で起動されている必要があります。ecs-agentはDocker containerとしてEC2上で起動され、EC2の様々な情報をECS側に送るはたらきをしています。ECS側ではecs-agentから送信されてくる情報を基に、TaskをCluster上のどのEC2 Instanceで起動するかを決定しています。

AWSはECS-Optimized AMIというAMIを提供しています。これはAmazon Linux上にDockerやecs-agentといったECS Cluster用のEC2として稼働するための最適な、かつ最小限の設定があらかじめ実施されているベースAMIです。このAMIを利用するのが一番利用までの障壁は低いですが、用途に応じてUbuntuなどのAmazon Linux以外のディストリビューションやContainer Linuxなどの軽量OS上にecs-agentをインストールして、Cluster Instanceとして稼働させることも可能です。

Amazon EC2 Container Repository(ECR)

ECRはECSとは直接の関係はありませんが、併せて利用される機会が多いサービスなので一緒に紹介します。

ビルドされたDocker Imageは、Docker Registryというサービスを経由して配布することが可能です。OSや各種プログラミング言語のパッケージリポジトリのようなものですね。Docker社の提供しているDocker Hubのようなパブリックレジストリもあれば、提供されているソースコードDocker Imageを利用して自前でプライベートレジストリを構築することも可能です。

Amazon ECRは、AWSが提供するプライベートレジストリです。IAMアクセスキーを利用してDocker Imageを登録することが可能で、適切な権限を与えられたアクセスキーからのみイメージをpullすることが可能です。

Dockerを使いたいが様々な理由からDocker Hubにイメージを公開できない場合は、プライベートレジストリを利用することになります。自前で構築することも可能ですが、マネージドサービスであるECRをECSと一緒に使うとレジストリの運用が不要になるので非常に楽になります。

図にしてみた

図でそれぞれの概念の関連をまとめるとこのようになります。概念図なので詳細をかなり省略した図なのはご容赦ください。

Untitled

まとめ

  • Clusterは1つ以上のecs-agentが動いているEC2 Instance
  • Serviceは複数個のTaskを起動させ、TaskはTask Definitionに基いてDockerコンテナをEC2上に起動する
  • ServiceおよびTaskは、どのCluster上でコンテナを起動するかを選択することが出来る。Cluster上のどのEC2インスタンスで起動するかを制御することはできない *1

少々複雑ですが、触ってみると「なるほど、そういうことか」となると思っています。興味を持った方はぜひECSを触ってみましょう!

脚注

  1. Task Placementという仕組みを利用して、どういうstrategyでEC2インスタンスにコンテナを配置していくか、を制御することは可能です。