今日届いたAmazon EC2 Container Service (ECS)を使ってみた

こんにちは、sparkgeneです。

re:Inventで発表されたAmazon EC2 Container Serviceプレビューが通ったので、早速どんな感じなのかを試してみました。

事前準備

事前準備として、こちらのSetting Up with Amazon ECSを参考にしながらRole、鍵、セキュリティーグループを作成します。

CLIの初期設定

ECSはまだus-east-1リージョンでしか提供されていませんが、CLIでの操作はMacやLinuxであれば実行可能なので、今回はTokyoリージョンのVPCに新しくインスタンスを起動して、ECSのプレビュー用のCLIをインストールしました。

ECSはまだプレビュー版なのでregionはus-east-1で設定します

$ /home/ec2-user/.local/lib/aws/bin/aws configure
AWS Access Key ID [None]:<ECSの操作ができる権限を持ったものを指定>
AWS Secret Access Key [None]:<ECSの操作ができる権限を持ったものを指定>
Default region name [None]: us-east-1
Default output format [None]: json

準備が出来たので次はGetting Started with Amazon ECSを見ながら実際にコマンドを実行していきます。

クラスタの作成

$ /home/ec2-user/.local/lib/aws/bin/aws ecs create-cluster --cluster-name MyFirstCluster
{
    "cluster": {
        "clusterName": "MyFirstCluster",
        "status": "ACTIVE",
        "clusterArn": "arn:aws:ecs:us-east-1:1234567890:cluster/MyFirstCluster"
    }
}

コンテナ用のインスタンスを起動

ECSでは専用のAMIを使うので、「ami-34ddbe5c」と入力してAMIを検索します。

スクリーンショット-2014-12-18-23.21.07

事前準備で作成したRoleを指定し、Public IPが付与されるようにします。

スクリーンショット-2014-12-18-23.27.37

更に下の方へスクロールすると、user-dataが指定できるので、先ほど作成したクラスタ名を指定します。

スクリーンショット-2014-12-18-23.29.06

セキュリティーグループ、鍵を設定をして、インスタンスを起動します。

インスタンスが起動したら、以下のコマンドでクラスタに存在するか確認できます。

$ aws ecs list-container-instances --cluster MyFirstCluster
{
  "containerInstanceArns": [
    "arn:aws:ecs:us-east-1:304322479775:container-instance/1b48aeb1-4b02-4ce1-b78c-qqqqqqqqq"
  ]
}

以下のコマンドでインスタンスの詳細も確認できます。

