コンテナ イメージのビルド

このページでは、Docker イメージをビルドして格納するように Cloud Build を構成する方法について説明します。Cloud Build を初めて使用する場合は、最初にクイックスタートビルド構成の概要をご覧ください。

Cloud Build には、事前にビルドされたイメージが用意されています。このイメージを Cloud Build 構成ファイルで参照してタスクを実行できます。これらのイメージは Google Cloudでサポートされ、管理されています。サポートされているビルド済みの Docker イメージを使用して Docker コマンドを実行し、Docker イメージをビルドできます。

準備

このページの説明は、Docker の知識があることを前提としています。次の特長があります。

  • アプリケーションのソースコードと Dockerfile を同じ場所に置きます。
  • Artifact Registry にイメージを保存する Docker リポジトリがあるか、新しいリポジトリを作成します。
  • このページの gcloud コマンドを使用する場合は、Google Cloud CLI をインストールします。
  • イメージを実行する場合は、Docker をインストールします
  • cosign を使用してイメージに署名する場合は、サービス間アクセスの承認の手順に沿ってユーザー指定のサービス アカウントを作成し、ID トークンの生成に必要な権限を付与します。

ビルド構成ファイルを使用してビルドする

ビルド構成ファイルを使用して Docker イメージをビルドするには、次のことを行います。

  1. アプリケーションのソースコード が含まれているディレクトリに、cloudbuild.yaml または cloudbuild.json という名前でファイルを作成します。
  2. ビルド構成ファイルで、次のことを行います。

    • name フィールドを追加し、事前にビルドされている Docker イメージを指定します。事前にビルドされたイメージは gcr.io/cloud-builders/docker に保存されます。以下の構成ファイルの例では、name フィールドは、args フィールドで示されるタスクを実行するために、ビルド済みの Docker イメージを Cloud Build が使用することを指定します。
    • args フィールドに引数を追加してイメージをビルドします。

      YAML

      steps: - name: 'gcr.io/cloud-builders/docker'   args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ] 

      JSON

      {  "steps": [   {       "name": "gcr.io/cloud-builders/docker",       "args": [         "build",         "-t",         "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",         "."        ]    }    ]  } 

      上記のビルド構成のプレースホルダ値を次のように置き換えます。

    • LOCATION: Artifact Registry 内の Docker リポジトリのリージョンまたはマルチリージョンのロケーション。

    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。

    • REPOSITORY: Artifact Registry の Docker リポジトリの名前。

    • IMAGE_NAME: コンテナ イメージの名前。

      Dockerfile とソースコードが異なるディレクトリにある場合、-fDockerfile へのパスを args フィールドの引数リストに追加します。

      YAML

      steps: - name: 'gcr.io/cloud-builders/docker'   args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '-f', 'DOCKERFILE_PATH', '.' ] 

      JSON

      {  "steps": [   {       "name": "gcr.io/cloud-builders/docker",       "args": [         "build",         "-t",         "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", '-f', 'DOCKERFILE_PATH', "."        ]    }    ]  } 

      上記のビルド構成のプレースホルダ値を次のように置き換えます。

      • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
      • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
      • REPOSITORY: Artifact Registry リポジトリの名前
      • IMAGE_NAME: コンテナ イメージの名前。
      • DOCKERFILE_PATH: Dockerfile へのパス。
  3. ビルド構成ファイルを使用してビルドを開始します。

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY 

    上記のコマンドのプレースホルダ値を次のように置き換えます。

    • CONFIG_FILE_PATH: ビルド構成ファイルのパス。
    • SOURCE_DIRECTORY: ソースコードのパスまたは URL。

    gcloud builds submit コマンドに CONFIG_FILE_PATHSOURCE_DIRECTORY を指定しないと、Cloud Build は、構成ファイルとソースコードが現在の作業ディレクトリにあることを前提とします。

Dockerfile を使用してビルドする

Cloud Build では、Dockerfile のみを使用して Docker イメージをビルドできます。個別のビルド構成ファイルは不要です。

Dockerfile を使用してビルドするには、ソースコードと Dockerfile が格納されているディレクトリから次のコマンドを実行します。

    gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME 

