建立容器映像檔

本頁說明如何設定 Cloud Build 以建構及儲存 Docker 映像檔。如果您是 Cloud Build 新手,請先參閱快速入門課程建構設定總覽

Cloud Build 提供預先建構的映像檔,您可以在 Cloud Build 設定檔中參照這些映像檔來執行工作。這些圖片由 Google Cloud支援及維護。您可以使用支援的預先建構 Docker 映像檔執行 Docker 指令並建構 Docker 映像檔。

事前準備

本頁面的操作說明假設您已熟悉 Docker。此外:

  • 請準備好應用程式原始碼和 Dockerfile
  • 您必須擁有 Docker 存放區,才能在 Artifact Registry 中儲存映像檔,或者建立新的存放區
  • 如要使用本頁中的 gcloud 指令,請安裝 Google Cloud CLI
  • 如要執行映像檔,請安裝 Docker
  • 如果您想使用共同簽署功能簽署圖片,請按照「授權服務對服務存取權」中的指示建立使用者指定的服務帳戶,並授予產生 ID 權杖所需的權限。

使用建構設定檔建構

如要使用建構設定檔建構 Docker 映像檔,請按照下列步驟操作:

  1. 在含有應用程式原始碼的同一個目錄中,建立名為 cloudbuild.yamlcloudbuild.json 的檔案。
  2. 在建構設定檔中:

    • 新增 name 欄位,並指定預先建構的 Docker 映像檔。預先建構的映像檔會儲存在 gcr.io/cloud-builders/docker 中。在以下設定檔範例中,name 欄位會指定 Cloud Build 使用預先建構的 Docker 映像檔,執行 args 欄位所指示的工作。
    • 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_PATHDockerfile 的路徑。
  3. 使用建構設定檔展開建構作業:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    請將上述指令中的預留位置值替換為以下內容:

    • CONFIG_FILE_PATH:建構設定檔的路徑。
    • SOURCE_DIRECTORY:原始碼的路徑或網址。

    如果您未在 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 執行這項操作。

如要使用 Buildpack 建構,請從含有原始碼的目錄執行下列指令:

    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 中的圖片網址。圖片網址格式必須為 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'
    

設定觸發條件以使用建構包:除了使用指令列建構外,您也可以設定觸發條件,以便使用建構包自動建構映像檔。詳情請參閱「建立及管理自動建構觸發條件」。

在 Artifact Registry 中儲存映像檔的不同方式

您可以設定 Cloud Build 以下列任一方式儲存建構的映像檔:

  • 使用 images 欄位,該欄位會在建構完成後將映像檔儲存至 Artifact Registry。
  • 使用 docker push 指令,將映像檔儲存在 Artifact Registry 中,做為建構流程的一部分。

使用 images 欄位與 Docker push 指令的區別在於,如果您使用 images 欄位,儲存的映像檔將顯示在建構結果中。這包括Google Cloud 主控台中建構項目的「Build description」頁面、Build.get() 的結果,以及 gcloud builds list 的結果。然而,如果您使用 Docker push 指令儲存建構的映像檔,映像檔將不會顯示在建構結果中。

如果您想將映像檔儲存為建構流程的一部分,並且想在建構結果中顯示映像檔,請在建構設定檔中使用 Docker push 指令和 images 欄位。

如要在建構完成後將容器映像檔儲存於 Artifact Registry

  1. 如果目標存放區不存在,請建立新的存放區
  2. 在含有應用程式來源程式碼和 Dockerfile 的目錄中,建立名為 cloudbuild.yamlcloudbuild.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 是原始碼的路徑或網址。

如要將映像檔儲存於 Artifact Registry,做為建構流程的一部分

  1. 在含有應用程式來源程式碼和 Dockerfile 的目錄中,建立名為 cloudbuild.yamlcloudbuild.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 是原始碼的路徑或網址。

如要將儲存映像檔做為建構流程的一部分,並於建構結果中顯示映像檔

  1. 在含有應用程式來源程式碼和 Dockerfile 的目錄中,建立名為 cloudbuild.yamlcloudbuild.json 的檔案。
  2. 在建構設定檔中,在建構映像檔的步驟之後,新增一個步驟來叫用 Docker push 指令,然後新增 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 是原始碼的路徑或網址。

使用 cosign 為容器映像檔簽署

如果您將映像檔儲存在 Artifact Registry 中,可以使用 cosign 工具,為啟動建構作業所使用的服務帳戶建立記錄,藉此增加一層安全防護。由於這項功能採用 OpenID Connect (OIDC) 標準,稽核人員可以利用這項記錄,驗證映像檔是由可信任的服務帳戶建構。

下列步驟說明如何使用 cloudbuild.yaml 設定檔取得身分驗證權杖,並為容器映像檔簽署。

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. 設定 Docker 在與 Artifact Registry 互動時使用 Artifact Registry 憑證。(您只需執行這項操作一次)。使用下列指令,透過 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.
    

後續步驟