$ aws ecs describe-container-instances --cluster MyFirstCluster --container-instances 1b48aeb1-4b02-4ce1-b78c-qqqqqqqqq
{
    "failures": [],
    "containerInstances": [
        {
            "status": "ACTIVE",
            "registeredResources": [
                {
                    "integerValue": 1024,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "CPU",
                    "doubleValue": 0.0
                },
                {
                    "integerValue": 996,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "MEMORY",
                    "doubleValue": 0.0
                },
                {
                    "name": "PORTS",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [
                        "2376",
                        "22",
                        "51678",
                        "2375"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ],
            "ec2InstanceId": "i-b12f475d",
            "agentConnected": true,
            "containerInstanceArn": "arn:aws:ecs:us-east-1:304322479775:container-instance/1b48aeb1-4b02-4ce1-b78c-qqqqqqqqq",
            "remainingResources": [
                {
                    "integerValue": 1024,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "CPU",
                    "doubleValue": 0.0
                },
                {
                    "integerValue": 996,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "MEMORY",
                    "doubleValue": 0.0
                },
                {
                    "name": "PORTS",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [
                        "2376",
                        "22",
                        "51678",
                        "2375"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ]
        }
    ]
}

コンテナインスタンスにSSHしてみましょう。

$ ssh 54.999.999.32
Last login: Thu Dec 18 14:42:59 2014 from ec2-54-999-999-18.ap-northeast-1.compute.amazonaws.com
    __|  __|  __|
    _|  (   __   Amazon ECS-Optimized Amazon Linux AMI
  ____|___|____/
  Image created: Thu Dec 18 01:39:14 UTC 2014
  PREVIEW AMI

いつものEC2ではなく、「ECS」になっている!

プロセスを確認すると、、

$ ps auxfww
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMANDroot      2097  0.0  1.0 366920 10728 ?        Sl   14:34   0:00 /usr/bin/docker -d
root      2453  0.0  0.5 218068  5840 ?        Sl   14:34   0:00  _ docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 51678 -container-ip 172.17.0.2 -container-port 51678
root      2461  0.0  0.6  14780  6632 ?        Ssl  14:34   0:00  _ /agent
root      2406  0.0  0.1  11404  1452 ?        Ss   14:34   0:00 /bin/sh /etc/ecs/ecs-init start
root      2421  0.0  0.6 218068  6516 ?        Sl   14:34   0:00  _ docker run --name ecs-agent -v /var/run/docker.sock:/var/run/docker.sock -v /var/log/ecs:/log -p 127.0.0.1:51678:51678 --env-file /etc/ecs/ecs.config -e ECS_LOGFILE=/log/ecs-agent.log amazon/amazon-ecs-agent:latest
$ sudo docker ps
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                        NAMES
ede41b89be65        amazon/amazon-ecs-agent:latest   "/agent"            14 minutes ago      Up 14 minutes       127.0.0.1:51678->51678/tcp   ecs-agent

dockerのプロセスが動いてます。

確認ができたので、SSHを終了して元のインスタンスへ戻ります。

タスクの実行

タスク(Dockerのコンテナ)の登録はJSONファイルをコマンドに指定するか、コマンドに直接JSONを含めるかのどちらの方法でも可能です。

今回はサンプルをそのまま使い、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://$HOME/task.json
{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:us-east-1:1234567890: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
{
    "taskDefinitionArns": [
        "arn:aws:ecs:us-east-1:1234567890:task-definition/sleep360:1"
    ]
}

task-definitionはアカウントに対して登録されるようです。

タスクを実行

登録されているタスクを実行するには、以下のコマンドを使います。

$ aws ecs run-task --cluster MyFirstCluster --task-definition sleep360:1 --count 1
{
    "tasks": [
        {
            "taskArn": "arn:aws:ecs:us-east-1:1234567890:task/5e3a75f1-62fc-4135-818e-3ddce4cd4f8c",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "sleep"
                    }
                ]
            },
            "lastStatus": "PENDING",
            "containerInstanceArn": "arn:aws:ecs:us-east-1:1234567890:container-instance/1b48aeb1-4b02-4ce1-b78c-qqqqqqqqq",
            "desiredStatus": "RUNNING",
            "taskDefinitionArn": "arn:aws:ecs:us-east-1:1234567890:task-definition/sleep360:1",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:us-east-1:1234567890:container/b2492674-726a-4a4c-9b4a-ssssssssss",
                    "taskArn": "arn:aws:ecs:us-east-1:1234567890:task/5e3a75f1-62fc-4135-818e-3ddce4cd4f8c",
                    "lastStatus": "PENDING",
                    "name": "sleep"
                }
            ]
        }
    ]
}

実行されているタスクは以下のコマンドで確認できます。

$ aws ecs list-tasks --cluster MyFirstCluster
{
    "taskArns": [
        "arn:aws:ecs:us-east-1:1234567890:task/11e8d948-4fd6-4f39-a35d-wwwwwwwww"
    ]
}

実行されているタスクの詳細な情報は、以下のコマンドで確認します。

$ aws ecs describe-tasks --cluster MyFirstCluster --task 11e8d948-4fd6-4f39-a35d-a7f52a3c3ef9
{
    "failures": [],
    "tasks": [
        {
            "taskArn": "arn:aws:ecs:us-east-1:1234567890:task/11e8d948-4fd6-4f39-a35d-a7f52a3c3ef9",
            "overrides": {
                "containerOverrides": [
                    {
                        "name": "sleep"
                    }
                ]
            },
            "lastStatus": "RUNNING",
            "containerInstanceArn": "arn:aws:ecs:us-east-1:1234567890:container-instance/1b48aeb1-4b02-4ce1-b78c-qqqqqqqqq",
            "desiredStatus": "RUNNING",
            "taskDefinitionArn": "arn:aws:ecs:us-east-1:1234567890:task-definition/sleep360:1",
            "containers": [
                {
                    "containerArn": "arn:aws:ecs:us-east-1:1234567890:container/b62cd705-d2fd-4863-9b60-ssssssssss",
                    "taskArn": "arn:aws:ecs:us-east-1:1234567890:task/11e8d948-4fd6-4f39-a35d-a7f52a3c3ef9",
                    "lastStatus": "RUNNING",
                    "name": "sleep",
                    "networkBindings": []
                }
            ]
        }
    ]
}

タスクを実行している状態で、コンテナインスタンスでdockerの状態を確認してみます。

$ docker ps
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                        NAMES
ba3ff735a5f6        busybox:latest                   "sleep 360"         5 minutes ago       Up 5 minutes                                     ecs-sleep360-1-sleep-f88697e3d3f2a1b5ab01
ede41b89be65        amazon/amazon-ecs-agent:latest   "/agent"            44 minutes ago      Up 44 minutes       127.0.0.1:51678->51678/tcp   ecs-agent

先ほど実行したタスク(コンテナ)が実行されてました!

まとめ

コマンドラインでの操作でしたが、結構簡単に出来た印象です。

今回はAmazonのAMIを利用しましたが、CoreOSのAMIも用意されているようです。

AWSのブログに書かれているように、今後はプレビューの申し込みをすると24時間ぐらいで使えるようになるそうです。

AWSの多くのサービスは、最初の頃はマネージメントコンソールでは最低限の設定しか出来ないけど、日々マネージメントコンソールがアップデートされ続け、気づいたら画面からポチポチで設定ができるようになってきました。

ECSも現在はCLIのみの提供ですが、正式リリースではマネージメントコンソールから色々とできるようになるといいですね。

おまけ

AWSあるあるとして、立ちあげたインスタンスを落とし忘れて、翌月の請求が来た時に「しまった!!」と思うことがよくあるので、今回はちゃんとお掃除をしようと思った所、まだ実装されていないコマンドもあるようでした。

例えば、deregister-task-definitionはヘルプに出てるけど実際に実行するとDeregistering task definitions is currently unsupported.と言われてしまう。

$ aws ecs deregister-task-definition --task-definition arn:aws:ecs:us-east-1:1234567890
A client error (InvalidAction) occurred when calling the DeregisterTaskDefinition operation: Deregistering task definitions is currently unsupported.

コンテナインスタンスの削除は出来ました

$ aws ecs deregister-container-instance --cluster MyFirstCluster --container-instance 1b48aeb1-4b02-4ce1-b78c-qqqqqqqq
{
    "containerInstance": {
        "status": "INACTIVE",
        "registeredResources": [
            {
                "integerValue": 1024
〜〜
}
$ aws ecs list-container-instances --cluster MyFirstCluster{
    "containerInstanceArns": []
}

クラスタを削除するコマンドもまだ用意されていない模様。