ようへいの日々精進XP

よかろうもん

Amazon ECS をちょっと試す

リリースされてからずっと触ってみたかった Amazon EC2 Container Service を触ってみたのでメモ。

参考

www.slideshare.net

docs.aws.amazon.com

ECS ってなんくさ?

コンテナ管理サービス

  • EC2 クラスタ上に Docker コンテナを起動、管理
  • Docker コンテナの管理を AWS をよしなにラッピングして簡素化

構成要素

構成要素に関してはこちらより抜粋。

構成要素 詳細
Cluster A logical grouping of container instances that you can place tasks on.
Container instance An Amazon EC2 instance that is running the Amazon ECS agent and has been registered into a cluster. For more information, see Amazon ECS Container Instances.
Task definition A description of an application that contains one or more container definitions. For more information, see Amazon ECS Task Definitions.
Scheduler The method used for placing tasks on container instances. For more information about the different scheduling options available in Amazon ECS, see Scheduling Amazon ECS Tasks.
Service An Amazon ECS service allows you to run and maintain a specified number of instances of a task definition simultaneously. For more information, see Services.
Task An instantiation of a task definition that is running on a container instance.
Container A Linux container that was created as part of a task.

コンテナインスタンス

  • VPC 内の EC2(東京リージョンだと ami-7806df78)
  • Docker
  • ECS Agent(Docker コンテナで動いてる、go で書かれている)

クラスタ

タスク

  • 関連するコンテナの集合
  • コンテナインスタンス上で稼働
  • タスク定義(タスクの定義で JSON Validation)

個人的に感じたメリットデメリット

  • ピュアな Docker がそのまま利用出来る(コンテナリポジトリに登録済みのコンテナをそのまま利用出来る)のが嬉しい
  • AWS の各種サービスと組み合わせて Docker コンテナを利用出来るのが嬉しい
  • クラスタ、タスク等の ECS 用語と概念を勉強する必要がある(とは言っても簡単でした)

超シンプルチュートリアル

構成

f:id:inokara:20150621180147p:plain

手順整理

  1. IAM role 作成
  2. ECS クラスタ作成
  3. コンテナインスタンスを作成
  4. タスクの定義(docker 的に言うと docker pull 相当かしら...)
  5. タスクの実行(docker 的に言うと docker run 相当かしら...)
  6. タスクの停止(docker 的に言うと docker stop 相当かしら...)
  7. コンテナインスタンスの登録解除と削除
  8. ECS クラスタの削除
  9. タスク定義の解除

ゴールとしてホスト名を出力するコマンド(hostname -s)を一秒毎に出力するコンテナを 2 つ起動することと、後片付けまでちゃんとやる。

IAM role を作成する

ecs の IAM role をコンテナインスタンスに付与する必要があるので IAM role を作成する。尚、IAM role が付与されていない場合には ECS Agent コンテナがインストールされないので忘れずに付与する。

aws iam create-role --role-name ecs_iam_role --assume-role-policy-document file://ecs-iam-role.json
aws iam create-instance-profile --instance-profile-name ecs_iam_role
aws iam add-role-to-instance-profile --instance-profile-name ecs_iam_role --role-name ecs_iam_role
aws iam put-role-policy --role-name ecs_iam_role --policy-name ecs-iam-role --policy-document file://ecs-iam-role-policy.json
  • ecs-iam-role.json は以下のような内容
{
  "Version":"2008-10-17",
  "Statement":[
    {
      "Sid":"",
      "Effect":"Allow",
      "Principal":{
        "Service":"ec2.amazonaws.com"
      },
      "Action":"sts:AssumeRole"
    }
  ]
}
  • ecs-iam-role-policy.json は以下のような内容
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "ecs:*",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

ECS クラスタの作成

aws ecs create-cluster --cluster kappa-test-cluster --output json --region ap-northeast-1

以下のように出力される。

{
    "cluster": {
        "status": "ACTIVE",
        "clusterName": "kappa-test-cluster",
        "registeredContainerInstancesCount": 0,
        "pendingTasksCount": 0,
        "runningTasksCount": 0,
        "clusterArn": "arn:aws:ecs:ap-northeast-1:1234567890123:cluster/kappa-test-cluster"
    }
}

describe-clusters にてクラスタの詳細を確認する。

aws ecs describe-clusters --cluster kappa-test-cluster

以下のように出力される。

