Container Registry の廃止予定と Artifact Registry への移行について

2023/05/19に公開

こんにちは。クラウドエースの阿部です。
このブログ記事では、 Container Registry の廃止予定と、 Artifact Registry への移行について紹介したいと思います。

Container Registry の廃止予定について

2023 年 5 月 15 日に、 Container Registry の廃止に関するスケジュールがリリースノートで公開されました。リリースノートはこちらを参照してください。
現在は非推奨の段階であり、2024 年 5 月 15 日までは変わらずに Container Registry を使用することが可能です。
ただし、Container Registry を使用しているユーザーは、2024 年 5 月 15 日までに以下いずれかの方法で移行することが推奨されています。

  • 標準の Artifact Registry リポジトリを作成し、既存のコンテナイメージをコピーする。以降は Artifact Registry でコンテナイメージを運用する。
  • gcr.io ドメインをサポートする Artifact Registry リポジトリを作成し、既存のコンテナイメージをコピーする。 gcr.io ドメインの Artifact Registry でコンテナイメージを運用する。

Container Registry の廃止予定は下記の通りです。

  • 2025 年 3 月 18 日以降、Container Registry へイメージを保存できません。
  • 2025 年 4 月 22 日以降、Container Registry からイメージを読み取りできません。既存のイメージはアクセス不能になります。
  • 2025 年 5 月 22 日以降、全ての gcr.io ドメインへのリクエストは Artifact Registry でサービスされます。

詳細は下記のドキュメントを参照してください。記事執筆時点では、英語版のみ上記の廃止予定について記載されています。

https://cloud.google.com/container-registry/docs/deprecations/container-registry-deprecation

Container Registry と Artifact Registry の概要

Container Registry (以降 CR) は、2014 年頃から Google Cloud において提供されているコンテナホスティングサービスです。
gcr.io というドメインで提供されており、リポジトリ初期化の手間などがなくシンプルな操作で運用できるサービスです。

https://cloud.google.com/container-registry/docs/overview

一方、 Artifact Registry (以降 AR) は 2020 年頃から提供されているコンテナホスティングサービスです。
pkg.dev というドメインで提供されており、使用するためにリポジトリを別途作成する等の操作が必要ですが、CR にない細やかな権限管理を行うことができ、現在はコンテナイメージだけでなく Java,Node.js,Python といったプログラム言語のパッケージのホスティングも行える多目的なホスティングサービスとして提供されています。

https://cloud.google.com/artifact-registry/docs/overview

Container Registry 移行方法の違いについて

CR リポジトリから標準 AR リポジトリへ移行する場合、移行後は AR のフル機能を使用することが可能です。ただし、コンテナイメージのパスを AR のパスに修正する必要があります。
標準 AR が使用できる機能で、 CR との主な差分は以下が挙げられます。

  • リージョンリポジトリを使用可能 (CR はマルチリージョンのみ)
  • リポジトリレベルの権限(IAM)

一方、 gcr.io をサポートする AR リポジトリに移行する場合は、GKE や Cloud Run 等のコンテナイメージのパス指定を変更することなく、リポジトリ側の変更のみで対応可能です。ただし、前述の AR のフル機能を使用することはできません。

どちらの移行方法を選択するのがよいか

Google Cloud における推奨は「標準 Artifact Registry に移行」です。しかし、 CR を使用している GKE や Cloud Run 等が多い場合、その全てを漏れなく修正することは時間も工数もかかります。
そのため、影響範囲が大きい場合、まずは「gcr.io をサポートする Artifact Registry に移行」して様子見することを推奨します。この場合はイメージの Pull パスを変更することなく移行することが可能です。

標準の Artifact Registry リポジトリに移行する手順

CR のリポジトリを標準の AR リポジトリに移行する手順の概要は以下の通りです。

  1. 移行先の AR リポジトリを作成し、必要に応じて IAM で権限付与する
  2. CR リポジトリから AR リポジトリにコンテナイメージをコピーする
  3. GKE や Cloud Run のコンテナイメージ Pull 先のパスを変更する
  4. CI/CD やツール等でコンテナイメージを作成している場合は、 Push 先のパスを変更する

