Google Artifact RegistryのGKEイメージ操作

タグ操作

GKEで利用するイメージは一般的にタグを持ちます。ビルド時に省略した場合にはlatestが付いているケースが多いでしょう。
ビルドごとにlatestが指すイメージが変わり、旧latestはタグ無しになります。

イメージ実体は複数のタグを持つことが可能で、 gcloud artifacts docker tags addコマンドにより別のタグを追加できます。
たとえば、latestの指す実体が新イメージに差しかわった場合にも、別のタグがあれば引き続き分かりやすいURIでアクセスできます。

$ gcloud artifacts docker tags add \
    <REGION>-docker.pkg.dev/<PROJECT>/<REPO>/<IMAGE>:<ORIGINAL_TAG> \
    <REGION>-docker.pkg.dev/<PROJECT>/<REPO>/<IMAGE>:<NEW_TAG>

同様に、タグの確認には gcloud artifacts docker tags list、除去には gcloud artifacts docker tags deleteコマンドを使います。

イメージ削除

GKEなどのコンテナイメージのレジストリgcr.io(と地域バリアント)は基本的に古いイメージを削除しません。

イメージの削除は gcloud artifacts docker images deleteコマンドを用いて手動作業します。
(または Cloud ConsoleのArtifact Registry画面でイメージ選択して消す方法もあります)

ただし、意図したイメージを削除するには、挙動をよく理解する必要があります。

旧GoogleContainerRegistryの例

以下の情報は、旧GoogleContainerRegistryの実行例です。Artifact Registryでも同等の手順が必要ですが、互換性がないため別途検証が必要です。
たとえば、イメージ名を指定して実行する方法は一見標準的な使い方に見えますが、latestタグのイメージを削除する挙動となり、多くのケースで一番不適な使い方となります。

$ gcloud container images delete gcr.io/<PROJECT_NAME>/<IMAGE_NAME>
WARNING: Implicit ":latest" tag specified: gcr.io/<PROJECT_NAME>/<IMAGE_NAME>
WARNING: Successfully resolved tag to sha256, but it is recommended to use sha256 directly.
Digests:
- gcr.io/<PROJECT_NAME>/<IMAGE_NAME>@sha256:015d97e86f5a02f115710610fd9e96956ba2018567421f86a438bf77e581b75a
  Associated tags:
 - latest
Tags:
- gcr.io/<PROJECT_NAME>/<IMAGE_NAME>:latest
This operation will delete the tags and images identified by the digests above.

Do you want to continue (Y/n)?

タグの無いイメージを削除するコマンド例

古いイメージはビルドの際にタグが除去されるため、list-tagsサブコマンドでタグ無しのイメージをフィルタすると、多くのケースで想定する古いイメージのリストを得られます。

公式リファレンスのコマンド例を参考に、bashのfor文と組み合わせた実行例は以下のようになります。

for d in $(gcloud container images list-tags gcr.io/<PROJECT_NAME>/<IMAGE_NAME> --filter='-tags:*'  --format="get(digest)"); do
  gcloud container images delete gcr.io/<PROJECT_NAME>/<IMAGE_NAME>@$d --quiet;
done

これにより、タグのあるイメージのみが残ります。
各イメージは共通するレイヤを共有していますが、クリーンアップ後に残ったイメージを適切に起動できたことから、レイヤの参照関係はgcloud container images deleteが解釈して適切に削除しているようです。

プロジェクト外のクラスタにアクセス許可する

ArtifactRegistryへのアクセスは、GCP IAMのサービスアカウントにroles/artifactregistry.readerを付与することで制御できます。
クレデンシャルをセットアップする手順は、 プライベートレジストリへのアクセス権を設定で解説しています。

GKEのクラスタの場合には、ノードプール作成時にサービスアカウントを選択しており、このアカウントがImagePull時にも使われます。
この点が分かりづらいのは、デフォルトのセットアップ手順では「ComputeEngineのデフォルトサービスアカウント」が選択されていて、サービスアカウントが機能している前提を意識しづらいからでしょう。

また、デフォルト設定でありながら ComputeEngineのアカウントは非推奨です。
公式ドキュメントの説明のとおり、新たにサービスアカウントを作成し、ノードプールに指定するとよりセキュアになります。なお、サービスアカウントはノードプール作成時にしか指定できないため、プールの再作成が必要です。

このようにノードプールにサービスアカウントを割り当てることで、GKEクラスタの権限をクラウドコンソールなどGCP IAM上で制御できます。
サービスアカウントはメールアドレスと同じ形式のIDを持っており、IAMにはプロジェクト外のアカウントIDを追加できます。

ArtifactRegistryのレポジトリがあるプロジェクトでroles/artifactregistry.readerを割り当てることで、プロジェクト外のGKEクラスタもコンテナイメージを利用できます。

中馬崇尋
Chuma Takahiro