LoginSignup
6
2

Artifact RegistryのイメージをGKEにデプロイする際に詰まった話

Last updated at Posted at 2023-12-16

概要

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 にデプロイするスクリプトを実行します。

deploy.sh
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 という階層を増やしました。

deploy.sh
...
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

再度スクリプトを実行すると、デプロイできました!!!
お疲れ様でした。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2