latestタグ絶対禁止!?ECRでコンテナイメージタグの変更禁止設定がサポートされました!

普段のコンテナ運用を見直すきっかけになる地味だけど有用なアップデートです。一度開発環境で試してみてはいかがでしょうか。
2019.07.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

アップデート続きのECRですが、先日、コンテナのイメージタグを上書き禁止にする設定がサポートされました。

Amazon ECR Now Supports Immutable Image Tags

この設定をしたECRではタグの別イメージへの付け替えが禁止されます。latestタグを使った運用もできなくなります。

「ええ!latest、もう、使えないの…!?」

  ( ゚д゚) ガタッ
  /   ヾ
__L| / ̄ ̄ ̄/_
  \/   /

別に設定しなければ、従来どおり使えますYO

イメージタグの上書き禁止設定は何が嬉しいのか?

従来は、リポジトリに対してプッシュしたイメージにつけたタグを他のイメージに付け替えることが容易に可能でした。ということは、開発者がどのイメージが実際に運用環境で展開し動いているかどうかを厳密に知るためには、イメージのSHAの利用が必須でした。

Amazon ECRでイメージタグを上書き禁止の設定にすることで、開発チームが作成したイメージのバージョンと、実際に運用されているイメージの識別をイメージタグを利用して実施することができるようになります。

設定方法の詳細など、公式ドキュメントはこちら。

イメージタグの上書き禁止設定方法

ECRリポジトリの新規作成時、および既存のリポジトリの変更の両方に対応しています。

新規作成時の設定方法

Webコンソールから新規作成

リポジトリの新規作成時に「イメージタグの変更可能性」に関する項目が増えているので、ここで「変更不可能」を選択します。

AWWS CLIから新規作成

AWS CLIを最新版にバージョンアップしておきます。

$ aws --version
aws-cli/1.16.207 Python/3.6.4 Darwin/18.6.0 botocore/1.12.197

create-repositoryコマンドに、新たに--image-tag-mutabilityオプションが増えているので、それを使います。

コマンド例はこちら。immutable-repoリポジトリをIMMUTABLEとして作成します。

$ aws ecr create-repository --repository-name immutable-repo --image-tag-mutability IMMUTABLE
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:123456789012:repository/immutable-repo",
        "registryId": "123456789012",
        "repositoryName": "immutable-repo",
        "repositoryUri": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo",
        "createdAt": 1564290230.0,
        "imageTagMutability": "IMMUTABLE"
    }
}

Webコンソールから既存のリポジトリを変更

既存のリポジトリを選択して「編集」ボタンを押すと、イメージタグの変更可能性を編集できます。

AWS CLIから既存のリポジトリを変更

put-image-tag-mutabilityコマンドを使います。

$ aws ecr put-image-tag-mutability --repository-name immutable-repo --image-tag-mutability IMMUTABLE
{
    "registryId": "123456789012",
    "repositoryName": "immutable-repo",
    "imageTagMutability": "IMMUTABLE"
}

イメージタグの変更不可能性の動作を確認

実際に、イメージタグの変更不可能性の動作を確認してみます。IMMUTABLEなリポジトリimmutable-repoを使います。

以下のDockerfileを用意します。

Dockerfile

FROM scratch

LABEL maintainer "hamako0001"

ECRのプッシュコマンドに則り、ログインしてタグにlatestを付けて、プッシュします。

$ $(aws ecr get-login --no-include-email --region ap-northeast-1)
$ docker build -t immutable-repo .
$ docker tag immutable-repo:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo:latest
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo:latest

リポジトリの内容を確認すると、latestタグでイメージが1つ登録されていることがわかります。

$ aws ecr describe-images --repository-name immutable-repo
{
    "imageDetails": [
        {
            "registryId": "123456789012",
            "repositoryName": "immutable-repo",
            "imageDigest": "sha256:ebce9620b3c20dcdea9ff4653e8740ec76cbf2594f0f4e328b3dbfb8d9f1ed8f",
            "imageTags": [
                "latest"
            ],
            "imageSizeInBytes": 32,
            "imagePushedAt": 1564290849.0
        }
    ]
}

この状態で、先程ビルドしたDockerfileの内容を変更して別のイメージを作成します。maintainerの内容を変更したDockerfileを用意。

Dockerfile

FROM scratch

LABEL maintainer "hamako0002"

上の手順と同様に、ビルドしてプッシュしようとすると、tag invalidのエラーが表示されます。

$ $(aws ecr get-login --no-include-email --region ap-northeast-1)
$ docker build -t immutable-repo .
$ docker tag immutable-repo:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo:latest
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo:latest
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/immutable-repo]
tag invalid: The image tag 'latest' already exists in the 'immutable-repo' repository and cannot be overwritten because the repository is immutable.

このように、イメージタグの変更可能性を変更不可能に設定("imageTagMutability"が"IMMUTABLE")なECRリポジトリに対しては、latestタグを別イメージにつけてプッシュすることができなくなります。

タグの変更を不可能にすることによる、より安全で明確なコンテナ運用が可能に

コンテナワークロードにおいては、ソースコードとコンテナイメージのトレーサビリティを確保するため、CI/CDの中でDockerビルド時のgitのコミットハッシュやタグの名前を、イメージタグにつける場合が多いかと思います。

上で見たとおり、タグの変更が不可能に設定されたECRでは、イメージタグのlatestを利用した運用が事実上できなくなります。また、一度イメージに付与したタグの変更もできません。例えばECSにおいては、コンテナ定義でのリポジトリのlatest指定も使えないので、新しいイメージがビルドされるたびにタスク定義の変更とサービス定義の変更が必須となります。

一見これは運用がめんどくさくなりそうですが、これを強制しておくことで、ソースコードとコンテナイメージの一貫性の把握が容易になり、トラブルシューティング時に無駄な時間を使うことが減るでしょう。また、イメージタグの変更を禁止しておくことで、イレギュラーな運用によるトラブルや不正イメージの混入などのセキュリティ上の脅威に対しても、一定の抑止効果が期待できます。

既存の運用環境に対していきなりこの設定変更をするのはリスクが高すぎますが、一度開発環境などでこの設定を試してみて、より明確で一貫性のあるコンテナ運用を目指してみるのはいかがでしょうか。

それでは、今日はこのへんで。濱田(@hamako9999)でした。