AWSECS

AWS ECRでDockerイメージを管理する

ECSを使用する上で、必ずお世話になるであろうコンテナイメージを管理するためのサービス ECR(Elastic Container Registry)の基本的な使い方をメモっておきます。

スポンサーリンク

前提

AWS CLIのインストール

AWS CLIが必要になります。まだインストールしていない方は、以下の記事を参考にしてみてください。個人的にはAWS Vaultがオススメです。

Dockerのインストール

dockerコマンドも必要になります。

Get Docker
Download and install Docker on the platform of your choice, including Mac, Linux, or Windows.

ECRの使用方法

リポジトリ作成

まずDockerイメージを保管する場所となるリポジトリを作成します。

AWSマネジメントコンソールにログイン → 画面上部検索窓 [ registry ] で検索 → Elastic Container Registry をクリック → ECR画面の左ペイン [ Repositories ] → [ リポジトリを作成 ] を押下し、次の画面でリポジトリの設定を行います。

一般設定

可視性設定

一般的な開発では基本的に プライベート を使っていくことになると思います。プライベートに設定するとリポジトリへのアクセスに、IAMでの認証が必要となります。

認証なしで公開するには パブリック を選択します。ECR Public Gallery に公開され誰でもアクセスできるようになります。

リポジトリ名

任意の名前を入力します。

タグのイミュータビリティ

Dockerイメージは、リポジトリ名:タグ という形で管理します。有効にすると、同じタグでのイメージの保管ができなくなります。以下のようにプッシュ時にエラーとなります。

## 既にECRにlatestというタグでイメージが保管されている状態で、latestタグでイメージをプッシュする
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo
Using default tag: latest
...
tag invalid: The image tag 'latest' already exists in the 'demo-repo' repository and cannot be overwritten because the repository is immutable.
$

タグの上書きを禁止するとこちらの記事のようなメリットがあります。ただ同時にいろいろと使い勝手の良い latest が使えなくなるので、運用しづらくなる面もあります。僕はこの設定を無効のまま、latest と(重複する可能性がほぼないであろう)Githubのコミットハッシュ値をタグとして併用しています。

無効 の場合は、新しく保管されたイメージに当該タグが付きます。すでにECR上に保管されていた当該タグのイメージからは、そのタグが外れます。(結果、タグがなくなったイメージは <untagged> というタグになります)

イメージスキャンの設定

プッシュ時にスキャン

有効にすると イメージ保管時に無料でイメージの(ベーシック)スキャンができますが、2021年末に拡張スキャンがリリースされ、コンソール上は非推奨と表示されるようになったようです。

なお無効としてもベーシックスキャンであれば、任意のタイミングでスキャンを手動実行できます。

暗号化設定

KMS 暗号化

イメージはデフォルトでサーバサイド暗号化が行われS3へ保存されます。KMSで管理している暗号鍵を用いて暗号化したい場合は、有効にします。



Dockerイメージの保管

保管する場所を作成したので、実際にDockerイメージを保管します。保管の操作は、マネジメントコンソールからはできません。方法は何通りかありますが、今回は AWS CLI を使います。(本格的に CI/CD をやる場合は、CodePipeline などを使用します)

なおAWS CLIのコマンドについては、ECR画面でリポジトリを選択し、画面右上の [ プッシュコマンドの表示 ] を押下すると、一連のコピペ用のコマンドが表示される親切設計となっています。

ECR にログイン

レジストリをプライベートで作成している場合、まずレジストリにログインする必要があります。awsコマンドとdockerコマンドの組み合わせでログインします。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
$

このコマンドですが、get-login-password サブコマンドでパスワードが標準出力されるので、それを docker login コマンドの password-stdin オプションで標準出力から入力を受け取る形になっています。

## とても長いパスワードが表示されます
$ aws ecr get-login-password --region ap-northeast-1
eyJw.........................==
$

AWS Vaultを使用した場合でも同様に実行できます。

$ aws-vault exec zoo -- aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Enter token for arn:aws:iam::123456789012:mfa/zoo-jump:   ->認証コードを入力
Login Succeeded
$

なお、AWS CLI Version 1.17.10までは、get-loginというサブコマンドを使用していたようですが、こちらは非推奨となっています。AWS CLI Version 2ではサブコマンド自体が存在しません。

Dockerイメージのビルド

ECRに保存するDockerイメージを build コマンドで作成します。以下の例では、公式のnginxイメージをビルドしています。

## nginxイメージをビルドするDockerファイルを作成
$ echo 'FROM nginx' > Dockerfile
$
## -t リポジトリ名:タグ でタグを付けます。タグがない場合は、latestとなります。
$ docker build -t demo-repo .
...
$
## 作成されたイメージの確認
$ docker images demo-repo
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
demo-repo    latest    b55fc8c4dacc   12 days ago   142MB
$

Dockerイメージのプッシュ

push コマンドでECRにDockerイメージを保管します。

前述のビルド時に リポジトリ名[:タグ] とタグ指定しましたが、リポジトリの前にホスト名がない場合は、デフォルトでDockerリポジトリにプッシュされます。(そしてプッシュする権限ないのでエラーとなります)

そのためプッシュの前に、tag コマンドで ホスト名/リポジトリ名[:タグ]とECRのリポジトリを指定しつつ新しくタグ付けします。

$ docker tag demo-repo:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo:latest
$
## 作成されたイメージの確認
## demo-repo イメージがホスト名あり と なしの2つとなります
$ docker images demo-repo --filter=reference='*/demo-repo'
REPOSITORY                                                    TAG       IMAGE ID       CREATED       SIZE
demo-repo                                                     latest    b55fc8c4dacc   12 days ago   142MB
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo   latest    b55fc8c4dacc   12 days ago   142MB
$
## プッシュ
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo:latest
...
$
## ホスト名なしのDockerリポジトリへのプッシュはエラーとなります
$ docker push demo-repo
Using default tag: latest
The push refers to repository [docker.io/library/demo-repo]
...
denied: requested access to the resource is denied
$

なおAWSコンソール上で表示される手順は上記の流れですが、ビルド時のタグを最初からホスト名ありで指定すれば、 tag コマンドで再度タグ付けする必要はなくなります。

$ docker build -t 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo .
...
$
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo
...
$

Dockerイメージの確認と取得

Dockerイメージの確認

AWSマネジメントコンソールで確認します。

ECR画面の左ペイン [ Repositories ] → [ Private ] タブ → 当該リポジトリ名 をクリックすると、保管されたイメージが表示されます。

以降はECSなどで、このECRに保管されたイメージを使用していく流れになります。

Dockerイメージの取得

ローカル環境にイメージを持ってない人は pull コマンドでイメージを取得します。プッシュ時と同じくレジストリへのログインが必要になります。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
$
$ docker pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/demo-repo
...
$

今回は以上です〜ノシ

参考

(´・ω・`)ゞアリガトゴザイマス.。.・゚

AWS CLIでECRにログインする時はget-loginではなくget-login-passwordを使おう
Use the Docker command line
latestタグ絶対禁止!?ECRでコンテナイメージタグの変更禁止設定がサポートされました!
新たなAmazon Inspectorと統合されたAmazon ECRのイメージスキャン拡張版がリリースされました!