EC2 Container Registryへ自作のDockerイメージをプッシュ

概要

ECR(Amazon EC2 Container Registory)は、AWSが提供するフルマネージドなDockerコンテナレジストリです。
プライベートなDockerコンテナレジストリとして使えますので、Docker registoryを自前で立てる必要がなくなります。
アクセス制御もIAMからできるようなので、おそらくセットで使う想定のECSのクラスタへDockerコンテナを配備する際などのアクセス権限の取り回しがスマートにできるものと思われます。

今回は、nginxだけが入ったDockerイメージを作成し、ECRへイメージを保存するところまでを試してみます。

ベースとするAmazon Linuxコンテナイメージの取得

先日、

で発表されたとおり、Amazon LinuxのDockerイメージがAWS環境の外でも利用できるようになりました。今回は、こちらをベースイメージとして使用します。

まずはAmazon Linuxコンテナイメージを取得します。
手順は

こちらに従っていきます。

ECRの操作にはaws cliを使用しますので、以降の作業はCredentialがセットされていることが前提となります。

とりあえずAmazonのDockerレジストリにあるAmazonLinuxのDockerイメージを一覧してみます。

$ aws ecr list-images --region us-west-2 --registry-id 137112412989 --repository-name amazonlinux
{
    "imageIds": [
        {
            "imageTag": "latest",
            "imageDigest": "sha256:7a8c3220667f2c7745df567a44de4a798a3d746e22ec2f79250e7819262ad54b"
        },
        {
            "imageTag": "latest-with-sources",
            "imageDigest": "sha256:77da13b438a51aa4b999036d30bab836d29345766f7746776f16775528ab4861"
        },
        {
            "imageTag": "with-sources",
            "imageDigest": "sha256:4e015fa2e01944a4befc3111ccc378f210ca5528651491b4ebbdf400df1198c4"
        },
        {
            "imageTag": "2016.09.0.20161118-with-sources",
            "imageDigest": "sha256:7f5172b5e289855ffc96e0b837bfb51d82a74c917da22476a395829dd4e3094b"
        },
        {
            "imageTag": "2016.09-with-sources",
            "imageDigest": "sha256:1afcf29f528cab412f68216bce7d56ab409332297a40f0ce27e5834faad5e041"
        },
        {
            "imageTag": "2016.09.0.20161028-with-sources",
            "imageDigest": "sha256:3cdd72fda4b9b84fbdcd82fa0ff9172fe728830c5f22d1f55ad4fdf00002bfb1"
        },
        {
            "imageTag": "2016.09",
            "imageDigest": "sha256:ff5456ad17ba1f5714e1c1091a21eb382fe5936e2b7492be9cd93913250e44ab"
        },
        {
            "imageTag": "2016.09.0.20161028",
            "imageDigest": "sha256:4787e4fd03cba7ff63e1592559dc2877af9741e020effc574ccaccb02b63e048"
        },
        {
            "imageTag": "2016.09.0.20161118",
            "imageDigest": "sha256:2facf8d6fc1323761225f8ad6f13642e3389355c1d59e86c5cedce45fac88fa5"
        }
    ]
}

いろいろあります。それだけです。

次に、AmazonのDockerレジストリへアクセスできるパスワードを含んだdocker loginコマンド文字列を取得します。
aws cliのecr get-loginを実行します。

$ aws ecr get-login --region us-west-2 --registry-ids 137112412989
docker login -u AWS -p <passowrdpassword....> -e none https://137112412989.dkr.ecr.us-west-2.amazonaws.com

パスワードを含んだdocker loginコマンドがまるっと出力されますので、コピペして実行します。

$ docker login -u AWS -p <passowrdpassword....> -e none https://137112412989.dkr.ecr.us-west-2.amazonaws.com
Login Succeeded

ログイン成功と出ました。
これでdocker pullが可能になります。
このパスワードでのログインは12時間有効です。

$ docker pull 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
...
Status: Downloaded newer image for 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest

$ docker images
REPOSITORY                                                                            TAG                 IMAGE ID            CREATED             SIZE
137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux                              latest              2e9b68390cd4        10 days ago         292.3 MB

取得したAmazonLinuxをDockerで動かしてみます。

$ docker run --rm 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux cat /etc/system-release
Amazon Linux AMI release 2016.09

問題無さそうです。

…とここまで書いてきましたが、Docker HubにAmazonLinuxのレポジトリができていました。。!

