share facebook facebook2 twitter menu hatena pocket slack

2016.02.29 MON

(ショロカレ 23 日目)Amazon ECR をもう一時間使ってみた(aws-cli による操作と ECS との連携を試す)

川原 洋平

WRITTEN BY川原 洋平

「初老丸の独り Advent calendar 2015」の二十三日目の記事です。

追記

コンテナインスタンスに付ける IAM role のポリシーを Amazon Managed Policy に変更した。

(ショロカレアップデート) Amazon Managed Policy をコンテナインスタンスに付与しておく方が色々と幸せになれたので追記します - ようへいの日々精進XP
この記事はショロカレで書いた記事の中で検証した内容を再構成してお送り致します。 tl;dr inokara.hateblo.jp の中で ECS のコンテナインスタンスに付ける IAM role ポリシーの JSON を以下のように terraform 内で直接記載していた。 # # Create IAM role Policy #...

inokara.hateblo.jp

助言を頂いた @riywo さん、有難う御座いました!

tl;dr

(ショロカレ 21 日目)ずっと待ってた Amazon ECR を一瞬、使ってみた - ようへいの日々精進XP
「初老丸の独り Advent calendar 2015」の二十一日目の記事です。 tl;dr ずっと待ってた Amazon EC2 Container Registory Service が来た!ので、ドキュメントを全く読まずに恐縮ですが触ってみた。(後ほど、いろいろと追記していくか別記事に書く) Amazon EC2 Con...

inokara.hateblo.jp

では、触ってみただけだったので、少しうんちくを参考資料などから拝借する。

うんちくとか

なんぼ?

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 に保存される

共有

  • リポジトリ内で AWS のリソースタグが利用可能
  • リソースレベルのアクセス制限によりアカウントを越えてコンテナイメージを共有することが可能

アクセスコントロール

  • IAM によってコンテナイメージへのアクセス制限を設けることが出来る

暗号化

  • コンテナイメージの送受信は HTTPS 経由で行われる
  • 保存されたイメージは Amazon S3 のサーバー側で自動的に暗号化される

モニタリング

  • 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 の連携をしてみる。

20151223024101

教材はいつものように。

inokappa/oreno-ecs-tutorial
Contribute to oreno-ecs-tutorial development by creating an account on GitHub.

github.com

ドキュメントによると ECR との連携については以下の条件を満たす必要がありそう。

  • ECS Container agent のバージョンは 1.7 以上
  • latest バージョンの Amazon ECS-optimized AMI で起動したコンテナインスタンス

但し、今回は 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 にて確認。

20151223021010

そして…暫くすると 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 を適切に付与すること。ここだけ気をつければ簡単に連携を試すことが出来ると思う。

以上。

元記事はこちら

(ショロカレ 23 日目)Amazon ECR をもう一時間使ってみた(aws-cli による操作と ECS との連携を試す)