上記のコマンドのプレースホルダ値を次のように置き換えます。

  • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
  • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
  • REPOSITORY: Artifact Registry リポジトリの名前
  • IMAGE_NAME: コンテナ イメージの名前。

Google Cloud の Buildpacks を使用してビルドする

Cloud Build では、Dockerfile やビルド構成ファイルを使用せずにイメージをビルドできます。これは、Google Cloud の Buildpacks を使用して行うことができます。

Buildpacks を使用してビルドするには、ソースコードが格納されているディレクトリから次のコマンドを実行します。

    gcloud builds submit --pack builder=BUILDPACK_BUILDER, \         env=ENVIRONMENT_VARIABLE, \         image=IMAGE_NAME 

上記のコマンドのプレースホルダ値を次のように置き換えます。

  • BUILDPACK_BUILDER: 使用する buildpacks ビルダー。ビルダーを指定しない場合、Cloud Build はデフォルトで gcr.io/buildpacks/builder を使用します。
  • ENVIRONMENT_VARIABLE: ビルドの環境変数。
  • IMAGE: Artifact Registry のイメージの URL。イメージの URL は LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME の形式である必要があります。

次にコマンドの例を示します。

  • デフォルトの gcr.io/buildpacks/builder を使用してビルドを実行し、イメージ us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app を作成します。

      gcloud builds submit --pack image=us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app 
  • 区切り文字に ^--^ を使用して、複数の環境変数をビルドに渡します。引数のエスケープについての詳細は、gcloud topic escaping をご覧ください。

      gcloud builds submit --pack \       ^--^image=gcr.io/my-project/myimage--env=GOOGLE_ENTRYPOINT='java -jar target/myjar.jar',GOOGLE_RUNTIME_VERSION='3.1.301' 

Buildpacks を使用するようにトリガーを構成する: コマンドラインを使用してビルドするだけでなく、Buildpacks を使用してイメージを自動的にビルドするようにトリガーを構成できます。詳しくは、ビルドトリガーの作成と管理をご覧ください。

Artifact Registry にイメージを保存するさまざまな方法

ビルド済みのイメージを次のいずれかの方法で格納するように Cloud Build を構成できます。

  • images フィールドを使用する。ビルドが完了した後、Artifact Registry にイメージを格納します。
  • docker push コマンドを使用する。ビルドフローの中で Artifact Registry にイメージを格納します。

images フィールドを使用した場合と Docker push コマンドを使用した場合の違いは、images フィールドを使用した場合、保存されたイメージがビルド結果に表示されることです。たとえば、Google Cloud コンソールのビルドの [ビルドの説明] ページや、Build.get() の結果、gcloud builds list の結果に表示されます。一方、Docker push コマンドを使用してビルドされたイメージを保存すると、イメージはビルド結果に表示されません。

ビルドフローの中でイメージを保存し、ビルドの結果にイメージを表示する場合は、ビルド構成ファイルで Docker の push コマンドと images フィールドの両方を使用します。

ビルドの完了後に Artifact Registry にコンテナ イメージを格納するには次のことを行います

  1. ターゲット リポジトリが存在しない場合は、新しいリポジトリを作成します
  2. アプリケーションのソースコードと Dockerfile が含まれているディレクトリに、cloudbuild.yaml または cloudbuild.json という名前でファイルを作成します。
  3. ビルド構成ファイルに、イメージをビルドするビルドステップを追加して、images フィールドを追加してビルドイメージを指定します。これにより、Artifact Registry にイメージが格納されます。以下のスニペットは、イメージをビルドして Artifact Registry に格納するビルド構成を示しています。

    YAML

    steps: - name: 'gcr.io/cloud-builders/docker'   args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ] images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'] 

    JSON

    { "steps": [ {     "name": "gcr.io/cloud-builders/docker",     "args": [         "build",         "-t",         "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",         "."     ] } ], "images": [     "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME" ] } 

    ここで

    • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • REPOSITORY: Artifact Registry リポジトリの名前
    • IMAGE_NAME: コンテナ イメージの名前。
  4. ビルド構成ファイルを使用してビルドを開始します。

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY 

    ここで

    • CONFIG_FILE_PATH は、ビルド構成ファイルへのパスです。
    • SOURCE_DIRECTORY は、ソースコードへのパスまたは URL です。

