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 の変更をご覧ください。

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

始める前に

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

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

ワークフローを変更する

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

  1. Dockerfile またはビルド構成ファイルを使用して、Cloud Build でイメージをビルド、タグ付けし、リポジトリに 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. 変更: Cloud Run や GKE などの Google Cloud ランタイム環境にイメージをデプロイします。

    次のコマンドの例は 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 とは異なるプロジェクトにある。
  • Google Cloud サービス(Cloud Build や GKE など)には、デフォルトのサービス アカウントではなく、カスタム サービス アカウントを使用する。
  • 他のユーザーまたはサービス アカウントに権限を付与した。

API の有効化

要点:

次の比較では、サービスごとに API を有効にする方法を示しています。

Container Registry

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

  • App Engine フレキシブル環境
  • Cloud Build
  • Cloud Run 関数
  • 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 は、すべてのイメージを同じストレージ バケットの単一のマルチリージョンに保存します。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 の後、他のユーザーにストレージ バケットに対する権限を付与できます。

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

プロジェクト内では、レジストリ ホストがすべてのイメージを同じストレージ バケットに保存します。次の例では、プロジェクト my-project には、レジストリ gcr.io 内に web-app という 2 つのイメージがあります。1 つはプロジェクト ID my-project の直下にあります。もう一方の画像はリポジトリ 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 ホストをプロジェクトに追加するために必要な権限がストレージ管理者ロールに付与されています。

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

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

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

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 を使用すると、Google Cloud プロジェクトにまだ存在しないレジストリ ホストに Cloud Build でイメージを正常に 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