【Amazon ECR】Amazon Elastic Container Registryの基本(プッシュの処理、ライフサイクルポリシーなど)

記事タイトルとURLをコピーする

こんにちは!技術4課のイーゴリです。

Amazon ECR(「Amazon Elastic Container Registry」の省略)とは、完全マネージド型のDockerコンテナレジストリです。簡単に説明しますと、Docker Hubにとても似ているサービスです。

例えば、Dockerfileを作成し、Buildを実行すると、Dockerが作成された後、作ったDockerをどこで保存すれば良いかというと、Docker Hub以外にAmazon Elastic Container Registryが存在していますので、本件の記事では、Amazon Elastic Container Registry (ECR)についてご説明したいと思います。

前提条件

  • Dockerの基本コマンドの理解
  • インストール済みのDocker
  • 設定済みのAWS CLI

私の環境はMacOSですが、Windows、LinuxでもDockerを使えます。

Amazon ECRのリポジトリの作成

[Repositories]>[リポジトリを作成]をクリックします。

プライベートリポジトリを作成したいため、[可視性設定]で[プライベート]を選択します。そして、[リポジトリ名]を入力します。

[リポジトリ名]の下に書いてある下記のようなURLについて詳しく説明したいと思います。

リポジトリURIは「12345678900000.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1」となります。

リポジトリURIの解説:

  • 「123456789000」ー AWSアカウント番号
  • 「dkr」ー Dockerの省略
  • 「ecr」ー Amazon ECRの省略
  • 「ap-northeast-1」ー リポジトリのリージョン

「イメージスキャンの設定」及び「暗号化設定」をそのまま残し、[リポジトリを作成]をクリックします。

新規で作成したリポジトリに入りますと、イメージがない状態になりますので、Docker pushコマンドでアップロードする必要があります。下記のWebユーザーインターフェースからのアップロードが不可となります。

[プッシュコマンドの表示]をクリックすると、Windows/Linux/MacOSのプッシュ手順が出ます。

Dockerイメージの作成(任意)

nginxのコンテナを起動し、「index.html」に「Version X」と記載します。その後、複数のDockerイメージを作成します。

% docker pull nginx
% docker images   
                   
REPOSITORY               TAG       IMAGE ID       CREATED       SIZE
nginx                    latest    fd3d31a07ae6   3 weeks ago   134MB
docker/getting-started   latest    157095baba98   13 days ago   27.4MB
% docker run -d -p 1235:80 nginx
% docker ps                             
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
d63f68be0cb2   nginx     "/docker-entrypoint.…"   13 minutes ago   Up 13 minutes   0.0.0.0:1235->80/tcp   exciting_wiles

下記のURLにアクセスすると、nginxのスタートページが表示されます。

http://localhost:1235/

% docker exec -it d63f68be0cb2 /bin/bash
# cd /usr/share/nginx/html
# echo "Version 1" >> index.html
# exit

また下記のURLにアクセスしますと、下記の画面に「Version 1」という記載が表示されるので、Dockerイメージを作成します。

http://localhost:1235/

% docker commit d63f68be0cb2 igor:v1
% docker images                         
 REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
 igor                     v1        eddbdfc2e0ea   16 seconds ago   134MB
 docker/getting-started   latest    157095baba98   13 days ago      27.4MB
 nginx                    latest    fd3d31a07ae6   3 weeks ago      134MB

上記の手順と同じく「Version 2」を作成します。

下記の結果となります。

% docker images
REPOSITORY               TAG       IMAGE ID       CREATED             SIZE
igor                     v1        38be54f4fbda   About an hour ago    134MB
igor                     v2        eddbdfc2e0ea   10 seconds ago   134MB
docker/getting-started   latest    157095baba98   13 days ago         27.4MB
nginx                    latest    fd3d31a07ae6   3 weeks ago         134MB

試しに「igor:v2」を起動します。

% docker run -d -p 8888:80 igor:v2
% docker ps                             
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
d63f68be0cb2   nginx     "/docker-entrypoint.…"   14 seconds ago   Up 14 seconds   0.0.0.0:1235->80/tcp   exciting_wiles
2bdf7e943443   igor:v2   "/docker-entrypoint.…"   30 seconds ago   Up 30 seconds   0.0.0.0:8888->80/tcp   vigilant_hellman

レジストリの認証

[プッシュコマンドの表示]をクリックすると、Windows/Linux/MacOSのプッシュ手順が出ます。

[1]の手順通りにコマンドを実行します。

が・・・ 私の場合はAWS CLI Profileを使用しているため、上記の手順の通りだと権限がなく、下記のエラーが発生します。

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::123456789000:user/XXXXXX is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action

IAMの「AmazonEC2ContainerRegistryFullAccess」権限があればが上記のコマンドを無事に実行できると思いますので、次のステップ(Dockerプッシュ)に移動してください。

AWS ECRでの権限不足エラーの解消方法

