Google Cloud でのビルドやデプロイのための変更

このドキュメントでは、Cloud Build でコンテナ イメージをビルドして、Cloud Run や Google Kubernetes Engine などの Google Cloud ランタイム環境にデプロイする際の Container Registry と Artifact Registry の違いについて説明します。

このガイドでは、標準 Artifact Registry リポジトリに重点を置いて比較しています。このリポジトリは Container Registry から独立しており、Artifact Registry のすべての機能をサポートしています。管理者が gcr.io ドメインをサポートするリポジトリを設定している場合は、gcr.io ホスト名へのリクエストは対応する Artifact Registry リポジトリに自動的にリダイレクトされ、Container Registry にアクセスできるデフォルト サービス アカウントには、Artifact Registry に対する同等のデフォルトの権限があります。

Docker クライアントを使用する場合の Container Registry と Artifact Registry の違いについては、Docker を使用した push と pull の変更をご覧ください。

この情報は、Cloud Build で Container Registry に関連する既存のコマンド、構成、ドキュメントを作成する際に役立ちます。

始める前に

このドキュメントは、次のものがあることを前提としています。

  1. プロジェクトで Artifact Registry を有効にしている
  2. Artifact Registry で使用している他の Google Cloud サービスの Cloud Build API と API を有効にしている。

ワークフローを変更する

同じプロジェクト内の Container Registry で Cloud Build を使用する場合、ワークフローは次のようになります。

  1. Cloud Build で、Dockerfile またはビルド構成ファイルを使用して、イメージのビルド、タグ付け、リポジトリへの push を行います。

    次の例では、イメージ my-image をビルドして tag1 でタグ付けし、プロジェクト my-project のホスト gcr.io に push します。

    gcloud builds submit --tag gcr.io/my-project/my-image:tag1
    
  2. Cloud Run や Google Kubernetes Engine などの Google Cloud ランタイム環境では、レジストリからイメージを pull します。

    たとえば、次のコマンドでは、前のステップのイメージを my-service として Cloud Run にデプロイします。

    gcloud run deploy my-service --image gcr.io/my-project/my-image:tag1
    

Container Registry ワークフローは、管理者の責任とビルドとデプロイを組み合わせたものです。

  • 一部の Google Cloud API を有効にすると、Container Registry API が自動的に有効になります。つまり、これらのサービスのユーザーは、同じプロジェクト内の Container Registry に暗黙的にアクセスできます。たとえば、Cloud Build でビルドを実行できるユーザーは、デフォルトでイメージをレジストリに push し、レジストリホストを追加できます。
  • Cloud Build サービス アカウントには、Cloud Storage ストレージ バケットを作成する権限があります。つまり、アカウントは、ホストに初めてイメージを push したときに、Container Registry ホストをプロジェクトに自動的に追加できます。つまり、Container Registry で使用されていないバケットを含め、プロジェクト全体でストレージ バケットの作成、読み取り、書き込みを行うことができます。

Artifact Registry では、ビルドとデプロイのワークフローの手順を変更する管理者とビルドのロールが明確に分離されています。Container Registry のワークフローを Artifact Registry に適応させるには、次の変更を行います。各ステップは、ワークフローの変更に関する追加情報にリンクしています。

  1. 新規: Artifact Registry API を有効にします。

    Artifact Registry API を有効にする必要があります。Cloud Build や、Cloud Run や GKE などのランタイム環境では、API が自動的に有効になりません。

  2. 新規: ターゲット Docker リポジトリがまだ存在しない場合は、それを作成します。イメージを push する前に、リポジトリを作成する必要があります。イメージを push してもリポジトリの作成をトリガーできません。Cloud Build サービス アカウントにはリポジトリを作成する権限がありません。

  3. 変更済み: Dockerfile またはビルド構成ファイルを使用して、Cloud Build がリポジトリにイメージをビルド、タグ付け、push します。

    次のコマンド例は、Container Registry の例と同じですが、イメージに Artifact Registry リポジトリ パスを使用しています。

    gcloud builds submit --tag us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1
    
  4. 変更: イメージを Google Cloud ランタイム環境(Cloud Run や GKE など)にデプロイします。

    次のコマンド例は、Container Registry の例と同じですが、イメージに Artifact Registry リポジトリ パスを使用しています。

    gcloud run deploy my-service --image us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1
    