{
    "clusters": [
        {
            "status": "ACTIVE",
            "clusterName": "kappa-test-cluster",
            "registeredContainerInstancesCount": 1,
            "pendingTasksCount": 0,
            "runningTasksCount": 2,
            "clusterArn": "arn:aws:ecs:ap-northeast-1:1234567890123:cluster/kappa-test-cluster"
        }
    ],
    "failures": []
}

コンテナインスタンスを作成する

aws ec2 run-instances --cli-input-json file://instance.json --user-data file://userdata.sh
  • instance,json は以下のような内容
{
    "ImageId": "ami-xxxxxxxx",
    "SecurityGroupIds": [
        "sg-xxxxxxxx"
    ],
    "KeyName": "key_name",
    "InstanceType": "t2.micro",
    "BlockDeviceMappings": [
        {
            "DeviceName": "/dev/xvda",
            "Ebs": {
                "VolumeSize": 30,
                "DeleteOnTermination": true,
                "VolumeType": "gp2"
            }
        }
    ],
    "Monitoring": {
        "Enabled": false
    },
    "SubnetId": "subnet-xxxxxxxx",
    "DisableApiTermination": true,
    "IamInstanceProfile": {
        "Arn": "arn:aws:iam::1234567890123:instance-profile/ecs_iam_role"
    },
    "EbsOptimized": false
}

インスタンスイメージは ECS に特化した Amazon ECS-Optimized Amazon Linux AMI を利用する。

  • userdata.sh は以下のような内容
#!/bin/bash

echo ECS_CLUSTER=kappa-test-cluster >> /etc/ecs/ecs.config

インスタンス作成実行後にインスタンス ID と IP アドレスを確認する。

aws ec2 describe-instances --filter "Name=instance-state-name,Values=running"  --query "Reservations[*].Instances[*].[InstanceId,PublicIpAddress]" --output table

以下のように出力される。

--------------------------------
|       DescribeInstances      |
+-------------+----------------+
|  i-xxxxxxxx |  xx.xx.xx.xxx  |
+-------------+----------------+

list-container-instances を実行してクラスタのコンテナインスタンスに登録されているかを確認する。

aws ecs list-container-instances --cluster kappa-test-cluster

以下のように出力される。

{
    "containerInstanceArns": [
        "arn:aws:ecs:ap-northeast-1:1234567890123:container-instance/2bb4fcde-0050-47a4-95bf-c3ffd265f0d8"
    ]
}

describe-container-instances を実行してコンテナインスタンスの詳細情報を取得する。

aws ecs describe-container-instances --cluster kappa-test-cluster --container-instances 2bb4fcde-0050-47a4-95bf-c3ffd265f0d8

以下のように出力される。

{
    "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": [
                        "22",
                        "2376",
                        "2375",
                        "51678"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                },
                {
                    "name": "PORTS_UDP",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ],
            "ec2InstanceId": "i-xxxxxxx",
            "agentConnected": true,
            "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:123456789123:container-instance/2bb4fcde-0050-47a4-95bf-c3ffd265f0d8",
            "pendingTasksCount": 0,
            "remainingResources": [
                {
                    "integerValue": 1004,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "CPU",
                    "doubleValue": 0.0
                },
                {
                    "integerValue": 976,
                    "longValue": 0,
                    "type": "INTEGER",
                    "name": "MEMORY",
                    "doubleValue": 0.0
                },
                {
                    "name": "PORTS",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [
                        "22",
                        "2376",
                        "2375",
                        "51678"
                    ],
                    "type": "STRINGSET",
                    "integerValue": 0
                },
                {
                    "name": "PORTS_UDP",
                    "longValue": 0,
                    "doubleValue": 0.0,
                    "stringSetValue": [],
                    "type": "STRINGSET",
                    "integerValue": 0
                }
            ],
            "runningTasksCount": 2
        }
    ]
}

タスクの定義

aws ecs register-task-definition --family kappa-test --container-definitions file://test.json --output json
  • test.json は以下のような内容
[
  {
    "environment": [],
    "name": "centos",
    "image": "centos:centos6",
    "cpu": 10,
    "portMappings": [],
    "memory": 10,
    "command": [
      "/bin/sh", "-c", "while true ; do sleep 1; hostname -s ; done"
    ],
    "essential": true
  }
]

以下のように出力される。