ビルドフローの中で Artifact Registry にイメージを格納するには次のことを行います

  1. アプリケーションのソースコードと Dockerfile が含まれているディレクトリに、cloudbuild.yaml または cloudbuild.json という名前でファイルを作成します。

  2. ビルド構成ファイルで、イメージをビルドする docker ビルドステップを追加します。さらに、別の docker ビルドステップを追加して引数を渡し、push コマンドを呼び出します。

    YAML

    steps: - name: 'gcr.io/cloud-builders/docker'   args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.'] - name: 'gcr.io/cloud-builders/docker'   args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'] 

    JSON

    {   "steps": [    {       "name": "gcr.io/cloud-builders/docker",       "args": [           "build",           "-t",           "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",           "."        ]    },    {        "name": "gcr.io/cloud-builders/docker",        "args": [           "push",           "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"         ]    }   ] } 

    ここで

    • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • REPOSITORY: Artifact Registry リポジトリの名前
    • IMAGE_NAME: コンテナ イメージの名前。
  3. ビルド構成ファイルを使用してビルドを開始します。

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY 

    ここで

    • CONFIG_FILE_PATH は、ビルド構成ファイルへのパスです。
    • SOURCE_DIRECTORY は、ソースコードへのパスまたは URL です。

ビルドフローの中でイメージを格納し、ビルド結果にイメージを表示するには次のことを行います

  1. アプリケーションのソースコードと Dockerfile が含まれているディレクトリに、cloudbuild.yaml または cloudbuild.json という名前でファイルを作成します。
  2. ビルド構成ファイルで、push コマンドを呼び出す Docker 起動ステップをイメージのビルドステップの後に追加し、images フィールドを追加します

    YAML

    steps: - name: 'gcr.io/cloud-builders/docker'   args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.'] - name: 'gcr.io/cloud-builders/docker'   args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'] images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'] 

    JSON

    {     "steps": [    {        "name": "gcr.io/cloud-builders/docker",        "args": [            "build",            "-t",            "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",            "."         ]    },    {        "name": "gcr.io/cloud-builders/docker",        "args": [            "push",            "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"         ]    }    ],     "images": [        "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"     ] } 

    ここで

    • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • REPOSITORY: Artifact Registry リポジトリの名前
    • IMAGE_NAME: コンテナ イメージの名前。
  3. ビルド構成ファイルを使用してビルドを開始します。

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY 

    ここで

    • CONFIG_FILE_PATH は、ビルド構成ファイルへのパスです。
    • SOURCE_DIRECTORY は、ソースコードへのパスまたは URL です。

cosign を使用してコンテナ イメージに署名する

Artifact Registry にイメージを保存している場合は、cosign ツールを使用してビルドの開始に使用するサービス アカウントの記録を作成することで、別のセキュリティ レイヤを追加できます。OpenID Connect(OIDC)標準に基づく監査者は、その記録を使用してイメージが信頼できるサービス アカウントによってビルドされていることを確認できます。

以下の手順では、cloudbuild.yaml 構成ファイルを使用して ID トークンを取得し、コンテナ イメージに署名する方法を示します。

YAML

  steps:   - name: 'gcr.io/cloud-builders/docker'     id: 'tag-and-push'     script: |       #!/bin/sh       set -e       docker build -t $_IMAGE .       docker push "$_IMAGE"       docker inspect $_IMAGE --format "$_IMAGE@{{.Id}}" >image_with_digest   - name: 'gcr.io/cloud-builders/gcloud'     id: 'generate-token'     script: |       #!/bin/sh       set -e       gcloud auth print-identity-token --audiences=sigstore > token   - name: 'gcr.io/cloud-builders/docker'     id: 'sign-image'     script: |       #!/bin/sh       set -e       docker run \       --network=cloudbuild \       --mount source=home-volume,target=/builder/home \       --rm \       -e SIGSTORE_NO_CACHE=true \       -e HOME=/builder/home \       gcr.io/projectsigstore/cosign \       sign --identity-token=$(cat token) $(cat image_with_digest) -y   service_account: '$_SERVICE_ACCOUNT'   artifacts:     images:     - $_IMAGE   substitutions:     _IMAGE: 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'     _SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'     _SERVICE_ACCOUNT: projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}   options:     env:     - '_IMAGE=$_IMAGE'     dynamic_substitutions: true     logging: CLOUD_LOGGING_ONLY 