私と同じように下記のエラーが発生する方がいたら、

  • まずは対象AWS CLIユーザーがAmazonEC2ContainerRegistryFullAccessの権限を持っているかご確認ください。
  • スイッチロールを使っている場合、対象プロフィールを指定しないといけないので、下記で適切なコマンドを紹介致します。
% aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::123456789000:user/XXXXXX is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action

上記の場合、別のAWSアカウント経由でスイッチロールの処理を行って、下記のコマンドを実行します。

blog.serverworks.co.jp

スイッチロールを含むコマンドは下記となります。

% aws --profile <プロフィール名> ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com
  Login Succeeded

Dockerプッシュ

[プッシュコマンドの表示]の手順と違って「latest」のタグではなく、「v1」,「v2」など付けたいため、少しコマンドを変更し、下記の通り、実行します。

% docker tag igor:v1 <AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1:v1   
% docker images
REPOSITORY                                                 TAG       IMAGE ID       CREATED             SIZE
<AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1   v1        38be54f4fbda   About an hour ago   134MB
igor                                                       v1        38be54f4fbda   About an hour ago   134MB
igor                                                       v2        eddbdfc2e0ea   2 hours ago         134MB
docker/getting-started                                     latest    157095baba98   13 days ago         27.4MB
nginx                                                      latest    fd3d31a07ae6   3 weeks ago         134MB

Docker imagesで「REPOSITORY」が「<AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1」、「TAG」が「v1」となりました。

上記のイメージをAmazon ECRにプッシュします。

% docker push <AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1:v1
The push refers to repository [XXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1]
3710d91a514e: Pushed 
9a71b3622c62: Pushed 
c692319770ad: Pushed 
4142781731ab: Pushed 
01aab3a35503: Pushed 
c11b105c903e: Pushed 
3185c5ca0c1f: Pushed 
v1: digest: sha256:fa45f24ded43aa92e7fcbe587253ed602f208b7a7a7a3fe2c88e41fddd65ac2f size: 1778

レポジトリーを確認しますと、下記のような画面が表示されます。

無事に「v1」をプッシュすることができました!

上記の手順と同じく「v2」をプッシュします。

% docker push <AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1:v2
The push refers to repository [XXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1]
0403c5e78c9c: Pushed 
9a71b3622c62: Layer already exists 
c692319770ad: Layer already exists 
4142781731ab: Layer already exists 
01aab3a35503: Layer already exists 
c11b105c903e: Layer already exists 
3185c5ca0c1f: Layer already exists 
v2: digest: sha256:a61c55a622128dd70bc0f3f86fc3a2d0f21dced35f119c317c2a8c90c1474a61 size: 1778

v2に変更はほとんどなかったため(Indexページで「Version 1」から「Version 2」に記載を変更したぐらい)、プッシュ時にほぼ「Layer already exists 」となっており、一瞬でプッシュが完了しました。

ちなみに、「docker images」のコマンドの確認によると、イメージサイズは134MBとなりますが、AWSマネジメントコンソールの確認によると、イメージサイズは55.37MBとなりました。2倍ぐらいサイズが小さくなりましたね。

docker images
REPOSITORY                                                 TAG       IMAGE ID       CREATED       SIZE
<AWSアカウント番号>.dkr.ecr.ap-northeast-1.amazonaws.com/myapp1   v1        38be54f4fbda   2 hours ago   134MB

理由はDockerがCompress Imageの処理を行っているためです。

プッシュの作業は以上となりますが、次は他のAmazon ECRの機能をご紹介したいと思います。

Permissions (Amazon ECR リポジトリにアクセス権限)

「Permissions」タブは「誰がAmazon ECR リポジトリにアクセスを持っているか」という設定項目です。

例えば、他のAWSアカウントからもAmazon ECR リポジトリにアクセスしたい場合、ここで設定します。

ライフサイクルポリシー

Amazon ECR ライフサイクルポリシーを使用すると、プライベートリポジトリ内のイメージのライフサイクル管理をより詳細に制御できます。

ECRの料金はレポジトリーの容量によって課金するので、ライフサイクルポリシーで制御をおすすめ致します。

ルールの設定で、「○日たったら、イメージを削除する」というルールもありますし、「○個のバージョン超えたら、古いイメージを削除する」というルールもあります。

この記事では、「レポジトリー内で10イメージ以降の古いバージョンは削除する」という設定を行います。

「イメージのステータス」で「すべて」に変更します。

[一致条件]で[次の数値を超えるイメージ数]を選択した上、10を入力します。

[ルールの説明]を記載した上、[保存]をクリックします。

完了です!

以上、御一読ありがとうございました。

次の記事↓ blog.serverworks.co.jp

本田 イーゴリ (記事一覧)

カスタマーサクセス部

・AWS SAP, DOP, SCS, DBS, SAA, DVA, CLF
・Azure AZ-900
・EC-Council CCSE

趣味:日本国内旅行(47都道府県制覇)・ドライブ・音楽