リリースされてからずっと触ってみたかった Amazon EC2 Container Service を触ってみたのでメモ。
参考
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 用語と概念を勉強する必要がある(とは言っても簡単でした)
超シンプルチュートリアル
構成
手順整理
- IAM role 作成
- ECS クラスタ作成
- コンテナインスタンスを作成
- タスクの定義(docker 的に言うと docker pull 相当かしら…)
- タスクの実行(docker 的に言うと docker run 相当かしら…)
- タスクの停止(docker 的に言うと docker stop 相当かしら…)
- コンテナインスタンスの登録解除と削除
- ECS クラスタの削除
- タスク定義の解除
ゴールとしてホスト名を出力するコマンド(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 台のクラスタだったが、複数台構成でも試してみたい企んでいる。