詳細な手順は標準リポジトリへの移行を参照してください。
なお、本ブログ記事ではこの手順について細かく解説しません。

gcr.io をサポートする AR リポジトリに移行する手順

CR のリポジトリを gcr.io をサポートする AR リポジトリに移行する手順の概要は以下の通りです。

  1. 移行先の AR リポジトリを作成し、必要に応じて IAM で権限を付与する
  2. CR リポジトリから AR リポジトリにコンテナイメージをコピーする
  3. gcr.io のルーティングを切り替える (リダイレクトを有効にする)

上記手順の詳細はこちらのドキュメントを参照してください。
本ブログ記事ではこちらの手順を解説していこうと思います。

移行作業に必要な権限

以降の移行手順は、プロジェクトオーナーロールを付与したアカウントで検証しています。
もし、最小権限のみで実施する場合、公式ドキュメントで示されるロールをあらかじめ付与しておく必要があります。
必要に応じて、ドキュメントを参照しロールを付与しましょう。

移行先の Artifact Registry リポジトリを作成する

移行先の AR リポジトリを作成します。
手順としては Web ブラウザコンソールから一括作成する方法と、コマンドライン等で手動作成する方法があります。
以下の手順は Web ブラウザから一括作成する方法です。

Google Cloud コンソールのナビゲーションバーから、「Artifact Registry」をクリックします。
以下のような画面が表示されますので、「GCR.IO リポジトリを作成」ボタンを押します。

Artifact Registry 画面

gcr.io リポジトリの作成画面が表示されます。「作成」ボタンを押します。

gcr.ioリポジトリの作成画面

しばらくすると Artifact Registry リポジトリの一覧画面に戻ります。
gcr.ioasia.gcr.ious.gcr.ioeu.gcr.ioの 4 つのリポジトリが作成できたことを確認できます。

Artifact Registry 画面

このとき、各リポジトリに ⚠ マークが表示されています。このマークにカーソルを合わせると以下のようなメッセージが表示されます。

Container Registry は引き続き、*gcr.io トラフィックを配信しています。 gcr.io/PROJECT_ID から us-docker.pkg.dev/PROJECT_ID/gcr.io にイメージをコピー してから、Artifact Registry にトラフィックをルーティング して移行を続行します。

現段階ではgcr.ioのルーティングを変更していませんので、この警告が表示されることは正常です。

IAM で権限を付与する

GKE や Cloud Run で CR を運用している場合、 IAM ロールを付与していることがあります。
例えば、 GKE クラスタ(ノードプール)や、 Cloud Run サービスエージェントの読み込み権限(オブジェクト参照者)等です。
こうしたサービスアカウントに対して手動で権限付与している場合は、新たに作成した AR リポジトリにも付与する必要があります。
また、 Cloud Build でコンテナイメージを作成している場合は、 Cloud Build サービスアカウント、または、Cloud Build トリガーで指定しているカスタムサービスアカウントで AR にコンテナイメージを Push できる権限 (Artifact Registry リポジトリ管理者 等) を付与します。CI/CD ツールでカスタムサービスアカウントを使用している場合も Cloud Build のケースと同様です。

なお、Cloud Run サービスエージェント (service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com) はデフォルトで同じプロジェクトにある AR リポジトリに対する読み取り権限を持っています。異なるプロジェクトでコンテナイメージを管理しているケースでは確認頂く必要があります。

GKE クラスタ(ノードプール)のサービスアカウントをデフォルトではなくカスタムサービスアカウントに変更している場合は、同様に IAM 権限の変更(追加)が必要なケースがあります。

CR リポジトリから AR リポジトリにコンテナイメージをコピーする

CR リポジトリに保管されているコンテナイメージを、 gcr.io ドメインをサポートする AR リポジトリにコピーします。
コピーツールは gcrane を使用します。