また、Artifact Registry は Container Registry とは異なるロールを使用してイメージへのアクセスを制御します。次のような状況では、権限を構成する必要があります。

  • Cloud Build または Google Cloud のランタイム環境が、Artifact Registry とは異なるプロジェクトにある。
  • デフォルトのサービス アカウントの代わりに、Cloud Build や GKE などの Google Cloud サービス用のカスタム サービス アカウントを使用します。
  • 他のユーザーまたはサービス アカウントに権限を付与しました。

API の有効化

要点:

次の比較では、各サービスで API を有効にする方法を説明します。

Container Registry

次の Google Cloud API を有効にすると、Container Registry API も自動的に有効になります。

  • App Engine フレキシブル環境
  • Cloud Build
  • Cloud Functions
  • Cloud Run
  • Artifact Analysis のコンテナ スキャンまたはオンデマンド スキャン
  • Google Kubernetes Engine(GKE)

デフォルトの権限では、レジストリが同じプロジェクトにある場合、Cloud Build でビルドを実行したり、Artifact Analysis を使用してコンテナをスキャンしたり、コンテナを Google Cloud ランタイムにデプロイしたりできるユーザーは、Container Registry 内のイメージに明示的にアクセスできます。

Artifact Registry

Artifact Registry API を有効にする必要があります。Cloud Build、Cloud Run、GKE などのサービスでは、Artifact Registry API は自動的に有効になりません。

gcloud を使用して、同じプロジェクト内の複数の API を有効にできます。たとえば、Cloud Build API と Artifact Registry API を有効にするには、次のコマンドを実行します。

gcloud services enable
    artifactregistry.googleapis.com \
    cloudbuild.googleapis.com

レジストリとリポジトリの追加

要点:

  • イメージを push する前に、Artifact Registry Docker リポジトリを作成する必要があります。
  • Container Registry では、すべてのイメージを同じストレージ バケットの 1 つのマルチリージョンに保存します。Artifact Registry では、同じアクセス ポリシーを使用して、同じリージョンまたはマルチリージョンに複数のリポジトリを作成できます。

次の比較では、各サービスでのリポジトリの設定について説明します。

Container Registry

Container Registry では、プロジェクトに最大 4 つのレジストリホストを追加できます。最初のイメージを push して、レジストリホストを追加します。

  1. gcr.io などのレジストリをプロジェクトに追加するには、プロジェクト レベルでストレージ管理者のロールを持つアカウントが初期イメージを push します。

    たとえば、gcr.io ホストがプロジェクト my-project に存在しない場合は、イメージ gcr.io/my-project/my-image:1.0 を push すると次の手順がトリガーされます。

    1. gcr.io ホストをプロジェクトに追加する
    2. プロジェクトで gcr.io のストレージ バケットを作成します。
    3. イメージを gcr.io/my-project/my-image:1.0 として保存する
  2. 最初に push した後、Storage バケットに別のユーザーの権限を付与できます。

デフォルトでは、Cloud Build にはストレージ バケットの作成に必要な権限があるため、最初のイメージの push と後続の push は区別できません。

プロジェクト内では、レジストリホストがすべてのイメージを同じストレージ バケットに保存します。次の例では、プロジェクト my-project のレジストリ gcr.ioweb-app という 2 つのイメージがあります。1 つはプロジェクト ID my-project の直下にあります。もう 1 つのイメージはリポジトリ team1 にあります。

gcr.io/my-project/web-app
gcr.io/my-project/team1/web-app

Artifact Registry

Cloud Build には、Artifact Registry の pkg.dev ドメインに標準リポジトリを作成する権限がありません。