JSON

    {         "steps": [             {                 "name": "gcr.io/cloud-builders/docker",                 "id": "tag-and-push",                 "script": "#!/bin/sh set -e \ndocker build -t $_IMAGE . \ndocker push \"$_IMAGE\""             },             {                 "name": "gcr.io/cloud-builders/gcloud",                 "id": "generate-token-and-get-digest",                 "script": "#!/bin/sh set -e \ngcloud auth print-identity-token --audiences=sigstore > token \ngcloud container images describe \"$_IMAGE\" --format=\"value(image_summary.fully_qualified_digest)\" > image_with_digest"             },             {                 "name": "gcr.io/projectsigstore/cosign",                 "id": "sign-image",                 "script": "#!/busybox/sh cosign sign --identity-token=$(cat token) $(cat image_with_digest) -y",                 "env": [                     "SIGSTORE_NO_CACHE=true"                 ]             }         ],         "service_account": "$_SERVICE_ACCOUNT",         "artifacts": {             "images": [                 "$_IMAGE"             ]         },         "substitutions": {             "_IMAGE": "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",             "_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",             "_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"         },         "options": {             "env": [                 "_IMAGE=$_IMAGE"             ],             "dynamic_substitutions": true,             "logging": "CLOUD_LOGGING_ONLY"         }     } 

ここで

  • LOCATION は、イメージが保存されているリポジトリのリージョンまたはマルチリージョンのロケーションus-east1us など)です。

  • PROJECT_ID: 実際の Google Cloud プロジェクト ID。

  • REPOSITORY は、イメージが保存されるリポジトリの名前です。

  • IMAGE_NAME はイメージの名前です。

  • SERVICE_ACCOUNT_ID は、ビルドを実行するユーザー指定のサービス アカウントのメールアドレスです。たとえば、サービス アカウントのメールアドレスは次のようになります。[email protected]

署名を確認するには、ローカルマシンに cosign をインストールして cosign verify コマンドを実行します。

cosign verify \ --certificate-identity=SERVICE_ACCOUNT_ID \ --certificate-oidc-issuer=https://accounts.google.com \ IMAGE 

ここで

  • SERVICE_ACCOUNT_ID は、コンテナ イメージのビルドに使用されたと思われる信頼できるサービス アカウントのメールアドレスです。
  • IMAGE は、sha256 イメージ ダイジェストを含む完全なイメージ名です。

Docker イメージを実行する

ビルドしたイメージが想定どおりに動作することを確認するため、Docker を使用してイメージを実行できます。

  1. Artifact Registry を操作するときに Artifact Registry 認証情報を使用するように Docker を構成します。(この操作は初回のみ必要です。)gcloud 認証ヘルパーを使用して認証を行うには、次のコマンドを使用します。

    gcloud auth configure-docker HOSTNAME-LIST 

    HOSTNAME-LIST は、認証ヘルパー構成に追加するリポジトリ ホスト名のカンマ区切りのリストです。

    たとえば、リージョン us-central1asia-northeast1 を追加する場合には、次のコマンドを実行します。

    gcloud auth configure-docker us-central1-docker.pkg.dev,asia-northeast1-docker.pkg.dev 
  2. 前にビルドした Docker イメージを実行します。

    docker run LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME 

    ここで

    • LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • REPOSITORY: Artifact Registry リポジトリの名前
    • IMAGE_NAME: コンテナ イメージの名前。

    出力は次のようになります。

    Hello, world! The time is Fri Feb  2 16:09:54 UTC 2018. 

次のステップ