{
    "taskDefinition": {
        "volumes": [],
        "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:1234567890123:task-definition/kappa-test:2",
        "containerDefinitions": [
            {
                "environment": [],
                "name": "centos",
                "mountPoints": [],
                "image": "centos:centos6",
                "cpu": 10,
                "portMappings": [],
                "command": [
                    "/bin/sh",
                    "-c",
                    "while true ; do sleep 1; hostname -s ; done"
                ],
                "memory": 10,
                "essential": true,
                "volumesFrom": []
            }
        ],
        "family": "kappa-test",
        "revision": 2
    }
}

list-tasks で確認。

aws ecs list-task-definitions

以下のように出力される。

{                                                                             
    "taskDefinitionArns": [                                                   
        "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2"
    ]                                                                         
}                                                                             

タスクの実行

aws ecs run-task --cluster kappa-test-cluster --task-definition kappa-test:2 --count 2 --output json

以下のように出力される。

{                                                                                                                                      
    "failures": [],                                                                                                                    
    "tasks": [                                                                                                                         
        {                                                                                                                              
            "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/5f6f6f01-6269-474b-93ae-9959e30f60f4",                            
            "overrides": {                                                                                                             
                "containerOverrides": [                                                                                                
                    {                                                                                                                  
                        "name": "centos"                                                                                               
                    }                                                                                                                  
                ]                                                                                                                      
            },                                                                                                                         
            "lastStatus": "PENDING",                                                                                                   
            "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:123456789123:container-instance/2bb4fcde-0050-47a4-95bf-c3ffd265f0d8", 
            "clusterArn": "arn:aws:ecs:ap-northeast-1:123456789123:cluster/kappa-test-cluster",                                        
            "desiredStatus": "RUNNING",                                                                                                
            "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2",                               
            "containers": [                                                                                                            
                {                                                                                                                      
                    "containerArn": "arn:aws:ecs:ap-northeast-1:123456789123:container/e8345af3-8f8b-4ffd-af64-0b298c7aeed7",          
                    "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/5f6f6f01-6269-474b-93ae-9959e30f60f4",                    
                    "lastStatus": "PENDING",                                                                                           
                    "name": "centos"                                                                                                   
                }                                                                                                                      
            ]                                                                                                                          
        },                                                                                                                             
        {                                                                                                                              
            "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb",                            
            "overrides": {                                                                                                             
                "containerOverrides": [                                                                                                
                    {                                                                                                                  
                        "name": "centos"                                                                                               
                    }                                                                                                                  
                ]                                                                                                                      
            },                                                                                                                         
            "lastStatus": "PENDING",                                                                                                   
            "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:123456789123:container-instance/2bb4fcde-0050-47a4-95bf-c3ffd265f0d8", 
            "clusterArn": "arn:aws:ecs:ap-northeast-1:123456789123:cluster/kappa-test-cluster",                                        
            "desiredStatus": "RUNNING",                                                                                                
            "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2",                               
            "containers": [                                                                                                            
                {                                                                                                                      
                    "containerArn": "arn:aws:ecs:ap-northeast-1:123456789123:container/095df586-4891-4eee-8785-8f09ef075ec3",          
                    "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb",                    
                    "lastStatus": "PENDING",                                                                                           
                    "name": "centos"                                                                                                   
                }                                                                                                                      
            ]                                                                                                                          
        }                                                                                                                              
    ]                                                                                                                                  
}                      

実行されているタスクを確認する。

$ aws ecs list-tasks --cluster kappa-test-cluster

以下のように出力され、二つのタスクが実行されているのが判る。

{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:123456789123:task/5f6f6f01-6269-474b-93ae-9959e30f60f4",
        "arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb"
    ]
}

実際にコンテナが起動しているかをコンテナインスタンスにログインして確認する。

$ docker ps
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                        NAMES
0bb8b74cdfb3        centos:centos6                   "/bin/sh -c 'while t   2 minutes ago       Up 2 minutes                                     ecs-kappa-test-2-centos-b6c49d88b0ccb9b87100
ac66d44861cc        centos:centos6                   "/bin/sh -c 'while t   2 minutes ago       Up 2 minutes                                     ecs-kappa-test-2-centos-90e8a9c993a5f1d03f00
a5d60003d480        amazon/amazon-ecs-agent:latest   "/agent"               13 minutes ago      Up 13 minutes       127.0.0.1:51678->51678/tcp   ecs-agent