Artifact Registry リポジトリ管理者のロールを持つアカウントは、イメージを push する前にリポジトリを作成する必要があります。その後、リポジトリの他のユーザーに権限を付与できます。

Artifact Registry では、各リポジトリは別々のリソースです。したがって、すべてのイメージパスにリポジトリを含める必要があります。

有効なイメージパス:

us-central1-docker.pkg.dev/my-project/team1/web-app:1.0
us-central1-docker.pkg.dev/my-project/team2/web-app:1.0

無効なイメージパス(リポジトリは含まれません):

us-central1-docker.pkg.dev/my-project/web-app:1.0

次の例は、不明なリポジトリへのイメージの push が失敗する状況を示しています。

  • us-central1-docker.pkg.dev/my-project/team1 が存在しない場合、イメージを us-central1-docker.pkg.dev/my-project/team1 に push します。
  • us-central1-docker.pkg.dev/my-project/team1 が存在しても us-central1-docker.pkg.dev/my-project/team2 が存在しない場合は、イメージを us-central1-docker.pkg.dev/my-project/team2 に push します。

権限の付与

要点:

  • Google Cloud サービスには、Container Registry と Artifact Registry の両方に対する同等の読み取りまたは書き込みアクセス権があります。ただし、デフォルトの Cloud Build サービス アカウントは、pkg.dev ドメインに標準リポジトリを作成することはできません。
  • Artifact Registry にアクセスする他のアカウントに、適切な Artifact Registry のロールを付与します。
  • Container Registry では、ストレージ バケット レベルでのアクセス制御がサポートされています。Artifact Registry は、リポジトリ レベルでのアクセス制御をサポートしています。

次の比較では、各サービスの権限について説明します。

Container Registry

Container Registry では、Cloud Storage のロールを使用してアクセスを制御します。Cloud Build には、Container Registry ホストをプロジェクトに追加するために必要なストレージ管理者ロールの権限が必要です。

ストレージ バケット レベルのストレージ オブジェクト閲覧者
プロジェクト内の既存のレジストリ ホストからイメージを pull(読み取り)します。
ストレージ バケットレベルでのストレージのレガシー バケット書き込み
プロジェクト内の既存のレジストリ ホストのイメージを push(書き込み)および pull(読み取り)します。
プロジェクト レベルのストレージ管理者
ホストに初期イメージを push して、レジストリ ホストをプロジェクトに追加します。

最初のイメージをレジストリに push したら、ストレージ バケットへのアクセスが必要な他のアカウントに Cloud Storage のロールを付与します。ストレージ管理者のロールのすべての権限を持つアカウントは、プロジェクト全体でストレージ バケットとストレージ オブジェクトの読み取り、書き込み、削除を行うことができます。

ストレージ バケットに対する権限は、レジストリ内のすべてのリポジトリに適用されます。たとえば、gcr.io/my-project のバケットに対するストレージ オブジェクト閲覧者権限を持つユーザーは、これらすべてのリポジトリのイメージを読み取ることができます。

gcr.io/my-project/team1
gcr.io/my-project/team2
gcr.io/my-project/test
gcr.io/my-project/production

Artifact Registry

Artifact Registry には、アクセスを制御する独自のロールがあります。これらのロールは、管理者とリポジトリのユーザーロールを明確に区別します。

Cloud Build は、pkg.dev ドメインの標準リポジトリでイメージを push および pull することのみを必要とするため、Artifact Registry の書き込みロールの権限が付与されています。

リポジトリを管理するアカウントのみに、Artifact Registry リポジトリ管理者または Artifact Registry 管理者のロールが必要です。

Artifact Registry 読み取り
アーティファクトとリポジトリを一覧表示します。アーティファクトをダウンロードします。
Artifact Registry 書き込み
アーティファクトとリポジトリを一覧表示します。アーティファクトのダウンロード、新しいアーティファクト バージョンのアップロード、タグの追加や更新を行います。
Artifact Registry リポジトリ管理者
Artifact Registry の書き込み権限とアーティファクトとタグを削除する権限。
Artifact Registry 管理者
Artifact Registry リポジトリ管理者の権限と、リポジトリの作成、更新、削除、権限の付与。

