概要
2023 年 5 月 15 日より、Container Registry は非推奨となり、Artifact Registry への移行が推奨されています。
こちらの推奨に伴い、弊チームでも GKE にデプロイするイメージを Container Registry から Artifact Registry へ移行することになりました。
この記事では移行の際に詰まったポイントをまとめておきます。
結論
以下3つの対応をすればよい。
-
REGISTRY_URL
の記述方法を正しく設定する -
roles/artifactregistry.writer
の権限を付与する - リポジトリに対する認証を行う
Container Registry と Artifact Registry の違い
Container Registry では コンテナイメージのみが保存対象としてサポートされますが、Artifact Registry ではコンテナイメージだけでなく、言語パッケージ、OS パッケージもサポートされます。
Artifact Registry を利用することで Cloud Run でコンテナを利用せずにソースからサービスを稼働させたりもできるらしいです。(詳細)
やりたいこと
以下のようなイメージをビルドして Artifact Registry に登録し、GKE にデプロイするスクリプトを実行します。
set -e
SCRIPT_DIR=$(cd $(dirname $0) && pwd)
REGISTRY_IMAGE_PROJECT=sample_project
IMAGE_NAME=sample-api
REGISTRY_URL="asia-docker.pkg.dev/${REGISTRY_IMAGE_PROJECT}/${IMAGE_NAME}"
kubectl config use-context my-cluster-context
echo "kube_context=$(kubectl config current-context)"
set -x
# build image
docker build -t ${IMAGE_NAME}:latest .
gcloud auth configure-docker --quiet
docker tag ${IMAGE_NAME} ${REGISTRY_URL}:latest
docker push ${REGISTRY_URL}:latest
# deploy
kubectl set image -n sample-namespace deployment/${IMAGE_NAME} ${IMAGE_NAME}=${REGISTRY_URL}:latest --record
詰まったポイント1
上記のスクリプトを実行すると、以下のように REGISTRY_URL
の記述方法がよろしくないと怒られました。
name invalid: Missing image name. Pushes should be of the form docker push HOST-NAME/PROJECT-ID/REPOSITORY/IMAGE
Container Registry の場合は、gcr.io/${REGISTRY_IMAGE_PROJECT}/${IMAGE_NAME}
で push できたのですが、Artifact Registry では REPOSITORY
という階層が増え、asia-docker.pkg.dev/${REGISTRY_IMAGE_PROJECT}/${REPOSITORY_NAME}/${IMAGE_NAME}
としてあげる必要があるみたいです。
そこで、今回は REGISTRY_URL
に簡易的に /sample
という階層を増やしました。
...
REGISTRY_URL="asia-docker.pkg.dev/${REGISTRY_IMAGE_PROJECT}/${IMAGE_NAME}/sample"
...
詰まったポイント2
詰まったポイント1で修正したスクリプトを実行すると、次は以下のように権限まわりで怒られました。
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource "projects/xxxxxxxxxxxxxxxx" (or it may not exist)
使用している Service Account に Artifact Regitstry の書き込み権限が足りなかったためですね。言われた通り、roles/artifactregistry.writer
の権限を付与します。
詰まったポイント3
権限を付与して再度スクリプトを実行したのですが、再度同様に権限まわりで怒られました。
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource "projects/xxxxxxxxxxxxxxxx" (or it may not exist)
行き詰まったのでドキュメントに目を通してみると、以下の項目を発見。
リポジトリに対する認証
Docker リポジトリまたは Docker リポジトリで別のサードパーティ クライアントを使用する場合は、リポジトリに対して認証を行う必要があります。このセクションでは、認証に成功するために必要なことの概要を説明します。詳細な手順については、Docker の認証の設定をご覧ください。
認証情報ヘルパーの使用
gcloud CLI 認証ヘルパーまたはスタンドアロン認証情報ヘルパーの場合、使用する Artifact Registry ホストが Docker 構成ファイルに含まれている必要があります。
Artifact Registry では、すべてのレジストリ ホストが Docker 構成ファイルに自動的に追加されるわけではありません。構成されたレジストリが多い場合、Docker の応答時間が大幅に遅くなります。構成ファイル内のレジストリの数を最小限に抑えるには、必要なホストをファイルに追加します。
認証情報ヘルパーを利用して、リポジトリに対する認証が必要とのことです。
この観点は自分にはなかったので、ドキュメントを読んでなるほどなと思いました。
ホストを確認してみると、予想通り asia-docker.pkg.dev
が存在していませんでした。
cat ~/.docker/config.json
{
"credHelpers": {
"asia.gcr.io": "gcloud",
"eu.gcr.io": "gcloud",
"gcr.io": "gcloud",
"us.gcr.io": "gcloud"
}
}
認証情報ヘルパーを実行してホストを追加します。
gcloud auth configure-docker asia-docker.pkg.dev
再度スクリプトを実行すると、デプロイできました!!!
お疲れ様でした。