「初老丸の独り Advent calendar 2015」の二十三日目の記事です。
追記
コンテナインスタンスに付ける IAM role のポリシーを Amazon Managed Policy に変更した。
助言を頂いた @riywo さん、有難う御座いました!
tl;dr
では、触ってみただけだったので、少しうんちくを参考資料などから拝借する。
うんちくとか
なんぼ?
Amazon ECR って利用するのになんぼくらいするの?(現在はヴァージニア料金)
- ストレージ使用料 0.10 USD/GB/月
- Amazon ECR からのデータ転送量が発生
お楽しみの無料枠は...
- 500MB/月
- 翌月繰り越しは出来ないとの(携帯電話みたい)
ECR の特徴
こちらからの抜粋。
ECS との連携
- ECS で稼働しているコンテナイメージを管理することが出来る
- タスク定義で ECR を指定してイメージを取得することが出来る
Docker 互換
- Docker Registry HTTP API V2 がサポートされている
- Docker コマンド(
push
/pull
/list
/tag
等)が利用可能
高可用性、耐久性
- コンテナイメージは S3 に保存される
共有
アクセスコントロール
- IAM によってコンテナイメージへのアクセス制限を設けることが出来る
暗号化
モニタリング
- CloudWatch を利用してモニタリングされる
- コンテナイメージサイズ、ストレージ、データ転送などのリソース消費状況を確認することが出来る
制限事項
こちらを抜粋。
以下は申請により変更が可能(と思われる)。
Resource | Default Limit |
---|---|
1 アカウントあたりの最大リポジトリ数 | 1,000 |
1 リポジトリあたりの最大イメージ数 | 500 |
以下は変更不可。
Resource | Default Limit |
---|---|
1 イメージあたりの最大 layer 数 | 127 (this is the current Docker limit) |
最大 layer part サイズ | 10 MiB |
最小 layer part サイズ | 5 MiB (except the final layer part in an upload) |
最大 layer parts | 1,000 MiB |
もう一時間くらい
awscli と docker コマンドだけで操作してみる
- リポジトリを作成
$ aws --region us-east-1 ecr create-repository --repository-name oreno-docker-repo { "repository": { "registryId": "xxxxxxxxxxxxx", "repositoryName": "oreno-docker-repo", "repositoryArn": "arn:aws:ecr:us-east-1:xxxxxxxxxxxxx:repository/oreno-docker-repo" } }
- リポジトリを確認
$ aws --region us-east-1 ecr describe-repositories { "repositories": [ { "registryId": "xxxxxxxxxxxxx0", "repositoryName": "oreno-docker-repo", "repositoryArn": "arn:aws:ecr:us-east-1:xxxxxxxxxxxxx:repository/oreno-docker-repo" }, { "registryId": "xxxxxxxxxxxxx", "repositoryName": "oreno-registory", "repositoryArn": "arn:aws:ecr:us-east-1:xxxxxxxxxxxxx:repository/oreno-registory" } ] }
- リポジトリに登録されているイメージを確認
$ aws --region us-east-1 ecr list-images --repository-name oreno-registory { "imageIds": [ { "imageTag": "latest", "imageDigest": "sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } ] }
- ECR にログインする為の情報を取得(
docker login
する為の情報を取得)
$ aws --region us-east-1 ecr get-login
以下のようにログイン情報が出力される。
docker login -u AWS -p xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -e none https://xxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com
docker login
を利用して ECR にログインする
$ docker login -u AWS -p xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -e none https://xxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com
以下のように出力される。
WARNING: login credentials saved in ${HOME}/.docker/config.json Login Succeeded
尚、${HOME}/.docker/config.json の中身は以下の通り。
$ cat /home/vagrant/.docker/config.json { "auths": { "https://xxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com": { "auth": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "email": "none" } } }
docker build
でオリジナルコンテナをビルド
$ docker build -t inokappa/oreno-jenkins .
docker tag
でイメージを ECR リポジトリに登録する
$ docker tag inokappa/oreno-jenkins xxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo
- イメージを ECR リポジトリに push する
$ docker push xxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo The push refers to a repository [xxxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo] (len: 1) 0d3bf9ffe6f6: Pushed 4bb741cb567f: Pushing 1.024 kB (snip) 3375effa7f2a: Pushed latest: digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx size: 24325
- イメージを確認
$ aws --region us-east-1 ecr list-images --repository-name oreno-docker-repo { "imageIds": [ { "imageTag": "latest", "imageDigest": "sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } ] }
docker run
してみる
# # docker run # $ docker run --name jenkins -d -p 8080 xxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo Unable to find image 'xxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo:latest' locally latest: Pulling from oreno-docker-repo Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Status: Downloaded newer image for xxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo:latest xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # # docker ps # $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aa3ef49191c9 xxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo "/usr/bin/java -jar /" 46 seconds ago Up 45 seconds 0.0.0.0:32772->8080/tcp jenkins # # Jenkins コンテナを確認 # $ curl -s localhost:32772/api/json | jq . { "views": [ { "url": "http://localhost:32772/", "name": "All" } ], "useSecurity": false, "useCrumbs": false, "unlabeledLoad": {}, "slaveAgentPort": 0, "quietingDown": false, "primaryView": { "url": "http://localhost:32772/", "name": "All" }, "assignedLabels": [ {} ], "mode": "NORMAL", "nodeDescription": "the master Jenkins node", "nodeName": "", "numExecutors": 2, "description": null, "jobs": [], "overallLoad": {} }
ECS との連携を試してみる
やっと本番
以下のように ECS と ECR の連携をしてみる。
教材はいつものように。
ドキュメントによると ECR との連携については以下の条件を満たす必要がありそう。
但し、今回は Docker 1.9 をインストールした Ubuntu 14.04 で試すことにした。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS" $ sudo docker version sudo: unable to resolve host ip-10-0-0-93 Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.2 Git commit: a34a1d5 Built: Fri Nov 20 13:12:04 UTC 2015 OS/Arch: linux/amd64 Server: Version: 1.9.1 API version: 1.21 Go version: go1.4.2 Git commit: a34a1d5 Built: Fri Nov 20 13:12:04 UTC 2015 OS/Arch: linux/amd64 $
ECS コンテナインスタンスに付与する IAM ポリシー
以下をコンテナインスタンスに付与する IAM role に追加する。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:GetDownloadUrlForLayer", "ecr:GetAuthorizationToken" ], "Resource": "*" } ] }
terraform のテンプレートは以下のように
terraform のテンプレートは以下のように修正する。
# # Create ECS cluster # resource "aws_ecs_cluster" "oreno-cluster" { name = "oreno-cluster" } # # Define task # resource "aws_ecs_task_definition" "sample01" { family = "sample01" container_definitions = <<EOS [ { "environment": [], "name": "oreno-jenkins", "image": "xxxxxxxxxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo", "cpu": 0, "memory": 256, "portMappings": [ { "containerPort": 8080, "hostPort": 8080 } ], "command": [ ], "essential": true } ] EOS } # # Define Service(as container start) # resource "aws_ecs_service" "sample01" { name = "sample01" cluster = "${aws_ecs_cluster.oreno-cluster.id}" task_definition = "${aws_ecs_task_definition.sample01.arn}" desired_count = 1 }
コンテナイメージを指定する際に ECR のリポジトリを指定する。
apply
apply すると以下のように。
$ make tf-apply (snip) Outputs: CloudWatch Logs Log Group Name = docker-logging EC2 IP address = xxx.xxx.xxx.xxx EC2 Instance ID = i-xxxxxxxx ECS Cluster Name = oreno-cluster
terraform apply
で適用する。
確認
マネジメントコンソールの Task Definitions にて確認。
そして...暫くすると Task に登録された Jenkins コンテナが起動しているはずなので確認する。
$ curl -s xx.xx.xxx.xx:8080/api/json | jq . { "views": [ { "url": "http://xx.xx.xxx.xx:8080/", "name": "All" } ], "useSecurity": false, "useCrumbs": false, "unlabeledLoad": {}, "slaveAgentPort": 0, "quietingDown": false, "primaryView": { "url": "http://xx.xx.xxx.xx:8080/", "name": "All" }, "assignedLabels": [ {} ], "mode": "NORMAL", "nodeDescription": "the master Jenkins node", "nodeName": "", "numExecutors": 2, "description": null, "jobs": [], "overallLoad": {} }
念のため、ECS Container Agent のログを見てみる。
$ sudo docker logs ecs-agent (snip) 2015-12-22T16:56:40Z [INFO] Creating container module="TaskEngine" task="sample01:3 arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/4a5bf09f-cc8e-4908-b351-d2451201a051, Status: (NONE->RUNNING) Containers: [oreno-jenkins (PULLED->RUNNING),]" container="oreno-jenkins(xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo:latest) (PULLED->RUNNING)" 2015-12-22T16:56:40Z [INFO] Created container name mapping for task sample01:3 arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/4a5bf09f-cc8e-4908-b351-d2451201a051, Status: (NONE->RUNNING) Containers: [oreno-jenkins (PULLED->RUNNING),] - oreno-jenkins(xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/oreno-docker-repo:latest) (PULLED->RUNNING) -> ecs-sample01-3-oreno-jenkins-ead1bcfd81ba9fe91400
ECR から docker pull
してきているのがなんとなく判る。
以上
ECR と ECS の連携を試してみた。ポイントは IAM Policy を適切に付与すること。ここだけ気をつければ簡単に連携を試すことが出来ると思う。
以上。