操作 Docker Hub 映像檔

您可以使用 Docker Hub 中的容器映像檔,在 Cloud Build 中執行工作。此外,如果建構作業會產生映像檔,您可以將這些映像檔推送至 Docker Hub。本頁說明如何編寫建構設定檔,以推送及提取 Docker Hub 映像檔。如要查看版本設定檔中所有可用欄位的總覽,請參閱「版本設定總覽」。

從 Docker Hub 提取公開映像檔

您可以在建構步驟中,透過在 name 欄位中指定映像檔名稱,提取官方 Docker 映像檔Docker 認證映像檔,以及儲存在 Docker Hub 中的自訂映像檔。Cloud Build 會先從 Docker Hub 提取指定的映像檔,然後使用該映像檔執行建構步驟。

在下列範例中,Cloud Build 會提取 maven 的 Docker 映像檔,以執行 args 中指定的 mvn 指令:

YAML

steps:
- name: "maven"
  args: ["mvn", "--version"]

JSON

{
   "steps": [
      {
         "name": "maven",
         "args": [
            "mvn",
            "--version"
         ]
      }
   ]
}

在 Secret Manager 中儲存 Docker 憑證

如要從 Docker Hub 提取私人映像檔,以及向 Docker Hub 推送公開和私人映像檔,Cloud Build 必須使用您的憑證向 Docker 進行驗證。如要在建構作業中加入 Docker 憑證,請先將憑證儲存於 Secret Manager,然後授予 Cloud Build 權限,允許其從 Secret Manager 存取密鑰。

如要在 Secret Manager 中儲存 Docker 憑證,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的 Secret Manager 頁面:

    前往 Secret Manager 頁面

  2. 在「Secret Manager」(密鑰管理工具) 頁面中,按一下「Create Secret」(建立密鑰)

  3. 在「建立密鑰」頁面的「名稱」下方,輸入 docker-username

  4. 在「Secret value」(密鑰值) 欄位中輸入 Docker 使用者名稱。

  5. 請勿變更「區域」部分。

  6. 按一下「Create secret」(建立密鑰) 按鈕。

重複上述步驟,將 Docker 密碼儲存在 Secret Manager 中。

如要將密鑰的 Secret Manager 密鑰存取者身分與存取權管理角色授予用於建構的服務帳戶:

  1. 在 Google Cloud 控制台中開啟「Secret Manager」頁面:

    前往 Secret Manager 頁面

  2. 勾選與 Docker 使用者名稱和密碼對應的密碼核取方塊。

  3. 如果面板尚未開啟,請按一下「顯示資訊面板」開啟面板。

  4. 在面板的「權限」下方,按一下「新增主體」

  5. 在「New principals」(新增主體) 欄位中,輸入服務帳戶的電子郵件地址。

  6. 在「Select a role」(選取角色) 下拉式方塊中,選取「Secret Manager Secret Accessor」(Secret Manager 密碼存取者) 角色。

  7. 按一下 [儲存]

從 Docker Hub 提取私人映像檔

如要從 Docker Hub 提取私人映像檔,請按照下列步驟操作:

  1. 請確認您已將 Docker 憑證儲存在 Secret Manager 中,並授予 Cloud Build 存取密鑰的權限

  2. 在建構設定檔中:

    • 在所有建構 steps 完成後,請新增 availableSecrets 欄位,指定 Docker 使用者名稱和密碼的密碼版本和環境變數。
    • 在要指定使用者名稱和密碼的建構步驟中:
      • 新增指向 bashentrypoint 欄位,即可在建構步驟中使用 bash 工具。這是參照密鑰環境變數的必要條件。
      • 新增 secretEnv 欄位,指定使用者名稱和密碼的環境變數。
      • args 欄位中,新增 -c 標記做為第一個引數。系統會將 -c 後方傳遞的任何字串視為指令。如要進一步瞭解如何使用 -c 執行 bash 指令,請參閱 bash 說明文件
      • args 欄位中指定密鑰時,請使用以 $$.

    The following build config file shows how to login to Docker using the Docker username and password stored in Secret Manager, and run a private image.

    YAML

     steps:
     - name: 'gcr.io/cloud-builders/docker'
       entrypoint: 'bash'
       args: ['-c', 'docker login --username=$$USERNAME --password=$$PASSWORD']
       secretEnv: ['USERNAME', 'PASSWORD']
     - name: "gcr.io/cloud-builders/docker"
       entrypoint: 'bash'
       args: ['-c', 'docker run $$USERNAME/REPOSITORY:TAG']
       secretEnv: ['USERNAME']
     availableSecrets:
       secretManager:
       - versionName: projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION
         env: 'PASSWORD'
       - versionName: projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION
         env: 'USERNAME'
     為前置字元的環境變數指定密鑰
    

    JSON

    {
      "steps": [
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker login --username=$$USERNAME --password=$$PASSWORD"
        ],
        "secretEnv": [
          "USERNAME",
          "PASSWORD"
        ]
      },
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker run $$USERNAME/REPOSITORY:TAG"
         ],
         "secretEnv": [
          "USERNAME"
        ]
      }
      ],
      "availableSecrets": {
        "secretManager": [{
          "versionName": "projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION",
          "env": "PASSWORD"
      }, {
        "versionName": "projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION",
        "env": "USERNAME"
         }]
      }
    }
    

    Replace the placeholder values in the above commands with the following:

    • PROJECT_ID: The ID of the Google Cloud project where you've stored your secrets.
    • DOCKER_USERNAME_SECRET_NAME: The secret name corresponding to your Docker username.
    • DOCKER_USERNAME_SECRET_VERSION: The secret version of your Docker username.
    • DOCKER_PASSWORD_SECRET_NAME: The secret name corresponding to your Docker password.
    • DOCKER_PASSWORD_SECRET_VERSION: The secret version of your Docker password.
    • REPOSITORY: The name of your Docker repository from where you're pulling the image.
    • TAG: The tag name of your image.
  3. Use the build config file to manually start a build or to automate builds using triggers.