[OFFICIAL REPOSITORY amazonlinux](https://hub.docker.com/_/amazonlinux/"OFFICIAL REPOSITORY amazonlinux")

$ docker pull amazonlinux
...
Status: Downloaded newer image for amazonlinux:latest

$ docker images
REPOSITORY                                                                            TAG                 IMAGE ID            CREATED             SIZE
amazonlinux                                                                           latest              5b52b314511a        6 days ago          292.3 MB

だけでイメージ取得完了です。こっちのほうがかんたん。。

取得したAmazon Linuxコンテナイメージをベースにnginxが入ったコンテナイメージを作成

Dockerfileは以下です。

  • Dockerfile
FROM amazonlinux
# AmazonのDockerレジストリからのイメージを使用する場合は
# FROM 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux

USER root
RUN set -x && \
    yum -y install nginx

RUN set -x && \
    echo "NETWORKING=yes" >/etc/sysconfig/network && \
    mkdir -p /var/www/html && \
    chown -R nginx.nginx /var/www/html && \
    echo "$(hostname)" > /var/www/html/index.html

COPY templates/etc/nginx/nginx.conf /etc/nginx/nginx.conf

RUN ln -sf /dev/stdout /var/log/nginx/access.log \
	&& ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 80

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

nginxのインストールと設定ファイルの配置、それに加えて、ドキュメントルートのindex.htmlへアクセスするとホスト名が表示されるようにしてあります。
(ホスト名を表示しているのは特に意味は無いです。イメージ作成時のホスト名ですし。。)

COPYを使っているので、以下のファイルも置いておきます。

  • templates/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    index   index.html index.htm;

    server {
      listen       80 default_server;
      listen       [::]:80 default_server;
      server_name  localhost;
      root         /var/www/html;
    }
}

buildします。
イメージ名は「oreno/nginx」とします。

$ docker build -t oreno/nginx:latest .
Sending build context to Docker daemon 8.704 kB
Step 1 : FROM amazonlinux
...
Successfully built 4db464ba22ea

buildが完了し、AmazonLinuxをベースとした、nginxが入ったコンテナイメージができました。

試しにdocker runを実行し、ブラウザでhttp://127.0.0.1/へアクセスします。

$ docker run --rm -p 80:80 oreno/nginx

自作Dockerコンテナイメージの起動

nginxが動作し、Dockerイメージを作成したときのホスト名が出力できていることが確認できます。

ECRにリポジトリを作成し、作成済みのDockerイメージをpush

マネジメントコンソールからECSのサービスを選択し「リポジトリ」を選択します。

画面右で「リポジトリの作成」をクリックします。

リポジトリの作成

リポジトリ名を、作成済みのDockerイメージの名前で指定し「次のステップ」をクリックします。

リポジトリの作成

完了です。

リポジトリの作成

上のように、pushする際の手順も出力されます。あとはこれに従っていけばよいです。

まず、aws cliを使用して、AmazonのDockerレジストリへアクセスできるパスワードを含んだdocker loginコマンド文字列を取得し、docker loginします。

$ aws ecr get-login --region ap-northeast-1
docker login -u AWS -p <passowrdpassword....> -e none https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

$ docker login -u AWS -p <passowrdpassword....> -e none https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
...
Login Succeeded

Dockerイメージのbuildは終わっていますので、作成したDockerイメージにタグを付けます。

$ docker tag oreno/nginx:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx:latest

$ docker images
REPOSITORY                                                                            TAG                 IMAGE ID            CREATED             SIZE
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx                         latest              cf06ef870a10        20 minutes ago      409.5 MB

pushします。

$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx:latest
The push refers to a repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx]
...
latest: digest: sha256:ee32d51b02cd4f325f768abb0d027d8cbdd4e6060f8ad64df12a23d5333ac18b size: 6317

pushが完了すると、以下のようにリポジトリの一覧に追加されます。

リポジトリの作成

これでECRへのDockerイメージの保存ができました。

試しに、別の端末からこのDockerイメージを取得してみます。

まずAmazonのDockerレジストリへアクセスできるパスワードを含んだdocker loginコマンド文字列を取得します。

$ aws ecr get-login --region ap-northeast-1
docker login -u AWS -p <passowrdpassword....> -e none https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

docker loginを実行します。

$ docker login -u AWS -p <passowrdpassword....> -e none https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded

$ docker pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx
Using default tag: latest
latest: Pulling from oreno/nginx
...
Status: Downloaded newer image for 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx:latest

$ docker images
REPOSITORY                                                      TAG                 IMAGE ID            CREATED             SIZE
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx   latest              cf06ef870a10        6 hours ago         409.5 MB

docker pullでイメージを取得できましたので、試しにdocker runしてみます。

$ docker run -it -d -p 80:80 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/oreno/nginx

ブラウザで、http://127.0.0.1/へアクセスします。

別端末で自作Dockerコンテナイメージの起動

正常に動作していることが確認できました。

自作のDockerイメージをpushできるようになり、ECRの操作手順は確認できましたので、次はECSクラスターへの配備を試してみたいと思います。