与 Docker Hub 映像交互

您可以使用 Docker Hub 中的容器映像在 Cloud Build 中执行任务。此外,如果您的构建生成了映像,您可以将它们推送到 Docker Hub。本页面介绍如何编写用于推送和拉取 Docker Hub 映像的构建配置文件。如需大致了解构建配置文件中的所有可用字段,请参阅构建配置概览

从 Docker Hub 拉取公共映像

您可以在构建步骤中拉取 Docker 官方映像Docker 认证映像和存储在 Docker Hub 中的自定义映像,方法是在 name 字段中指定映像的名称。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,Cloud Build 需要使用您的凭据向 Docker 进行身份验证。如需在构建中包含 Docker 凭据,您必须先将凭据存储在 Secret Manager 中,然后为 Cloud Build 授予从 Secret Manager 访问 Secret 的权限。

如需将 Docker 凭据存储在 Secret Manager 中,请执行以下操作:

  1. 进入 Google Cloud 控制台中的 Secret Manager 页面:

    转到 Secret Manager 页面

  2. Secret Manager 页面上,点击创建密钥

  3. 创建密钥页面的名称下,输入 docker-username

  4. Secret 值字段中,输入您的 Docker 用户名。

  5. 保持区域部分不变。

  6. 点击创建密钥按钮。

重复执行上述步骤,将您的 Docker 密码存储在 Secret Manager 中。

如需向用于构建的服务帐号授予 Secret 的 Secret Manager Secret Accessor IAM 角色,请执行以下操作:

  1. 在 Google Cloud 控制台中打开 Secret Manager 页面:

    转到 Secret Manager 页面

  2. 选中与您的 Docker 用户名和密码对应的 Secret 的复选框。

  3. 如果面板尚未打开,请点击显示信息面板将其打开。

  4. 在面板中的权限下,点击添加主账号

  5. 新的主帐号字段中,输入服务帐号的电子邮件地址。

  6. 选择角色下拉框中,选择 Secret Manager Secret Accessor 角色。

  7. 点击保存

从 Docker Hub 中拉取私有映像

如需从 Docker Hub 中拉取私有映像,请执行以下操作:

  1. 确保您已将 Docker 凭据存储在 Secret Manager 中,并已为 Cloud Build 授予访问 Secret 的权限

  2. 在构建配置文件中:

    • 在完成所有构建 steps 后,添加 availableSecrets 字段以指定用于 Docker 用户名和密码的 Secret 版本和环境变量。
    • 在您要指定用户名和密码的构建步骤中:
      • 添加指向 bashentrypoint 字段,以在构建步骤中使用 bash 工具。这是引用 Secret 的环境变量所必需的。
      • 添加 secretEnv 字段以指定用户名和密码的环境变量。
      • args 字段中,添加 -c 标志作为第一个参数。您在 -c 之后传递的任何字符串均被视为命令。如需详细了解如何使用 -c 运行 bash 命令,请参阅 bash 文档
      • args 字段中指定 Secret 时,请使用前缀为 $$.

    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'
     的环境变量指定 Secret。
    

    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:您存储 Secret 的 Google Cloud 项目的 ID。
    • DOCKER_USERNAME_SECRET_NAME:与您的 Docker 用户名对应的 Secret 名称。
    • DOCKER_USERNAME_SECRET_VERSION:您的 Docker 用户名的 Secret 版本。
    • DOCKER_PASSWORD_SECRET_NAME:与您的 Docker 密码对应的 Secret 名称。
    • DOCKER_PASSWORD_SECRET_VERSION:您的 Docker 密码的 Secret 版本。
    • 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 构建步骤中将 -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"
      ],
  }
  ...
}

后续步骤