🧑‍🎓

Google Cloud 入門:Artifact Registry ハンズオン

2024/10/31に公開

概要

Google Cloud の Artifact Registry を初めて使う人に向けて、次のような基本的な使い方をまとめた。

  • 事前作業(Artifact Registry 認証情報の設定など)
  • リポジトリの作成
  • イメージの保存
  • イメージの取得

Artifact Registryとは

Artifact Registry は、パッケージと Docker コンテナイメージを 1 か所で保管し管理できるサービス。
パッケージとは、JavaパッケージやNode.jsパッケージなど様々なものがサポートされている(参考:サポートされている形式)。

使用例としては、CDパイプラインでビルドした Dockerイメージを Artifact Registry に保存しておき、デプロイやロールバック時に保存したイメージをダウンロードする、といった具合。

事前作業

※既に実施済みの作業はスキップしてください。

Docker Desktop インストール

Docker Desktop for Macには「Intel chip版」と「Apple chip(Apple Silicon)版」の2種類がある。
公式サイトを開き、自分のマシンに合った方をインストールし起動する。

gcloud CLI セットアップ

公式ドキュメントの内容を実施する。ポイントは次の通り。

  • gcloudコマンドがインストールされていない場合、公式ドキュメントにあるリンクからダウンロードして ./google-cloud-sdk/install.shを実行する。

  • gcloud init を実行し gcloud CLI を初期化する。

    • Google アカウントへのログインを求められるのでイメージの pull/push 権限を含む roles/artifactregistry.writer ロールを付与したアカウントでログインする(必要な権限の詳細については Artifact Registry の事前定義ロール を参考)。
  • gcloud config list を実行して、以下のように accountproject が設定されていることを確認する。

$ gcloud config list
[core]
account = {使用するアカウントのメールアドレス}
disable_usage_reporting = True
project = {プロジェクトID}

Your active configuration is: [default]

Artifact Registry 認証情報の設定

Dockerイメージをレジストリ(≒イメージの保管場所)に保存するには docker pushコマンド、レジストリからイメージを取得するには docker pull コマンドを実行する。
このレジストリに当たるものが Artifact Registry であり、今回は非公開のリポジトリを使用するため、認証されたユーザで権限を持ったユーザしかアクセスできないものとなる。

非公開の Artifact Registry リポジトリにアクセスするには、gcloud 認証情報ヘルパーを使って次のコマンドを実行する。

gcloud auth configure-docker {HOSTNAME-LIST}

HOSTNAME-LIST は認証ヘルパー構成に追加する Artifact Registry のリポジトリホスト名のカンマ区切りのリスト。
例えばリージョン asia-northeast1 を追加する場合には、gcloud auth configure-docker asia-northeast1-docker.pkg.dev のコマンドを実行する。

その後、gcloud auth login を実行してユーザ認証を行う。

リポジトリの作成

リポジトリの作成を行うアカウントは、roles/artifactregistry.admin ロールを付与したものを使用する。
Google Cloud コンソール画面で作成するには、「Artifact Registry」へ移動し「リポジトリを作成」をクリックする。
必要事項を次の図のように入力して作成すると、リポジトリが作られる。

  • 形式

    • Dockerイメージを保存するため Docker を選択。
  • モード

    • リポジトリのモードには3種類ある(参考:リポジトリモード)。
    • 標準モードは限定公開用のリポジトリであり、これがデフォルトである。
  • ロケーションタイプ

    • 単一リージョンで他の Google Cloud サービスと同じリージョンにリポジトリを作成すると、レイテンシと下り(外向き)ネットワークの費用が削減される。
    • 一方、複数のリージョンにわたる冗長性による高可用性を期待する場合は、マルチリージョンを使用する。
    • 参考:リポジトリの場所Artifact Registry ロケーション
  • ラベル

    • ラベルは、Google Cloud Repository に割り当てることができる Key-Value ペア。請求料金をラベル別に分類することができる(参考:リポジトリにラベルを付ける)。
  • クリーンアップポリシー(任意項目)
    • クリーンアップポリシーは、不要になったバージョンを自動的に削除する削除ポリシーと、無期限に保持するための条件を定義する保持ポリシーがある(参考:クリーンアップポリシークリーンアップポリシーの設定)。
    • 削除ポリシーと保持ポリシーの両方を作成した場合、両方の条件に一致する時には保持ポリシーが適用される。
    • よく使いそうなポリシーを次のように設定した。保持期間や保持数については用途に合わせて要調整。

keep-latest

タグがついているバージョンに対して、prefix が latest のものを保持するポリシー。
例えばアプリケーションの最新版イメージに latest タグを付けておくと、最新版イメージを保持することができる。

keep-minimum-versions

最新バージョンを2つまで保持するポリシー。
直近でリリースしたいくつかのバージョンを残しておき、ロールバックなどに使用する。

