ちょっと話題の記事

Amazon EC2 Container Service (ECS)を試してみた

2014.12.18

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

2104/12/20更新 : Dockerの動作に一部不具合があり、ECS-Optimized Amazon LinuxのAMIが更新されました。「3. ECS-Optimized Amazon Linuxの起動」のAMI IDを変更しました。

ども、大瀧です。
AWSのイベント、re:Invent 2014で発表されたDockerコンテナを扱うサービスEC2 Container Service(ECS)のプレビュー申請が通ったので、ドキュメントのチュートリアルを試した様子をレポートします。

1. IAMロールの作成

まずは、Dockerコンテナを実行するEC2インスタンス(ECSインスタンス)からECS APIにアクセスするためのIAMロールを作成します。IAMの管理画面から[Roles] - [Create New Role]で作成ウィザードを表示し、ロール名に「ecs-ec2-role」と入力、[Next Step]をクリックします。

ecs01

[Select Role Type]画面では、「Amazon EC2」にある[Select]ボタンをクリックします。

ecs02

[Set Permissions]画面では画面をスクロールし、[Custom Policy]を選択し[Select]ボタンをクリックします。

ecs03

[Policy Name]には適当なロール名(例: ecs-ec2-role)を入力、[Policy Document]に以下を貼り付けます。

ecs-ec2-role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ecs:*",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

ecs04

[Next Step]をクリックして確認画面に進み、[Create Role]をクリックしてロールが作成されます。

2. ECSクラスタの作成

続いてECSインスタンスをグループとしてまとめるECSクラスタを作成します。ECSクラスタ作成はここからダウンロードできるプレビュー版AWS CLIで行います。プレビュー版AWS CLIでは、aws ecsコマンドでECSを構成、管理することができます。ECSクラスタの作成は、aws ecs create-clusterコマンドを実行します。

$ aws ecs create-cluster --region us-east-1 --cluster-name MyCluster
CLUSTER	arn:aws:ecs:us-east-1:XXXXXXXXXXXX:cluster/MyCluster	MyCluster	ACTIVE
$ aws ecs list-clusters --region us-east-1 --output json
{
    "clusterArns": [
        "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:cluster/MyCluster"
    ]
}

ECSクラスタが作成できました!

3. ECS-Optimized Amazon Linuxの起動

ECSクラスタには、ECSエージェントを実行するEC2インスタンスが参加できます。ECSエージェントは現在、ECS-Optimized Amazon LinuxというDockerインストール済みのAMIを利用するほかに、Docker向けLinuxディストリビューションのCoreOSのAMIが利用できるようです。今回は簡単に試すことができるECS-Optimized Amazon Linuxを利用します。

ECSのプレビューは、現在バージニアリージョン(us-east-1)のみで利用できるため、EC2の管理画面からバージニアリージョンを選択します。

ecs07

EC2インスタンスの起動ウィザードを表示し[Community AMIs]をメニューから選択、ami-34ddbe5cで検索し表示されるAMIを選択します。

ecs08

インスタンスタイプの制限は特にないため、t2.microのまま[Next: Configure Instance Details]をクリックします。

詳細設定画面では[IAM Role]を、先ほど作成したIAMロール「ecs-ec2-role」に変更します。

ecs09

画面をスクロールし、[Advanced Details]を開いて以下のユーザーデータを入力します。

#!/bin/bash
echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.config

ECSの設定ファイルで、ECSクラスタ名をここで指定するようです。

ecs10

[Next: Add Storage]をクリックして、ウィザードを進めます。残りの項目は、SSHでログインできるようセキュリティグループを設定すればOKです。適当な設定でウィザードを完了し、インスタンスを起動します。

起動後、しばらく待ってからaws ecs list-container-instancesを実行すると、ECSクラスタのインスタンス一覧に、起動したインスタンスがリストされます。

$ aws ecs list-container-instances --cluster MyCluster --output json --region us-east-1
{
    "containerInstanceArns": [
        "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container-instance/3e7d23ad-a477-4fb3-9a5c-09f8ce7ba76d"
    ]
}
$

また、ECSインスタンスにSSHで接続してみます。motdの内容もアレンジされていますw