gcrane インストール

go-containerregistry の最新のリリースを確認して、自分の端末、または、Cloud Shell へ適切なファイルをダウンロードします。公式手順のドキュメントでは、 gcrane のバージョンは 0.10.0 以降が必要です。記事執筆時点の gcrane の最新バージョンは 0.15.2 でした。
例として、 Cloud Shell に gcrane 0.15.2 をインストールする手順を示します。

Cloud Shell 起動後、下記のコマンドを実行してホームディレクトリ移動後に tar.gz ファイルをダウンロードします。

## ホームディレクトリに移動
cd $HOME

## tar.gz ファイルダウンロード
curl -L -O https://github.com/google/go-containerregistry/releases/download/v0.15.2/go-containerregistry_Linux_x86_64.tar.gz

tar.gz ファイルダウンロード後、 gcrane ファイルを展開します。

tar zxvf go-containerregistry_Linux_x86_64.tar.gz gcrane

gcrane ファイルを PATH 環境変数が有効なディレクトリに移動します。どこでもよいのですが、今回はホームディレクトリを使用します。

## ホームディレクトリに .local/bin ディレクトリを作成
mkdir -p "${HOME}/.local/bin"

## gcrane ファイルを移動
mv gcrane "${HOME}/.local/bin"

## .profile ファイルを再ロード
source ~/.profile

これで gracne が実行できるようになったはずです。下記のコマンドを実行してテストしましょう。

gcrane version
実行結果例
$ gcrane version
0.15.2

Go 言語の開発環境がインストールされている場合は、下記コマンドでもインストール可能です。

go install github.com/google/go-containerregistry/cmd/gcrane@latest

(Optional) Artifact Registry サービスアカウントのロール付与

公式ドキュメントでは、Artifact Registry サービスエージェント(service-PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com)にストレージオブジェクト閲覧者のロール(roles/storage.objectViewer)の付与手順がありますが、検証した限りではこのロールを付与しなくてもコンテナイメージのコピーは問題無く実行できました。必須の手順ではありませんが、もし以降の手順で権限系のエラーが発生した場合は、公式ドキュメントにある手順を実行してください。

gcrane によるコンテナイメージのコピー

最初に、プロジェクト ID を変数に設定します。

PROJECT_ID="Google Cloud プロジェクトID"

下記のコマンドを実行して、 CR リポジトリにあるコンテナイメージを AR リポジトリにコピーします。

gcr.io リポジトリのコピー
gcrane cp -r gcr.io/${PROJECT_ID} us-docker.pkg.dev/${PROJECT_ID}/gcr.io
asia.gcr.io リポジトリのコピー
gcrane cp -r asia.gcr.io/${PROJECT_ID} asia-docker.pkg.dev/${PROJECT_ID}/asia.gcr.io
eu.gcr.io リポジトリのコピー
gcrane cp -r eu.gcr.io/${PROJECT_ID} europe-docker.pkg.dev/${PROJECT_ID}/eu.gcr.io
us.gcr.io リポジトリのコピー
gcrane cp -r us.gcr.io/${PROJECT_ID} us-docker.pkg.dev/${PROJECT_ID}/us.gcr.io

コピー後のコンテナイメージの確認

公式ドキュメントでは、コンテナイメージがコピーされたかどうかの確認手順は存在しません。
網羅的に全てチェックする手順は難しいですが、下記のコマンドを使用して tag/hash ベースでの比較は可能です。

gcr.io リポジトリの確認手順
## gcr.io リポジトリのコンテナ一覧
gcloud container images list --repository=gcr.io/${PROJECT_ID}

## gcr.io リポジトリのコンテナ tag/hash 一覧
gcloud container images list-tags gcr.io/${PROJECT_ID}/コンテナ名

## gcr.io AR リポジトリのコンテナ tag 一覧
gcloud artifacts docker tags list us-docker.pkg.dev/${PROJECT_ID}/gcr.io/コンテナ名