ちゃんとホスト名を出力し続けているかを確認する。

$ docker logs ecs-kappa-test-2-centos-90e8a9c993a5f1d03f00

ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc
ac66d44861cc

一応、ホスト名を出力しているように見えるけど、念の為に確認。

$ docker inspect ecs-kappa-test-2-centos-90e8a9c993a5f1d03f00 | python -c "exec(\"import json,sys\\nj=json.load(sys.stdin)\\nfor attr in j:\\n    h=attr.get('HostnamePath')\\n    if 'ac66
d44861cc' in h:   print 'ac66d44861cc included.'\")"

以下のように出力されるのでホスト名はちゃんと出力されているようだ。

ac66d44861cc included

おお。 ということで... ECS の超シンプルチュートリアルでした...と言いたいところだけど後片付け。

後片付け

  • タスクを止める
aws ecs stop-task --cluster kappa-test-cluster --task arn:aws:ecs:ap-northeast-1:123456789123:task/5f6f6f01-6269-474b-93ae-9959e30f60f4
aws ecs stop-task --cluster kappa-test-cluster --task arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb

それぞれ、以下のように出力される。

{
    "task": {
        "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb",
        "overrides": {
            "containerOverrides": [
                {
                    "name": "centos"
                }
            ]
        },
        "lastStatus": "RUNNING",
        "containerInstanceArn": "arn:aws:ecs:ap-northeast-1:123456789123:container-instance/2bb4fcde-0050-47a4-95bf-c3ffd265f0d8",
        "clusterArn": "arn:aws:ecs:ap-northeast-1:123456789123:cluster/kappa-test-cluster",
        "desiredStatus": "STOPPED",
        "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2",
        "containers": [
            {
                "containerArn": "arn:aws:ecs:ap-northeast-1:123456789123:container/095df586-4891-4eee-8785-8f09ef075ec3",
                "taskArn": "arn:aws:ecs:ap-northeast-1:123456789123:task/cb849596-7c4a-4d26-9a03-ccfbcb8cb0eb",
                "name": "centos",
                "networkBindings": [],
                "lastStatus": "RUNNING",
                "exitCode": 0
            }
        ]
    }
}
aws ecs deregister-container-instance --cluster kappa-test-cluster --container-instance 2bb4fcde-0050-47a4-95bf-c3ffd265f0d8
 aws ec2 terminate-instances --instance-ids i-xxxxxxx

以下のように出力される。

{
    "TerminatingInstances": [
        {
            "InstanceId": "i-xxxxxxx",
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
aws ecs delete-cluster --cluster kappa-test-cluster

以下のように出力される。

{
    "cluster": {
        "status": "INACTIVE",
        "clusterName": "kappa-test-cluster",
        "registeredContainerInstancesCount": 0,
        "pendingTasksCount": 0,
        "runningTasksCount": 0,
        "clusterArn": "arn:aws:ecs:ap-northeast-1:123456789123:cluster/kappa-test-cluster"
    }
}
  • ついでに登録したタスクも登録を解除しておく
aws ecs list-task-definitions

以下のようにタスクは登録されたまま。

{
    "taskDefinitionArns": [
        "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2"
    ]
}

以下のように登録を解除する。(削除する)

aws ecs deregister-task-definition --task-definition kappa-test:2

以下のように出力される。

{
    "taskDefinition": {
        "volumes": [],
        "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789123:task-definition/kappa-test:2",
        "containerDefinitions": [
            {
                "environment": [],
                "name": "centos",
                "mountPoints": [],
                "image": "centos:centos6",
                "cpu": 10,
                "portMappings": [],
                "command": [
                    "/bin/sh",
                    "-c",
                    "while true ; do sleep 1; hostname -s ; done"
                ],
                "memory": 10,
                "essential": true,
                "volumesFrom": []
            }
        ],
        "family": "kappa-test",
        "revision": 2
    }
}

も一回 list-task-definitions で確認。

aws ecs list-task-definitions

以下のようにタスクは登録されたまま。

{
    "taskDefinitionArns": []
}

お疲れ様でした。

ということで

Amazon ECS をちょっと使ってみた。当初は ECS 固有のクラスタ、タスクという考え方を理解出来ていなかったが、触ってみると意外に簡単で安心した。今回はコンテナインスタンスは 1 台のクラスタだったが、複数台構成でも試してみたい企んでいる。