Pushing images to Docker Hub

To push public and private images to Docker Hub:

  1. Make sure you've stored your Docker credentials in Secret Manager and granted permissions for Cloud Build to access the secret.

  2. In the build config file:

    • After all the build steps, add an availableSecrets field specifying the secret version and the env variable for the Docker username and password.
    • In the build step where you want to specify the username and password:
      • Add an entrypoint field pointing to bash to use the bash tool in the build step. This is required to refer to the environment variable for the secret.
      • Add a secretEnv field specifying the environment variable for username and password.
      • In the args field, add a -c flag as the first argument. Any string you pass after -c is treated as a command. For more information on running bash commands with -c, see the bash documentation.
      • When specifying the secret in the args field, specify it using the environment variable prefixed with $$.

    The following example build config file shows how to login to Docker, build an image with source code stored locally, and then push the image to Docker repository.

    YAML

     steps:
     - name: 'gcr.io/cloud-builders/docker'
       entrypoint: 'bash'
       args: ['-c', 'docker login --username=$$USERNAME --password=$$PASSWORD']
       secretEnv: ['USERNAME', 'PASSWORD']
     - name: 'gcr.io/cloud-builders/docker'
       entrypoint: 'bash'
       args: ['-c', 'docker build -t $$USERNAME/REPOSITORY:TAG .']
       secretEnv: ['USERNAME']
     - name: 'gcr.io/cloud-builders/docker'
       entrypoint: 'bash'
       args: ['-c', 'docker push $$USERNAME/REPOSITORY:TAG']
       secretEnv: ['USERNAME']
     availableSecrets:
       secretManager:
       - versionName: projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION
         env: 'PASSWORD'
       - versionName: projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION
         env: 'USERNAME'
    

    JSON

    {
      "steps": [
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker login --username=$$USERNAME --password=$$PASSWORD"
        ],
        "secretEnv": [
          "USERNAME",
          "PASSWORD"
        ]
      },
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker build -t $$USERNAME/REPOSITORY:TAG ."
         ],
         "secretEnv": [
          "USERNAME"
        ]
      },
      {
        "name": "gcr.io/cloud-builders/docker",
        "entrypoint": "bash",
        "args": [
          "-c",
          "docker push $$USERNAME/REPOSITORY:TAG"
         ],
         "secretEnv": [
          "USERNAME"
        ]
      }
      ],
      "availableSecrets": {
        "secretManager": [{
          "versionName": "projects/PROJECT_ID/secrets/DOCKER_PASSWORD_SECRET_NAME/versions/DOCKER_PASSWORD_SECRET_VERSION",
          "env": "PASSWORD"
      }, {
        "versionName": "projects/PROJECT_ID/secrets/DOCKER_USERNAME_SECRET_NAME/versions/DOCKER_USERNAME_SECRET_VERSION",
        "env": "USERNAME"
         }]
      }
    }
    

    將上述指令中的預留位置值替換為下列值:

    • PROJECT_ID:儲存密鑰的 Google Cloud 專案 ID。
    • DOCKER_USERNAME_SECRET_NAME:與 Docker 使用者名稱對應的密鑰名稱。
    • DOCKER_USERNAME_SECRET_VERSION:Docker 使用者名稱的密鑰版本。
    • DOCKER_PASSWORD_SECRET_NAME:對應 Docker 密碼的密鑰名稱。
    • DOCKER_PASSWORD_SECRET_VERSION:Docker 密碼的密鑰版本。
    • REPOSITORY:要將映像檔推送至的 Docker 存放區名稱。
    • TAG:圖片的標記名稱。
  3. 使用建構設定檔手動啟動建構,或使用觸發條件自動建構

使用 Docker 用戶端版本

Cloud Build 支援的 Docker 建構工具 gcr.io/cloud-builders/docker 使用的是 Docker 20.10.14。在這個版本中,如果將映像檔推送至 Docker 時未指定標記,Docker 只會推送具有 latest 標記的映像檔。如果 latest 標記不存在,推送就會失敗。

如要將具有特定標記的映像檔推送至 Docker,請在 docker push 建構步驟中指定標記。以下範例會推送標記為 prod 的圖片:

YAML

steps:
...
- name: 'gcr.io/cloud-builders/docker'
  args: ['docker', 'push', '$$USERNAME/myrepo:prod']
...

JSON

{
  ...
  {
    "name": "gcr.io/cloud-builders/docker",
    "args": [
      "docker",
      "push", 
      "$$USERNAME/myrepo:prod"
      ],
  }
  ...
}

如要將映像檔的所有標記推送至 Docker,請在 docker push 建構步驟的 args 清單中新增 -a 旗標:

YAML

steps:
...
- name: 'gcr.io/cloud-builders/docker'
  args: ['docker', 'push', '-a', '$$USERNAME/myrepo']
...

JSON

{
  ...
  {
    "name": "gcr.io/cloud-builders/docker",
    "args": [
      "docker",
      "push",
      "-a",
      "$$USERNAME/myrepo"
      ],
  }
  ...
}

您可以在 Docker 建構工具中標記版本,使用 Docker 用戶端 19.03.9:

YAML

steps:
...
- name: 'gcr.io/cloud-builders/docker:19.03.9'
  args: ['docker', 'push', '$$USERNAME/myrepo:prod']
...

JSON

{
  ...
  {
    "name": "gcr.io/cloud-builders/docker:19.03.9",
    "args": [
      "docker",
      "push",
      "$$USERNAME/myrepo:prod"
      ],
  }
  ...
}

後續步驟