## gcr.io AR リポジトリのコンテナ hash 一覧
gcloud artifacts versions list --project=${PROJECT_ID} --repository=gcr.io --location=us --package=コンテナ名
asia.gcr.io リポジトリの確認手順
## asia.gcr.io リポジトリのコンテナ一覧
gcloud container images list --repository=asia.gcr.io/${PROJECT_ID}

## asia.gcr.io リポジトリのコンテナ tag 一覧
gcloud container images list-tags asia.gcr.io/${PROJECT_ID}/コンテナ名

## asia.gcr.io AR リポジトリのコンテナの tag 一覧
gcloud artifacts docker tags list asia-docker.pkg.dev/${PROJECT_ID}/asia.gcr.io/コンテナ名

## asia.gcr.io AR リポジトリのコンテナ hash 一覧
gcloud artifacts versions list --project=${PROJECT_ID} --repository=asia.gcr.io --location=asia --package=コンテナ名
eu.gcr.io リポジトリの確認手順
## eu.gcr.io リポジトリのコンテナ一覧
gcloud container images list --repository=eu.gcr.io/${PROJECT_ID}

## eu.gcr.io リポジトリのコンテナ tag 一覧
gcloud container images list-tags eu.gcr.io/${PROJECT_ID}/コンテナ名

## eu.gcr.io AR リポジトリのコンテナの tag 一覧
gcloud artifacts docker tags list europe-docker.pkg.dev/${PROJECT_ID}/eu.gcr.io/コンテナ名

## eu.gcr.io AR リポジトリのコンテナ hash 一覧
gcloud artifacts versions list --project=${PROJECT_ID} --repository=eu.gcr.io --location=europe --package=コンテナ名
us.gcr.io リポジトリの確認手順
## us.gcr.io リポジトリのコンテナ一覧
gcloud container images list --repository=us.gcr.io/${PROJECT_ID}

## us.gcr.io リポジトリのコンテナ tag 一覧
gcloud container images list-tags us.gcr.io/${PROJECT_ID}/コンテナ名

## us.gcr.io AR リポジトリのコンテナの tag 一覧
gcloud artifacts docker tags list us-docker.pkg.dev/${PROJECT_ID}/us.gcr.io/コンテナ名

## us.gcr.io AR リポジトリのコンテナ hash 一覧
gcloud artifacts versions list --project=${PROJECT_ID} --repository=us.gcr.io --location=us --package=コンテナ名

gcloud container images list-tags コマンドは、タグなしのコンテナイメージのハッシュも一緒に出力されますが、 gcloud artifacts docker tags list コマンドはタグありのコンテナイメージのみが出力されるため、タグなしイメージの確認を厳密に行いたい場合は gcloud artifacts versions list コマンドも併用する必要がありました。

gcr.io のルーティングを切り替える

無事に gcrane によるコンテナイメージコピーに問題ないことが確認できましたら、 gcr.io ドメインのルーティングを変更します。

作業に必要なロール付与を実施

移行コマンドに必要な権限として、 以下の 2 つのロールが必要になります。

  • Artifact Registry リポジトリ管理者 (roles/artifactregistry.repoAdmin)
  • ストレージ管理者 (roles/storage.admin)

プロジェクトオーナーロールが付与されている場合、上記ロールの権限はオーナーロールが包含しているはずですが、 Dry Run コマンドを実行した際に権限検証エラーになるようです。

Web コンソールの「IAM と管理」>「IAM」のページから上記ロールを付与するか、または、下記コマンドを実行してロールを付与します。

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member=PRINCIPAL \
    --role=roles/artifactregistry.repoAdmin

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member=PRINCIPAL \
    --role=roles/storage.admin

PRINCIPALuser:GoogleアカウントserviceAccount:サービスアカウント といったアカウント指定の文字列

リダイレクト有効前の検証

ロール付与後、下記コマンドを gcr.io のルーティングの切替前の検証を実行します。

