メモ > サーバ > サービス: AWS > Amazon Elastic Container Registry(Amazon ECR)
■Amazon Elastic Container Registry(Amazon ECR)
AWSでDockerを使うなら、イメージのリポジトリにはECRを利用するといい
DockerHubは徐々に制限が厳しくなっている
また、Dockerhubからイメージがなくなったときのことを考えて、ECSには常にECRを使っておくと無難だと思われる
(公式イメージが無くなることは無いと思われるが、Dockerhubのサーバダウンなどが可用性に影響するため)
【ECR】リポジトリの作成からイメージのプッシュまで - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2020/01/23/ecr/
AWS CLIを使ってECRにDockerイメージを登録する | DevelopersIO
https://dev.classmethod.jp/articles/push-docker-image-to-ecr-with-cli/
Amazon ECRからローカル環境にコンテナイメージをPullする方法 メモ - Qiita
https://qiita.com/KWS_0901/items/95a6a386ec3eabd49afa
AWS CLIをインストールし、ECRへDockerイメージをpushする手順 | Enjoy IT Life
https://nishinatoshiharu.com/ecr-with-awscli/
■CLIの準備
ECRへのプッシュにはCLIが必要となる
最近起動したAmazonLinux2サーバだと、以下がプリインストールされていた
$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.243-185.433.amzn2.x86_64 botocore/1.18.6
CLIを「WSL2 + Ubuntu 20.04」環境へインストールしたときのメモは、
このファイル内の「AWS CLI(WSL2 + Ubuntu 20.04 で使用する場合)」を参照
■イメージを作成
※WSL2環境でイメージを作成
「php:8.1-apache」をもとに、追加でファイルを作成するだけのイメージを作成する
docker\ecr_test\Dockerfile … Dockerfileを作成
FROM php:8.1-apache
RUN touch /root/test1.txt
$ docker image build -t php:ecr_test docker/ecr_test … Dockerfileをもとに、新しいイメージをビルド
$ docker image ls … 作成されたイメージを確認
docker\ecr_test\code\index.php … 動作確認用にPHPプログラムを作成
<?php phpinfo() ?>
以下で起動する
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d php:ecr_test
… 作成したイメージから起動
$ docker container exec -it ecr_test bash … phpコンテナのターミナルに接続
# ls /root … テストファイルを確認する
# exit
また http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
確認できたら、起動したコンテナは終了しておく
$ docker container ls
$ docker container rm -f a3fee9aba4b8
■リポジトリの作成
※AWSコンソールで作業
Elastic Container Registry → リポジトリを作成
※初めてアクセスした場合、まずは「使用方法」をクリックすると「リポジトリを作成」と同じ画面が表示される
以下の内容でリポジトリを作成(いったん、リポジトリ名を入力する以外は初期値で作成してみる)
なお、「可視性設定」と「リポジトリ名」は後から変更できない
可視性設定: プライベート
リポジトリ名: ecr_test
タグのイミュータビリティ: 無効(実際に案件用にリポジトリを作成する場合、「有効」にしておくといい。詳細は後述の「タグの上書き禁止設定」を参照)
「リポジトリを作成」ボタンを押すとリポジトリが作成される
■イメージのプッシュ
※タグは「latest」ではなく、「1.1」や「1.0.1」のようなバージョンを指定しておく方が無難そう
詳細は後述の「タグの上書き禁止設定」を参照
AWSコンソールで作成したリポジトリにチェックを入れ、「プッシュコマンドの表示」ボタンを押す
解説とともに、以下のコマンドが表示される
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t ecr_test .
docker tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
以下はWSL2環境で実際に実行した時のもの
※アクセスキーには、ECR操作のための最低限の権限だけを設定しておくといい
この場合、AWSへの接続確認は「$ aws ecr list-images --repository-name ecr_test --query "imageIds[*].imageTag" --output table」のようにしてタグ一覧を表示すると良さそう
(「ecr_test」部分は、接続したいリポジトリ名を指定する)
$ cd docker/ecr_test
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/refirio/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
$ docker image build -t ecr_test .
Sending build context to Docker daemon 3.584kB
Step 1/2 : FROM php:8.1-apache
---> 76fa555fcac9
Step 2/2 : RUN touch /root/test1.txt
---> Using cache
---> e8332eb2f5c2
Successfully built e8332eb2f5c2
Successfully tagged ecr_test:latest
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test]
16788635e2ad: Pushed
839aba438279: Pushed
5fa1fe860d6d: Pushed
fbc5f9f798a9: Pushed
0247316d71c0: Pushed
d83d11719d7e: Pushed
a7618c479297: Pushed
fd73f51dc648: Pushed
d40a2cacf223: Pushed
5eea57558f06: Pushed
e1937617ab94: Pushed
3f0d95c332b4: Pushed
ffa1dde3d394: Pushed
43b3c4e3001c: Pushed
1.0.0: digest: sha256:88bc7b7d5c6966a4ca2f043a821d64d36d573c47ac3d877d466fa4d8d4d5486f size: 3242
ECRでリポジトリ名 ecr_test をクリックし、イメージタグとして「1.0.0」が現れていることを確認する
■イメージを利用
ECRからの取得を確認できるようにするため、
「イメージを作成」でタグ付けしたイメージを以下で削除しておく
$ docker image ls
$ docker image rm 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
イメージを再取得
$ cd
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
… プッシュしたイメージから起動
$ docker container exec -it ecr_test bash … phpコンテナのターミナルに接続
# ls /root … テストファイルを確認する
確認できたら、起動したコンテナは終了しておく
$ docker container ls
$ docker container rm -f 2cbfa9da239c
■イメージの脆弱性スキャン
リポジトリ内のイメージ一覧で、任意のイメージにチェックを入れて「スキャン」を押すと、イメージの脆弱性スキャンを利用できる
上記イメージに対して実行すると、441件の警告が表示された。詳細は以下のとおり
Critical ... 1
High ... 5
Medium ... 26
Low ... 17
Informational ... 207
Undefined ... 186
Criticalの内容は以下のとおり
名前: CVE-2019-19814
パッケージ: linux:5.10.127-1
重要度: CRITICAL
説明: In the Linux kernel 5.0.21, mounting a crafted f2fs filesystem image can cause __remove_dirty_segment slab-out-of-bounds write access because an array is bounded by the number of dirty types (8) but the array index can exceed this.
【超待望アップデート】ECRに対する脆弱性スキャン機能が提供されました | DevelopersIO
https://dev.classmethod.jp/articles/ecr-repository-scan/
対応については、また確認しておきたい
脆弱性スキャンについては、後述の「ベースイメージのセキュリティチェックについて考察」も参照
■latestタグについて
※タグは「latest」ではなく、「1.1」や「1.0.1」のようなバージョンを指定しておく方が無難そう
詳細は後述の「タグの上書き禁止設定」を参照
以下のように「ecr_test:latest」を付けてイメージをプッシュした場合、
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
以下のように「ecr_test」のみの指定で「latest」を取得できる
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test
Dockerfile を以下のように編集
docker\php_create_file\Dockerfile
FROM php:8.1-apache
RUN touch /root/test1.txt
RUN touch /root/test2.txt
イメージをビルド
$ cd docker/ecr_test
$ docker image build -t ecr_test .
latestタグを上書きしてプッシュ
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
イメージを再取得
$ docker image rm 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ cd
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test
最新の内容を取得できていることが確認できる
■タグの上書き禁止設定
リポジトリの設定編集で「タグのイミュータビリティ」を「有効」にすると、
タグを上書きしてプッシュしようとすると以下のようなエラーになる
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test]
3d6ebb73c1c8: Pushed
682dac57ee22: Layer already exists
e91015d98cd4: Layer already exists
a8ada76173c3: Layer already exists
46a0f0111934: Layer already exists
d6da32e9bff2: Layer already exists
400f5ced50ab: Layer already exists
7485c1ee99c3: Layer already exists
b98c6acdec28: Layer already exists
86b5e34374f3: Layer already exists
c52f69d9a297: Layer already exists
c24f05541085: Layer already exists
82f581b09510: Layer already exists
3b7e206db54c: Layer already exists
575b147c7c31: Layer already exists
814bff734324: Layer already exists
tag invalid: The image tag 'latest' already exists in the 'ecr_test' repository and cannot be overwritten because the repository is immutable.
以下のように、別のタグ(ここでは「1.0.1」)を指定するとプッシュできる
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
これにより、常に「latest」タグを付けてプッシュする運用を禁止することができる
(プッシュのためには、明示的に「1.1」や「1.0.1」のようなバージョンを指定することになる)
「latest」タグを使うと常に最終バージョンを取得するため、意図しない修正が入ったイメージを取得してしまう可能性がある
よってタグを付けるとき&Dockerfileで指定するとき、どちらも明示的にバージョンを指定するといい
■プログラムをイメージに含める
トップページにアクセスすると、ボリューム同期なしで phpinfo() が表示されるようにしてみる
docker\ecr_test\code\index.php
<?php phpinfo() ?>
docker\ecr_test\Dockerfile
FROM php:8.1-apache
COPY code /var/www/html
$ docker image build -t php:ecr_test docker/ecr_test
$ docker image ls
以下で起動する
$ docker container run --name ecr_test -p 80:80 -d php:ecr_test
$ docker container exec -it ecr_test bash
# ls /var/www/html
# exit
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker container ls
$ docker container rm -f 6f986c913818
タグ「1.1.0」を付けてプッシュする
$ cd docker/ecr_test
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t ecr_test .
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
ECRでリポジトリ名 ecr_test をクリックし、イメージタグとして「1.1.0」が現れていることを確認する
Docker Composeでの起動も試す
docker\ecr_compose_test\docker-compose.yml
version: '3'
networks:
compose_network:
driver: bridge
services:
php:
container_name: ecr_test
ports:
- 80:80
networks:
- compose_network
image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
ファイルを用意できたら以下で起動する
$ cd docker/ecr_compose_test
$ docker-compose build
$ docker-compose up -d
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker-compose down
■パブリックレジストリの利用
※うまくいかず
ECRからDocker公式イメージが取得可能になったらしい
Amazon ECR PublicからDocker公式イメージが取得可能に。Docker Hubのプル制限を回避可能。AWS re:Invent 2021 − Publickey
https://www.publickey1.jp/blog/21/amazon_ecr_publicdockerdocker_hubaws_reinvent_2021.html
[速報]AWS、Docker Hubの代替を狙う「Amazon Elastic Container Registry Public」提供開始。AWS re:Invent 2020 − Publickey
https://www.publickey1.jp/blog/20/awsdocker_hubamazon_elastic_container_registry_publicaws_reinvent_...
ECRをパブリックレジストリとして利用可能になりました! #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/ecr-public-registry/
ECRにある「php:8.1-apache」を使ってみる
Elastic Container Registry → Public gallery
ページ上部の検索フォームから「php:8.1-apache」と入力して検索すると、以下のページにたどり着くことができる
「Mirror of dockerhub php:8.1-apache」と書かれているので、DockerHubにあるイメージのコピーだと思われる
https://gallery.ecr.aws/w8m1p4d9/php_7_4_apache
docker\ecr_test\Dockerfile
FROM public.ecr.aws/w8m1p4d9/php_7_4_apache:latest
COPY code/html /var/www/html
以下のようにビルド
$ docker image build -t php:ecr_test docker/ecr_test
Sending build context to Docker daemon 5.12kB
Step 1/2 : FROM public.ecr.aws/w8m1p4d9/php_7_4_apache:latest
latest: Pulling from w8m1p4d9/php_7_4_apache
6f28985ad184: Pulling fs layer
db883aae18bc: Pulling fs layer
ffae70ea03a9: Pulling fs layer
1e8027612378: Waiting
3ec32e53dce5: Waiting
3bb74037bf77: Waiting
feda0fbd85b1: Waiting
b2244185b327: Waiting
8852ae668073: Waiting
985e21deb66e: Waiting
f262da4e7afa: Waiting
157f3d683e13: Waiting
990684a56233: Waiting
error pulling image configuration: Get "https://d2glxqk2uabbnd.cloudfront.net/ea2ac3-888802067332-72bc2017-5f4e-65a5-91f4-1bc1b7f291e8/441e156b-f02f-449d-9755-258c18f5ed29?Expires=1641552304&Signature=ipSg9QA9J0En6pUPT6IYwqLzAG8DFmaUcv7FGj3-YTVuPvv8MhT72RpRObzimwKt27OuPFMQcC3c8L-T717LgMHu03o4dXFF8DNv~yAjiTWCmOD8rxn1T7HuqsVeyG1W-dx8WwWW5KS2xlnbrdSI58uoc8gckWMzN4fEElqIA0UtpfkWxnO7IRzlnGYHO0T0ZMvZStu5N26FI2z2IDi2SW~YUwaItKyfJy0BhO0st8fi1RZZTGZblQovNv1c01EF1XzhyCf7uyyKQH0WY5JPgFmecljNpivgeo4OKDJbbsvsOAJAKZFnI06JCu2soFO2megUnBCnS5rfbo1zHnGZ4g__&Key-Pair-Id=KSPLJWGOARK62": dial tcp: lookup d2glxqk2uabbnd.cloudfront.net on 172.21.192.1:53: read udp 172.21.198.215:38077->172.21.192.1:53: i/o timeout
直接は取得できない?
Pull through cacheという仕組みを使う前提?
Amazon ECRのPull through cacheでECR PublicからDocker公式イメージをpullする - Qiita
https://qiita.com/hayao_k/items/78d3acd5b19af0cfa73b
Elastic Container Registry → Private registry → Pull through cache → ルールを追加
パブリックレジストリ: ECR Public
送信先: ecr-public (デフォルトのままとした)
「保存」ボタンをクリック
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/w8m1p4d9/php_7_4_apache:latest
latest: Pulling from ecr-public/w8m1p4d9/php_7_4_apache
6f28985ad184: Pulling fs layer
db883aae18bc: Pulling fs layer
ffae70ea03a9: Pulling fs layer
1e8027612378: Waiting
3ec32e53dce5: Waiting
3bb74037bf77: Waiting
feda0fbd85b1: Waiting
b2244185b327: Waiting
8852ae668073: Waiting
985e21deb66e: Waiting
f262da4e7afa: Waiting
157f3d683e13: Waiting
990684a56233: Waiting
error pulling image configuration: Get "https://d2glxqk2uabbnd.cloudfront.net/ea2ac3-888802067332-72bc2017-5f4e-65a5-91f4-1bc1b7f291e8/441e156b-f02f-449d-9755-258c18f5ed29?CallerAccountId=410618224259&Expires=1641553565&Signature=ZxqG3VRFp2gKq8enC5vyllnSMKBpSYNuvBddIpAYQQHEdg1~81Wgl37CortOA62aWQ-ddL2dkRFB5LawVdh6EasXrb-hlHy35sdVCQbplrfw1qzCv8i9Mp~wq72jD5rnokqJIdi~bUTIpIAN3VWW~n8gypQjf0TC9TD0XsErzHwar8t4~GcYalanEQ-RqcZ-exUMteduXh~MQLNIhtC~SH2CEZNaTbE6aon4Q9HjHo73PAbHi0CyJAf52PzV1hYaVywA3r5GYECgbsW65E1PNx9vMQyG1HLvHaizRp3BbE0jHSRMMX2EqfH0wG1J5WukkPzYAMpBkoL1qGwrF~slnw__&Key-Pair-Id=KSPLJWGOARK62": dial tcp: lookup d2glxqk2uabbnd.cloudfront.net on 172.21.192.1:53: read udp 172.21.198.215:43724->172.21.192.1:53: i/o timeout
それでも取得できない?
Amazon ECRに「プルスルーキャッシュリポジトリ」機能が追加されました #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/ecr-pull-through-cache-repositories/
$ docker image pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/amazonlinux/amazonlinux:latest
latest: Pulling from ecr-public/amazonlinux/amazonlinux
8b8a142162d2: Pulling fs layer
error pulling image configuration: Get "https://prod-ap-northeast-1-starport-layer-bucket.s3.ap-northeast-1.amazonaws.com/70714d-410618224259-b2beaaf0-1cbb-117e-eacb-91470817179b/725cefd4-a87c-42fa-b3ed-23488a697ef0?X-Amz-Security-Token=IQoJb3JpZ2luX2VjELH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLW5vcnRoZWFzdC0xIkcwRQIgRd4kBfF0JdGNO5z6siF1bRu7gknlu9KV26U2JSbDhb8CIQDShYYLQI7YfgFkJhu4rjRPmHdgxqf%2BlLJY2U7RzceF2CrRAwi7%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAMaDDc1NTI1NTY5Mjg2NSIMNGsKlupyXWB01Mm6KqUDPyEIrYf92RxamIfJBOD%2FQa1I9afmnW9TIV%2FLnrIU6MyM9bJ6qQhw2aewaXynx9NR2qqaE53vmUgpOLIQj7%2Fv7yL%2BTuI5tI9HPEKtwRyPb9E5ovgtdOORa8kEg%2F5K7LGzPVlafYuDu%2FWme9f60P7dw7VRgqiRFQ7pnFM50DX9eNxmGkn%2F2GzCg7OKaY141XtyEz9NkEwm3vOASnGo3tPXRuuOe0bMcZOGAl5%2FnwEbAq5QCvs%2FodVeaE0sP0hDi44p1hMuOMh8X2skQTtv9xJCg5cdFBJsMo%2Fm0tiih%2FfZpmwokM2YtZ0AMQNzLNDjFrunt2F2WwejLBIjx0uj0oKyOCYQreYvQG4JPXxpOZZy57Wdvt38p%2BVMoJfvYkuArIaf0HWAlrPuIRcQTsx7BPGepNPW4ZK5PG34w835iofsfSHTAWt1fNxIYq0OuZzAef4TEIOg3Kcpbg8MGWLaIclML8ZQYQ2FGLu4fAN1Hoc4NJ70wcBBGezb%2BD2TrUR8hiNdDy7iZnSGIcJpERm5%2BNFMbVZrg9H%2FCoVt6aGkoWVfXWTqM2YiOjD1jeCOBjqhAfLEVya56lIu5ZCv6F2aMiTqIWaE%2FOH3yZ9R5ftHYoFTPMnuAAOX6cSIogwpeaFFMfWFEV2ATHBOkMUiUEcbRldYX%2FpkNY28iPZJC6GgeyA3Mi6Xm6GZLTN1ZykNHlMbSn%2BHDlo4ohixtbQnfd6g%2FEcnBu0JdiJhomkYAbXmqAZLnDUNH7VTM3ed8KcBLtuOALk%2FcI4XORnxpinurUJ7n8a6&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220107T101729Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=ASIA27WF7JZA4KABMSMU%2F20220107%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Signature=429064555b3bb4f68a7be6f36d22ec42bf8f565638c5467647ff96a3a23513a2": dial tcp: lookup prod-ap-northeast-1-starport-layer-bucket.s3.ap-northeast-1.amazonaws.com on 172.21.192.1:53: read udp 172.21.198.215:60628->172.21.192.1:53: i/o timeout
それでも取得できない?
何か勘違いしてそうなので、改めて勉強する
取得できたら、AWS.txt の「Amazon Elastic Container Registry(Amazon ECR)」の「プログラムをイメージに含める」を参考に、Dockerfileを調整してプッシュするか