これらの権限は、リポジトリ レベルで適用できます。次に例を示します。

  • us-central1-docker.pkg.dev/my-project/team1 のチーム 1 にアクセス権を付与します。
  • us-central1-docker.pkg.dev/my-project/team2 のチーム 2 にアクセス権を付与します。

Artifact Registry 権限の付与については、アクセス制御のドキュメントをご覧ください。

イメージのビルドと push

要点:

  • イメージを push する前に、Artifact Registry Docker リポジトリを作成する必要があります。
  • Artifact Registry のホスト名は Container Registry のホスト名とは異なります。

Cloud Build は、1 ステップでイメージのビルド、タグ付け、push を行うことができます。

Container Registry を使用すると、Cloud Build は Google Cloud プロジェクトに存在しないレジストリホストにイメージを push できます。この最初のイメージの push では、Cloud Build には、レジストリホストをプロジェクトに自動的に追加する権限があります。

Container Registry ワークフローを適応させるには:

  1. イメージを push する前にリポジトリを設定します。
  2. またはビルド構成ファイルまたは gcloud builds submit コマンドでイメージパスを更新します。

ビルド構成ファイルによるビルド

ビルドするイメージの Container Registry パスを既存の Artifact Registry リポジトリへのパスに置き換えます。

次の cloudbuild.yaml ファイルの例では、イメージ us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1 をビルドします。

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', 'us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1', '.' ]
images:
- 'us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1'

次のコマンドを使用して、イメージをビルドできます。

gcloud builds submit --config cloudbuild.yaml

Dockerfile によるビルド

ビルドするイメージの Container Registry パスを既存の Artifact Registry リポジトリへのパスに置き換えます。

次のコマンドの例では、現在のディレクトリで Dockerfile を使用して、イメージ us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1 をビルドします。

gcloud builds submit --tag us-central1-docker.pkg.dev/my-project/my-repo/my-image:tag1

イメージのデプロイ

キーポイント:

  • Artifact Registry のホスト名は Container Registry のホスト名とは異なります。

Container Registry ワークフローを適応させるには、デプロイ構成とデプロイ コマンドのイメージパスを更新します。以降のセクションでは、Cloud Build、Cloud Run、GKE の例を示しますが、イメージをデプロイする他の Google Cloud サービスにも同じ手法が適用されます。

Cloud Build

デプロイするイメージの Container Registry パスを、既存の Artifact Registry リポジトリへのパスで置き換えます。

次のサンプル cloudbuild.yaml ファイルは、サンプル イメージ us-docker.pkg.dev/cloudrun/container/hello をデプロイします。

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  args:
  - 'run'
  - 'deploy'
  - 'cloudrunservice'
  - '--image'
  - 'us-docker.pkg.dev/cloudrun/container/hello'
  - '--region'
  - 'us-central1'
  - '--platform'
  - 'managed'
  - '--allow-unauthenticated'

Cloud Run

デプロイするイメージの Container Registry パスを、既存の Artifact Registry リポジトリへのパスで置き換えます。

たとえば、次のコマンドではサンプル イメージ us-docker.pkg.dev/cloudrun/container/hello をデプロイします。

gcloud run deploy my-service --image us-docker.pkg.dev/cloudrun/container/hello

GKE

ビルドするイメージの Container Registry パスを既存の Artifact Registry リポジトリへのパスに置き換えます。

Artifact Registry の例では、サンプル イメージ us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0 を使用しています。

コマンドラインからクラスタを作成します。

kubectl create deployment hello-server --image=us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0

デプロイ マニフェストでイメージを指定します。

In a deployment manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      run: my-app
  template:
    metadata:
      labels:
        run: my-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/artifact-registry-samples/containers/gke/hello-app:1.0