创建自定义构建步骤

编写构建配置时,您可以使用 Cloud Build 提供的受支持的开源构建步骤,也可以自行定义自定义构建步骤

自定义构建步骤是 Cloud Build 工作器虚拟机拉取并与装载到 /workspace 的源卷一起运行的容器映像。自定义构建步骤可以在容器内执行任何脚本或二进制文件;因此,该步骤可以执行的操作与容器完全相同。

自定义构建步骤对以下操作非常有用:

  • 从外部位置下载源代码或程序包
  • 使用外部工具链
  • 缓存任何必要的库
  • 预构建源(Cloud Build 仅负责在可能的情况下将构建封装到容器映像中)

自定义构建步骤与装载在 /workspace 下的源代码一起运行,并与 /workspace 中某个位置的工作目录一起运行。由给定构建步骤保留在 /workspace 中的任何文件都可用于其他构建步骤,无论这些步骤是并发运行还是随后运行。

自定义构建步骤可以推送到您的构建器服务帐号有权访问的 Google Container Registry 代码库(托管在 gcr.io/$PROJECT-NAME/ 上),也可以从该代码库中拉取自定义构建步骤。docker 命令行工具凭据不足以提供对 Docker Hub 的经身份验证的访问权限。

本指南举例说明如何创建执行 shell 脚本的构建步骤,借此说明创建自定义构建步骤的方式。您可以将“shell 脚本执行程序”创建为自定义构建步骤,用以从构建源中的某个位置执行 shell 脚本。

创建自定义构建步骤

要创建自定义构建步骤,您可以创建构建配置文件,该文件可构建并将构建步骤映像推送到构建器服务帐号可以访问的映像注册表(例如 Container Registry)。或者,您可以使用其他工具构建自定义构建步骤映像,然后将其存储在映像注册表中。该操作完成后,您可以在将来的构建中调用自定义构建步骤。

关于 entrypoint 字段

映像的 Dockerfile 可能包含一个 ENTRYPOINT 和/或 CMD 字段。如果容器要作为可执行文件运行,则 ENTRYPOINT 会指定用于自定义构建步骤的入口点。CMD 为执行提供默认值,如果省略 ENTRYPOINT,则应包含可执行文件。

在构建配置中,可选 entrypoint 字段定义构建步骤被调用时的运行方式。例如,您可以指定应该在构建步骤运行时调用的主命令:docker 构建步骤的入口点是 "/usr/bin/docker"。在之后的构建中使用构建步骤时,可通过在该构建中指定 entrypoint 来替换 Dockerfile ENTRYPOINT

如果您未在构建步骤的构建请求文件中指定 entrypoint 字段,并且构建步骤的映像未在其 Dockerfile 中指定 ENTRYPOINT,则 args 中的第一项将用作入口点,args 中的其余项将用作参数。

示例:从源执行 shell 脚本

如果某个自定义构建步骤要从源执行 shell 脚本,该步骤的容器映像必须包含能够运行该脚本的工具。ubuntudebianalpine 等标准基础映像和 busybox 容器映像都可以运行脚本,但是 alpinebusybox 映像未预装 bash(因此无法运行 bash 脚本),而 ubuntudebian 进行了预装。

如果某映像包含您运行脚本所需的所有工具(包括 shell),则可以直接将该映像用作构建步骤。

此示例使用 ubuntu 映像来运行脚本,因为该映像预封装有 bash 并支持许多开发者工具。构建本身基于 alpine 创建映像;此类映像要小得多,并且只包含运行时环境所需的内容。

以下是自定义构建步骤的示例 ./cloudbuild.yaml 配置文件:

steps:
- name: 'ubuntu'
  args: ['bash', './myscript.bash']
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/custom-script-test', '.']
images: ['gcr.io/$PROJECT_ID/custom-script-test']

该步骤运行下面名为 ./myscript.bash 的脚本:

echo "Hello, world!" > file.txt

以下是示例 Dockerfile

FROM alpine
COPY file.txt /file.txt
ENTRYPOINT ["cat", "/file.txt"]

要提交使用此自定义构建步骤的构建,请在 shell 或终端窗口中运行以下命令:

$ gcloud builds submit --config cloudbuild.yaml .
...
$ gcloud docker -- pull gcr.io/<your-project-id>/custom-script-test
...
$ docker run gcr.io/<your-project-id>/custom-script-test
Hello, world!

相对于此示例中所使用的 alpine 基础映像中提供的资源,自定义构建步骤运行的脚本可能需要更多资源。如果是这种情况,您可以使用 Dockerfile 中的 COPY 指令预构建一个包含必要资源的映像,以将资源从工作区添加到容器映像中。

例如,假设您要运行一个脚本,该脚本使用 curl 拉取一个文件并将其包含在构建的映像中。由于 ubuntu 映像未预封装 curl 命令行工具,我们将使用 ubuntu 基础映像和位于其上的 curl 创建一个新映像。

以下是一个使用自定义 ubuntu-curl 构建步骤的示例 ./cloudbuild.yaml 构建配置文件:

steps:
- name: 'gcr.io/$PROJECT_ID/ubuntu-curl'
  args: ['bash', './curl.bash']
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/custom-script-test2', '.']
images: ['gcr.io/$PROJECT_ID/custom-script-test2']

安装 curl 工具的 Dockerfile.ubuntu-curl

FROM ubuntu
RUN apt-get -q update && apt-get install -qqy curl

./curl.bash 脚本可能类似于以下内容:

#!/bin/bash
curl http://example.com > example.html

示例 Dockerfile

FROM alpine
COPY example.html /example.html
ENTRYPOINT ["cat", "/example.html"]

如需为 ubuntu-curl 运行自定义构建步骤,然后构建映像,请在 shell 或终端窗口中运行以下命令:

# First, build and push the `ubuntu-curl` custom build step.
$ docker build -f Dockerfile.ubuntu-curl -t gcr.io/your-project/ubuntu-curl .
...
$ gcloud docker -- push gcr.io/your-project/ubuntu-curl
...

将使用 Dockerfile.ubuntu-curl 创建的映像推送到 Docker 注册表后,您可以直接将该映像用作构建步骤。

# Then, use the custom `ubuntu-curl` build step in a new build.
$ gcloud builds submit --config cloudbuild.yaml .
...
$ gcloud docker -- pull gcr.io/your-project/custom-script-test2
...
$ docker run gcr.io/your-project/custom-script-test2
`<`contents of example.com source`>`

您可以通过添加初步步骤来构建脚本执行程序映像,从而在一个构建中完成相同的操作。构建完该映像后,可将其用作构建中的下一个步骤。这样做的好处是可以保持 curl.bash 整洁,并在 Cloud Build 服务中执行大部分工作。

下面是添加了初步步骤的示例 ./cloudbuild.yaml 配置文件:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-f', 'Dockerfile.ubuntu-curl', '-t', 'script-runner', '.']
- name: 'script-runner'
  args: ['bash', './curl.bash']
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/custom-script-test2', '.']
images: ['gcr.io/$PROJECT_ID/custom-script-test2']

只要您将 script-runner 置于 cloudbuild.yaml 中的 images 字段之外,Cloud Build 服务就不会尝试推送它(在本示例中将会失败)。但在构建环境中,script-runner 映像将存在于映像缓存中并且可用作构建步骤。

后续步骤