delete-no-tag

タグがついていないバージョンに対し、1日以上経過したら削除するポリシー。
「アップロード後の期間(最小)」という表現がピンと来づらいが、アップロードしてから指定期間を経過したバージョンが対象になると考えれば良い。

delete-old-image

タグがついているバージョンに対し、2日以上経過したら削除するポリシー。

Terraform を使う場合

Google Cloud コンソールではなく Terraform を使ってリポジトリを作成する場合、次のようなコードになる。(参考:Artifact Registry の Terraform ベースのガイド

resource "google_artifact_registry_repository" "sample_repo" {
  provider               = google-beta
  project                = "sample-project-id"
  location               = "asia-northeast1"
  repository_id          = "sample-repo"
  description            = "ハンズオン用のリポジトリ"
  format                 = "DOCKER"
  mode                   = "STANDARD_REPOSITORY"
  cleanup_policy_dry_run = false
  cleanup_policies {
    id     = "keep-latest"
    action = "KEEP"
    condition {
      tag_state = "TAGGED"
      tag_prefixes = ["latest"]
    }
  }
  cleanup_policies {
    id     = "keep-minimum-versions"
    action = "KEEP"
    most_recent_versions {
      keep_count = 10
    }
  }
  cleanup_policies {
    id     = "delete-no-tag"
    action = "DELETE"
    condition {
      older_than = "86400s" # 1日
      tag_state = "UNTAGGED"
    }
  }
  cleanup_policies {
    id     = "delete-old-image"
    action = "DELETE"
    condition {
      older_than = "604800s" # 7日
      tag_state = "ANY"
    }
  }
  labels = {
    "env"     = "production"
    "project" = "sample-project"
  }
}

イメージのpush

上記で作成したリポジトリにイメージを保存する作業を行う。
イメージを push するには Artifact Registry 書き込み(roles/artifactregistry.writer)権限を持ったアカウントで実施する。

今回保存するイメージは、hello-world イメージを元にしたものを使用する。
hello-world イメージを起動すると、次のように Hello World が出力される。

$ docker pull hello-world:latest
latest: Pulling from library/hello-world
c1ec31eb5944: Already exists 
Digest: sha256:d211f485f2dd1dee407a80973c8f129f00d54604d2c90732e8e320e5038a0348
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

$ docker run hello-world

Hello from Docker!
...

hello-world イメージを元にして、asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latestイメージに latestタグを付ける。

$ docker tag hello-world:latest asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest

docker pushコマンドでイメージをリポジトリに保存する。

$ docker push asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest

これでリポジトリにイメージが保存された。

イメージの pull

今度は上記で保存したイメージを取得する作業を行う。
イメージを pull するには Artifact Registry 読み取り(roles/artifactregistry.reader)権限を持ったアカウントで実施する。

まずはローカルに保存されているイメージを削除しておく。

$ docker rmi asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest

// イメージがローカルに無いことを確認する
$ docker images asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

リポジトリからイメージを pull して、上手くいけばイメージがローカルにダウンロードされる。

$ docker pull asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest
Using default tag: latest
latest: Pulling from sample-project-id/sample-repo/hello-world
Digest: sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7
Status: Downloaded newer image for asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest
asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest

// イメージがローカルに有ることを確認する
$ docker images asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest
REPOSITORY                                                                            TAG       IMAGE ID       CREATED         SIZE
asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world              latest    d2c94e258dcb   17 months ago   13.3kB

ローカルイメージを使ってコンテナを起動すると、Hello Worldが出力される。

$ docker run asia-northeast1-docker.pkg.dev/sample-project-id/sample-repo/hello-world:latest

Hello from Docker!
...

クリーンアップポリシーの動作確認

上記で作成したリポジトリのクリーンアップポリシーの動作について、具体例を用いて確認する。
作成したポリシーは、保持ポリシーが2つと削除ポリシーが2つ。

イメージが次のようにリポジトリにアップロードされている時、クリーンアップポリシーの働きによって何が削除され、何が保持されるのかを把握する。

アップロード後、1日以上2日未満経過した時点

削除ポリシー「delete-no-tag」により、タグなしイメージ efcb0ba2504a が削除された。

アップロード後、2日以上経過した時点

削除ポリシー「delete-old-image」により2日経過したタグ付きイメージが削除されるが、保持ポリシー「keep-minimum-versions」により直近のバージョンである 280af83742aca051f8bcd171 は保持され、adb041199c3f のみが削除される。

料金

アーティファクトを保存するリポジトリには、次の料金が適用される(料金の概要)。

  • 保存容量
    • 0.5GB/月までは無料。それを超えると $0.10/GB
  • データ転送
    • 同じロケーション内のデータの移動は無料
  • 脆弱性スキャン
    • 有効になっており、リポジトリでサポートされている場合

参考

Discussion