$ ssh ec2-user@54.85.XX.XX
Last login: Thu Dec 18 07:50:32 2014 from XX

    __|  __|  __|
    _|  (   \__ \  Amazon ECS-Optimized Amazon Linux AMI
  ____|\___|____/


  Image created: Wed Dec 17 00:19:14 UTC 2014
  PREVIEW AMI

[ec2-user@ip-172-31-28-157 ~]$

ECSインスタンスでは、ECSエージェントもDockerコンテナとして実行されます。

[ec2-user@ip-172-31-28-157 ~]$ sudo docker ps
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                        NAMES
41172dbd2c52        amazon/amazon-ecs-agent:latest   "/agent"            5 minutes ago       Up 5 minutes        127.0.0.1:51678->51678/tcp   ecs-agent
[ec2-user@ip-172-31-28-157 ~]$

エージェントもコンテナで提供される形態は珍しいのではないでしょうか。これでインスタンスの準備はOKです。

4. タスクの登録と実行

ECSでは、実行するDockerコンテナをタスクというグループ単位で管理します *1。タスクは、GKE(Google Container Engine)と同様にテキストデータ(JSON形式)であらかじめ定義し、aws ecs register-task-definition で登録します。タスクの定義ファイルの書式はドキュメントで確認できます。今回はシンプルに、Dockerオフィシャルのbusyboxイメージでsleep 360を実行するコンテナを定義しています。

sleep360.json

[
  {
    "environment": [],
    "name": "sleep",
    "image": "busybox",
    "cpu": 10,
    "portMappings": [],
    "entryPoint": [
      "/bin/sh"
    ],
    "memory": 10,
    "command": [
      "sleep",
      "360"
    ],
    "essential": true
  }
]
$ aws ecs register-task-definition --family sleep360 --container-definitions file://sleep360.json --region us-east-1 --output json
{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1",
        "containerDefinitions": [
            {
                "environment": [],
                "name": "sleep",
                "image": "busybox",
                "cpu": 10,
                "portMappings": [],
                "entryPoint": [
                    "/bin/sh"
                ],
                "memory": 10,
                "command": [
                    "sleep",
                    "360"
                ],
                "essential": true
            }
        ],
        "family": "sleep360",
        "revision": 1
    }
}
$ aws ecs list-task-definitions --region us-east-1
TASKDEFINITIONARNS	arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1
$

タスクが登録されました!続いてタスクを実行するaws ecs run-taskコマンドを実行します。

$ aws ecs run-task --cluster MyCluster --task-definition sleep360:1 --count 1 --region us-east-1 --output json
{
    "tasks": [
        {
            "taskArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task/69e6299c-b85b-43ad-a2d9-0e84944b162a",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "sleep"
                    }
                ]
            },
            "lastStatus": "PENDING",
            "containerInstanceArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container-instance/3e7d23ad-a477-4fb3-9a5c-09f8ce7ba76d",
            "desiredStatus": "RUNNING",
            "taskDefinitionArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container/2bcbefb1-d1ca-4d00-a092-f236ad443a8f",
                    "taskArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task/69e6299c-b85b-43ad-a2d9-0e84944b162a",
                    "lastStatus": "PENDING",
                    "name": "sleep"
                }
            ]
        }
    ]
}
$

タスクが実行されました!コマンドのオプションではECSクラスタを指定しているので、複数のECSインスタンスがある場合は、タスクが自動配置されると考えられます。そのあたりのルール設定などは今後深掘りしていきたいですね。

ECSインスタンスでdocker psを実行すると、確かにタスクに対応するDockerコンテナが実行されていることがわかります。

$ sudo docker ps
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                        NAMES
bf4c172f3416        busybox:latest                   "sleep 360"         39 seconds ago      Up 38 seconds                                    ecs-sleep360-1-sleep-ae8fcfb28383cc9a2700
41172dbd2c52        amazon/amazon-ecs-agent:latest   "/agent"            21 minutes ago      Up 21 minutes       127.0.0.1:51678->51678/tcp   ecs-agent
$

まとめ

チュートリアルの範囲でしたが、ECSの構築とDockerコンテナ実行までの簡単な流れは見ていただけたと思います。

Kubernetesとはまた異なる実装のようですので、他のコンテナ管理サービスにあるような可用性やスケジュールに関する機能がECSでどうなっているのか、気になるところですね。引き続きECSをウォッチしていきたいと思います。

脚注

  1. KubernetesのPodsとReplication Controllerを合わせたような概念のようです