ども、かっぱです。
tl;dr
以前から気になっていた ecs-cli から ECR のコンテナイメージをどうやって使うのか。実際にやってみたら難しくなかったけど念のためにメモっておきます。
memo
試した環境
- 構築した環境
- ecs-cli を叩く環境
i$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS" $ ecs-cli --version ecs-cli version 0.2.1 (e7b6965)
教材
github.com
拙作の pm25.test.inokara.com で提供されている JSON データを S3 から取得してクライアントに返すだけの API サーバーっぽいの。
ECR にコンテナイメージを push するまで
# # docker-compose build でコンテナイメージをビルドする # $ docker-compose build # # aws cli で ECR にログインする為のパスワードを取得 # $ aws --region us-east-1 ecr get-login # # docker login でログイン # $ docker login -u AWS -p xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -e none https://xxxxxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com # # aws cli でリポジトリを作成 # $ aws --region us-east-1 ecr create-repository --repository-name oreno-pm25-api # # ビルドしたイメージにタグを付与 # $ docker tag orenopm25api_web_1 xxxxxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-pm25-api # # タグを付与したイメージを ECR に push # $ docker push xxxxxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-pm25-api
以上。
docker-compose.yml
ECS 用に docker-compose.yml を作成する。
redis: image: redis cpu_shares: 100 mem_limit: 67108864 ports: - "6379" web: image: xxxxxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-pm25-api cpu_shares: 100 mem_limit: 268435456 volumes: - /tmp/nginx/:/var/log/nginx ports: - "80:80" - "4567:4567" links: - redis environment: - REDIS_HOST=redis
redis コンテナは Docker オフィシャルの Redis イメージを利用する。web コンテナは先ほど ECR に push したイメージを利用する。この YAML ファイルを ecs.yml という名前で保存しておく。(ファイル名は任意で OK 牧場)
ecs-cli でクラスタ作成、ECS インスタンスの起動
# # クラスタの初期設定 # $ ecs-cli configure --region ap-northeast-1 --cluster oreno-pm25-api # # 実行すると以下のようなファイルが生成される # $ cat ~/.ecs/config [ecs] cluster = oreno-pm25-api aws_profile = region = ap-northeast-1 aws_access_key_id = aws_secret_access_key = # # ECS インスタンスの起動 # $ ecs-cli up --keypair xxxxxxxxxxxxxxxxxxx --capability-iam --size 1 --vpc vpc-xxxxxxxx --instance-type t2.micro --subnets subnet-xxxxxxxx,subnet-zzzzzzzz --azs ap-northeast-1a,ap-northeast-1c (以下のように出力される) INFO[0000] Created cluster cluster=oreno-pm25-api INFO[0001] Waiting for your cluster resources to be created INFO[0002] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0062] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0122] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0183] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0243] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS INFO[0304] Cloudformation stack status stackStatus=CREATE_IN_PROGRESS
ecs-cli compose up
準備は整ったのでコンテナを起動する。
$ ecs-cli compose -f ecs.yml up (以下のように出力される) ERRO[0000] Error describing task definition error=ClientException: Unable to describe task definition. status code: 400, request id: 6c010388-dd17-11e5-bb49-531dd1d03f3f taskDefinitionName=ecscompose-oreno-pm25-api INFO[0000] Using ECS task definition TaskDefinition=ecscompose-oreno-pm25-api:1 INFO[0000] Starting container... container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/redis INFO[0000] Starting container... container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/web INFO[0000] Describe ECS container status container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/redis desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-oreno-pm25-api:1 INFO[0000] Describe ECS container status container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/web desiredStatus=RUNNING lastStatus=PENDING taskDefinition=ecscompose-oreno-pm25-api:1 snip... INFO[0097] Started container... container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/redis desiredStatus=RUNNING lastStatus=RUNNING taskDefinition=ecscompose-oreno-pm25-api:1 INFO[0097] Started container... container=xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/web desiredStatus=RUNNING lastStatus=RUNNING taskDefinition=ecscompose-oreno-pm25-api:1
それぞれのコンテナが起動したようだ。
ecs-cli compose ps
コンテナの状態を確認してみる。
$ ecs-cli compose -f ecs.yml ps Name State Ports TaskDefinition xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/redis RUNNING xx.xxx.x.xxx:32768->6379/tcp ecscompose-oreno-pm25-api:1 xxxxxxxx-0a0a-4871-a644-zzzzzzzzzz/web RUNNING xx.xxx.x.xxx:4567->4567/tcp, xx.xxx.x.xxx:80->80/tcp ecscompose-oreno-pm25-api:1
おけ。どうやらコンテナは正常に起動している。
アプリケーションの確認
デプロイ済みのなんちゃってアプリケーションの動作確認。
$ curl -s 'xx.xxx.x.xxx/json?date=20160224&station_code=40202010' | jq . { "time_series": { "24": 3, "23": 3, "22": 1, "21": 7, "20": 9, "19": 15, "18": 13, "17": 17, "08": 13, "07": 21, "06": 20, "05": 18, "04": 15, "03": 17, "02": 21, "01": 20, "09": 11, "10": 14, "11": 17, "12": 21, "13": 24, "14": 23, "15": 22, "16": 19 }, "check_date": "20160224", "check_station_code": "40202010", "check_station": "国設大牟田" }
一応、それっぽい JSON のレスポンスが得られた。
後片付け
$ ecs-cli down --force INFO[0001] Waiting for your cluster resources to be deleted INFO[0001] Cloudformation stack status stackStatus=DELETE_IN_PROGRESS INFO[0062] Cloudformation stack status stackStatus=DELETE_IN_PROGRESS INFO[0122] Deleted cluster cluster=oreno-pm25-api
ecs-cli down --force
で一発。
以上
ecs-cli から ECR が使えたのはなんでだろう
ECS インスタンスの起動時に --capability-iam
を付与することで以下の IAM ポリシーがコンテナインスタンスに付与されている為に利用できるのかしら。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateCluster", "ecs:DeregisterContainerInstance", "ecs:DiscoverPollEndpoint", "ecs:Poll", "ecs:RegisterContainerInstance", "ecs:StartTelemetrySession", "ecs:Submit*", "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage" ], "Resource": "*" } ] }
なるほど。
ちなみに、上記のポリシーは Managed Policy の AmazonEC2ContainerServiceforEC2Roleで適用される。
思ったより簡単だったけど…
- ECR は東京リージョンにいつくるだんろう…
- pm25.test.inokara.com をちゃんと作り直したい