gcloud artifacts settings enable-upgrade-redirection --project=${PROJECT_ID} --dry-run

特に問題無ければ以下のようなメッセージが出力されます。

Performing redirection enablement checks...

Redirection enablement report:

Container Registry Host: gcr.io
Location: us
Artifact Registry Repository: projects/PROJECT_ID/locations/us/repositories/gcr.io

Container Registry Host: us.gcr.io
Location: us
Artifact Registry Repository: projects/PROJECT_ID/locations/us/repositories/us.gcr.io

Container Registry Host: asia.gcr.io
Location: asia
Artifact Registry Repository: projects/PROJECT_ID/locations/asia/repositories/asia.gcr.io

Container Registry Host: eu.gcr.io
Location: europe
Artifact Registry Repository: projects/PROJECT_ID/locations/europe/repositories/eu.gcr.io

Dry run enabled, no changes made.

権限が不足している場合は、以下のようなエラーメッセージが出力されます。

Performing redirection enablement checks...

FAIL: This operation requires the storage.buckets.update permission(s) on project PROJECT_ID

エラーメッセージが出力された場合は、内容を確認し、公式ドキュメントに記載されている内容を確認しましょう。

リダイレクトを有効にする

検証コマンドで問題がなければ、下記のコマンドを実行します。

gcloud artifacts settings enable-upgrade-redirection --project=${PROJECT_ID}

以下のようなメッセージが出力されます。最終確認として y を入力してエンターを押すと、リダイレクトが有効になります。

OK: All Container Registry repositories have equivalent Artifact Registry repostories.


This action will redirect all Container Registry traffic to Artifact Registry for project PROJECT_ID. After enabling redirection,
you can route traffic back to Container Registry if needed.

Do you want to continue (y/N)?  y

legacyRedirectionState: REDIRECTION_FROM_GCR_IO_ENABLED
name: projects/PROJECT_ID/projectSettings

リダイレクトを有効にすると、Web コンソールの Artifact Registry リポジトリ一覧の画面は以下のようになります。
リポジトリに表示されていた ⚠ マークが消え、「すべての「*gcr.io」のトラフィックは Artifact Registry にルーティングされます。」というメッセージが表示されるようになっています。

Artifact Registry リポジトリ一覧画面

切り戻しを行う場合

リダイレクト有効後は gcr.io のバックエンドは Cloud Storage ではなく Artifact Registry リポジトリになり、アクセスログ等も Artifact Registry のログを参照することになります。
切替後にイメージの Pull や Push に問題が発生した場合、切り戻しを行うのではなく、Artifact Registry 監査ログのデータアクセス監査ログを有効化してエラー原因を調査し、必要な権限を付与する等の方法をとるべきです。
ただし、運用上復旧を優先する必要が有る場合は、下記のコマンドを実行することでリダイレクト設定を戻すことが可能です。

gcloud artifacts settings disable-upgrade-redirection --project=${PROJECT_ID}

上記コマンドを実行すると、Cloud Storage のコンテナイメージを参照する元の動作に戻ります。

権限付与のクリーンアップ

切替作業が完了しましたら、作業アカウントに付与していた下記のロールは削除しておきましょう。

  • Artifact Registry リポジトリ管理者 (roles/artifactregistry.repoAdmin)
  • ストレージ管理者 (roles/storage.admin)

不要バケットの削除

CR から AR に移行してある程度の期間問題が出なければ、古いバケットは削除した方がよいでしょう。(Cloud Storage の保管費用が余計にかかってしまうため)
バケット削除の手順は公式ドキュメントに記載されています。

なお、バケットを削除すると移行前のデータは復旧できませんので、慎重に行いましょう。

まとめ

Container Registry の廃止と Artifact Registry の移行方法について解説しました。
gcr.io ドメインのルーティングによる移行であれば、既存のシステム影響も最小限に抑えることが可能ですので、こうした移行措置を活用しつつ Container Registry の廃止に備えましょう。

Discussion