×

构建触发器

在定义 `BuildConfig` 时,您可以定义触发器来控制应运行 `BuildConfig` 的情况。可以使用以下构建触发器:

  • Webhook

  • 镜像变更

  • 配置变更

Webhook 触发器

Webhook 触发器允许您通过向 OpenShift Dedicated API 端点发送请求来触发新的构建。您可以使用 GitHub、GitLab、Bitbucket 或通用 Webhook 定义这些触发器。

目前,OpenShift Dedicated Webhook 仅支持每个基于 Git 的源代码管理 (SCM) 系统的推送事件的类似版本。所有其他事件类型都将被忽略。

处理推送事件时,OpenShift Dedicated 控制平面主机将确认事件中的分支引用是否与相应 `BuildConfig` 中的分支引用匹配。如果是,则它会在 OpenShift Dedicated 构建上检出 Webhook 事件中记录的确切提交引用。如果它们不匹配,则不会触发任何构建。

`oc new-app` 和 `oc new-build` 会自动创建 GitHub 和通用 Webhook 触发器,但任何其他需要的 Webhook 触发器都必须手动添加。您可以通过设置触发器手动添加触发器。

对于所有 Webhook,您必须定义一个密钥名为 `WebHookSecretKey`、值为调用 Webhook 时要提供的值的密钥。然后,Webhook 定义必须引用该密钥。该密钥确保 URL 的唯一性,防止其他人触发构建。密钥的值将与 Webhook 调用期间提供的密钥进行比较。

例如,这是一个带有对名为 `mysecret` 的密钥的引用的 GitHub Webhook:

type: "GitHub"
github:
  secretReference:
    name: "mysecret"

然后,密钥定义如下。请注意,密钥的值是 base64 编码的,这是任何 `Secret` 对象的 `data` 字段的要求。

- kind: Secret
  apiVersion: v1
  metadata:
    name: mysecret
    creationTimestamp:
  data:
    WebHookSecretKey: c2VjcmV0dmFsdWUx

将未经身份验证的用户添加到 system:webhook 角色绑定

作为集群管理员,您可以将未经身份验证的用户添加到 OpenShift Dedicated 中特定命名空间的 `system:webhook` 角色绑定中。`system:webhook` 角色绑定允许用户从不使用 OpenShift Dedicated 身份验证机制的外部系统触发构建。默认情况下,未经身份验证的用户无权访问非公共角色绑定。这是 OpenShift Dedicated 4.16 之前版本的一个更改。

必须将未经身份验证的用户添加到 `system:webhook` 角色绑定才能成功从 GitHub、GitLab 和 Bitbucket 触发构建。

如果需要允许未经身份验证的用户访问集群,您可以通过将未经身份验证的用户添加到每个所需命名空间中的 `system:webhook` 角色绑定来实现此目的。此方法比将未经身份验证的用户添加到 `system:webhook` 集群角色绑定更安全。但是,如果您有很多命名空间,则可以将未经身份验证的用户添加到 `system:webhook` 集群角色绑定,这会将更改应用于所有命名空间。

修改未经身份验证的访问权限时,始终验证是否符合您组织的安全标准。

先决条件
  • 您有权访问集群,并且具有 `cluster-admin` 角色。

  • 您已安装 OpenShift CLI ( `oc` )。

步骤
  1. 创建一个名为 `add-webhooks-unauth.yaml` 的 YAML 文件,并添加以下内容:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      annotations:
        rbac.authorization.kubernetes.io/autoupdate: "true"
      name: webhook-access-unauthenticated
      namespace: <namespace> (1)
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: "system:webhook"
    subjects:
      - apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: "system:unauthenticated"
    1 您的 `BuildConfig` 的命名空间。
  2. 运行以下命令应用配置

    $ oc apply -f add-webhooks-unauth.yaml

使用 GitHub webhooks

GitHub webhooks 处理 GitHub 在仓库更新时发出的调用。定义触发器时,必须指定一个密钥,该密钥是您在配置 webhook 时提供给 GitHub 的 URL 的一部分。

GitHub webhook 定义示例

type: "GitHub"
github:
  secretReference:
    name: "mysecret"

webhook 触发器配置中使用的密钥与您在 GitHub UI 中配置 webhook 时遇到的secret字段不同。 webhook 触发器配置中的密钥使 webhook URL 唯一且难以预测。在 GitHub UI 中配置的密钥是一个可选的字符串字段,用于创建正文的 HMAC 十六进制摘要,该摘要作为X-Hub-Signature标头发送。

有效负载 URL 由oc describe命令(参见显示 Webhook URL)作为 GitHub Webhook URL 返回,其结构如下

示例输出
https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
先决条件
  • 从 GitHub 仓库创建一个BuildConfig

  • system:unauthenticated可以访问所需命名空间中的system:webhook角色。或者,system:unauthenticated可以访问system:webhook集群角色。

步骤
  1. 配置 GitHub Webhook。

    1. 从 GitHub 仓库创建BuildConfig对象后,运行以下命令

      $ oc describe bc/<name_of_your_BuildConfig>

      此命令会生成一个 webhook GitHub URL。

      示例输出
      https://api.starter-us-east-1.openshift.com:443/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
    2. 从 GitHub 网页控制台复制此 URL 到 GitHub。

    3. 在您的 GitHub 仓库中,从**设置 → Webhooks**选择**添加 Webhook**。

    4. 将输出的 URL 粘贴到**有效负载 URL**字段中。

    5. 将**内容类型**从 GitHub 的默认application/x-www-form-urlencoded更改为application/json

    6. 单击**添加 webhook**。

      您应该会看到 GitHub 发出的消息,表明您的 webhook 已成功配置。

      现在,当您将更改推送到 GitHub 仓库时,将自动启动新的构建,并在构建成功后启动新的部署。

      Gogs 支持与 GitHub 相同的 webhook 有效负载格式。因此,如果您使用的是 Gogs 服务器,您也可以在您的BuildConfig上定义一个 GitHub webhook 触发器,并通过您的 Gogs 服务器触发它。

  2. 给定一个包含有效 JSON 有效负载的文件,例如payload.json,您可以使用以下curl命令手动触发 webhook

    $ curl -H "X-GitHub-Event: push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github

    只有当您的 API 服务器没有正确签名的证书时,才需要-k参数。

只有当 GitHub webhook 事件中的ref值与BuildConfig资源的source.git字段中指定的ref值匹配时,才会触发构建。

其他资源

使用 GitLab webhooks

GitLab webhooks 处理 GitLab 在仓库更新时发出的调用。与 GitHub 触发器一样,您必须指定一个密钥。以下示例是BuildConfig内的触发器定义 YAML

type: "GitLab"
gitlab:
  secretReference:
    name: "mysecret"

有效负载 URL 由oc describe命令作为 GitLab Webhook URL 返回,其结构如下

示例输出
https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab
先决条件
  • system:unauthenticated可以访问所需命名空间中的system:webhook角色。或者,system:unauthenticated可以访问system:webhook集群角色。

步骤
  1. 配置 GitLab Webhook。

    1. 输入以下命令获取 webhook URL

      $ oc describe bc <name>
    2. 复制 webhook URL,将<secret>替换为您的密钥值。

    3. 按照GitLab 设置说明将 webhook URL 粘贴到您的 GitLab 仓库设置中。

  2. 给定一个包含有效 JSON 有效负载的文件,例如payload.json,您可以使用以下curl命令手动触发 webhook

    $ curl -H "X-GitLab-Event: Push Hook" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab

    只有当您的 API 服务器没有正确签名的证书时,才需要-k参数。

使用 Bitbucket webhooks

Bitbucket webhooks 处理 Bitbucket 在仓库更新时发出的调用。与 GitHub 和 GitLab 触发器类似,您必须指定一个密钥。以下示例是BuildConfig内的触发器定义 YAML

type: "Bitbucket"
bitbucket:
  secretReference:
    name: "mysecret"

有效负载 URL 由oc describe命令作为 Bitbucket Webhook URL 返回,其结构如下

示例输出
https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket
先决条件
  • system:unauthenticated可以访问所需命名空间中的system:webhook角色。或者,system:unauthenticated可以访问system:webhook集群角色。

步骤
  1. 配置 Bitbucket Webhook。

    1. 输入以下命令获取 webhook URL

      $ oc describe bc <name>
    2. 复制 webhook URL,将<secret>替换为您的密钥值。

    3. 按照Bitbucket 设置说明将 webhook URL 粘贴到您的 Bitbucket 仓库设置中。

  2. 给定一个包含有效 JSON 有效负载的文件,例如payload.json,您可以通过输入以下curl命令手动触发 webhook

    $ curl -H "X-Event-Key: repo:push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket

    只有当您的 API 服务器没有正确签名的证书时,才需要-k参数。

使用通用 webhooks

通用 webhooks 可从任何能够发出网络请求的系统调用。与其他 webhooks 一样,您必须指定一个密钥,该密钥是调用者必须用来触发构建的 URL 的一部分。密钥确保 URL 的唯一性,防止其他人触发构建。以下是BuildConfig内的示例触发器定义 YAML

type: "Generic"
generic:
  secretReference:
    name: "mysecret"
  allowEnv: true (1)
1 设置为true以允许通用 webhook 传递环境变量。
步骤
  1. 要设置调用者,请向调用系统提供构建的通用 webhook 端点的 URL。

    通用 webhook 端点 URL 示例
    https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic

    调用者必须将 webhook 作为POST操作调用。

  2. 要手动调用 webhook,请输入以下curl命令

    $ curl -X POST -k https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic

    HTTP 动词必须设置为POST。不安全的-k标志用于忽略证书验证。如果您的集群具有正确签名的证书,则不需要此第二个标志。

    端点可以接受具有以下格式的可选有效负载

    git:
      uri: "<url to git repository>"
      ref: "<optional git reference>"
      commit: "<commit hash identifying a specific git commit>"
      author:
        name: "<author name>"
        email: "<author e-mail>"
      committer:
        name: "<committer name>"
        email: "<committer e-mail>"
      message: "<commit message>"
    env: (1)
       - name: "<variable name>"
         value: "<variable value>"
    1 类似于BuildConfig环境变量,此处定义的环境变量可用于您的构建。如果这些变量与BuildConfig环境变量冲突,则这些变量优先。默认情况下,webhook 传递的环境变量将被忽略。在 webhook 定义上将allowEnv字段设置为true以启用此行为。
  3. 要使用curl传递此有效负载,请将其定义在一个名为payload_file.yaml的文件中,然后运行以下命令

    $ curl -H "Content-Type: application/yaml" --data-binary @payload_file.yaml -X POST -k https://<openshift_api_host:port>/apis/build.openshift.io/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic

    参数与之前的示例相同,此外还添加了标头和有效负载。-H参数将Content-Type标头设置为application/yamlapplication/json,具体取决于您的有效负载格式。--data-binary参数用于使用POST请求发送具有完整换行符的二进制有效负载。

即使出现无效的请求有效负载(例如,无效的内容类型、无法解析或无效的内容等),OpenShift Dedicated 也允许通过通用 webhook 触发构建。为了向后兼容性,保留此行为。如果出现无效的请求有效负载,OpenShift Dedicated 会在 JSON 格式中返回警告,作为其HTTP 200 OK响应的一部分。

显示 webhook URL

您可以使用oc describe命令显示与构建配置关联的 webhook URL。如果命令没有显示任何 webhook URL,则表示当前没有为该构建配置定义任何 webhook 触发器。

步骤
  • 要显示与BuildConfig关联的任何 webhook URL,请运行以下命令

$ oc describe bc <name>

使用镜像变更触发器

作为开发人员,您可以配置您的构建,以便每次基础镜像发生更改时都自动运行。

您可以使用镜像更改触发器在新的上游镜像版本可用时自动调用您的构建。例如,如果构建基于 RHEL 镜像,您可以触发该构建以便在任何时候 RHEL 镜像发生更改时运行。这样,应用程序镜像将始终在最新的 RHEL 基础镜像上运行。

指向v1 容器注册表中容器镜像的镜像流仅在镜像流标签可用时触发一次构建,而不是在后续镜像更新时触发。这是由于 v1 容器注册表中缺乏唯一可识别的镜像。

步骤
  1. 定义一个指向您要作为触发器使用的上游镜像的ImageStream

    kind: "ImageStream"
    apiVersion: "v1"
    metadata:
      name: "ruby-20-centos7"

    这定义了与位于<system-registry>/<namespace>/ruby-20-centos7的容器镜像仓库绑定的镜像流。<system-registry> 定义为一个名为 docker-registry 的服务,运行在 OpenShift Dedicated 中。

  2. 如果镜像流是构建的基础镜像,请将构建策略中的 from 字段设置为指向该 ImageStream

    strategy:
      sourceStrategy:
        from:
          kind: "ImageStreamTag"
          name: "ruby-20-centos7:latest"

    在本例中,sourceStrategy 定义正在使用名为 ruby-20-centos7 的镜像流(位于此命名空间内)的 latest 标签。

  3. 定义一个具有一个或多个指向 ImageStreams 的触发器的构建。

    type: "ImageChange" (1)
    imageChange: {}
    type: "ImageChange" (2)
    imageChange:
      from:
        kind: "ImageStreamTag"
        name: "custom-image:latest"
    1 一个监控镜像流和标签的镜像变更触发器,该镜像流和标签由构建策略的 from 字段定义。此处的 imageChange 对象必须为空。
    2 一个监控任意镜像流的镜像变更触发器。在本例中,imageChange 部分必须包含一个引用要监控的 ImageStreamTagfrom 字段。

当对策略镜像流使用镜像变更触发器时,生成的构建将提供一个不可变的 Docker 标签,该标签指向与该标签对应的最新镜像。策略在执行构建时将使用此新的镜像引用。

对于不引用策略镜像流的其他镜像变更触发器,将启动新的构建,但不会使用唯一的镜像引用更新构建策略。

由于此示例具有策略的镜像变更触发器,因此生成的构建是

strategy:
  sourceStrategy:
    from:
      kind: "DockerImage"
      name: "172.30.17.3:5001/mynamespace/ruby-20-centos7:<immutableid>"

这确保了触发的构建使用刚刚推送到仓库的新镜像,并且可以使用相同的输入随时重新运行构建。

您可以暂停镜像变更触发器,以便在启动构建之前允许对引用的镜像流进行多次更改。您还可以在最初将 ImageChangeTrigger 添加到 BuildConfig 时将 paused 属性设置为 true,以防止立即触发构建。

type: "ImageChange"
imageChange:
  from:
    kind: "ImageStreamTag"
    name: "custom-image:latest"
  paused: true

如果由于 Webhook 触发器或手动请求而触发构建,则创建的构建将使用从 Strategy 引用的 ImageStream 解析的 <immutableid>。这确保构建使用一致的镜像标签,以便于重现。

其他资源

识别构建的镜像变更触发器

作为开发者,如果您有镜像变更触发器,您可以识别哪个镜像变更启动了上次构建。这对于调试或排查构建问题很有用。

BuildConfig 示例
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: bc-ict-example
  namespace: bc-ict-example-namespace
spec:

# ...

  triggers:
  - imageChange:
      from:
        kind: ImageStreamTag
        name: input:latest
        namespace: bc-ict-example-namespace
  - imageChange:
      from:
        kind: ImageStreamTag
        name: input2:latest
        namespace: bc-ict-example-namespace
    type: ImageChange
status:
  imageChangeTriggers:
  - from:
      name: input:latest
      namespace: bc-ict-example-namespace
    lastTriggerTime: "2021-06-30T13:47:53Z"
    lastTriggeredImageID: image-registry.openshift-image-registry.svc:5000/bc-ict-example-namespace/input@sha256:0f88ffbeb9d25525720bfa3524cb1bf0908b7f791057cf1acfae917b11266a69
  - from:
      name: input2:latest
      namespace: bc-ict-example-namespace
    lastTriggeredImageID:  image-registry.openshift-image-registry.svc:5000/bc-ict-example-namespace/input2@sha256:0f88ffbeb9d25525720bfa3524cb2ce0908b7f791057cf1acfae917b11266a69

  lastVersion: 1

此示例省略了与镜像变更触发器无关的元素。

先决条件
  • 您已配置多个镜像变更触发器。这些触发器已触发一个或多个构建。

步骤
  1. BuildConfig CR 中,在 status.imageChangeTriggers 中,识别具有最新时间戳的 lastTriggerTime

    ImageChangeTriggerStatus

    Then you use the `name` and `namespace` from that build to find the corresponding image change trigger in `buildConfig.spec.triggers`.
  2. imageChangeTriggers 下,比较时间戳以识别最新的

镜像变更触发器

在您的构建配置中,buildConfig.spec.triggers 是构建触发器策略 BuildTriggerPolicy 的数组。

每个 BuildTriggerPolicy 都有一个 type 字段和一组指针字段。每个指针字段对应于 type 字段的一个允许值。因此,您只能将 BuildTriggerPolicy 设置为一个指针字段。

对于镜像变更触发器,type 的值为 ImageChange。然后,imageChange 字段是指向 ImageChangeTrigger 对象的指针,该对象具有以下字段

  • lastTriggeredImageID:此字段(在示例中未显示)在 OpenShift Dedicated 4.8 中已弃用,将在未来的版本中被忽略。它包含从此 BuildConfig 触发上次构建时解析的 ImageStreamTag 的镜像引用。

  • paused:您可以使用此字段(在示例中未显示)暂时禁用此特定镜像变更触发器。

  • from:使用此字段引用驱动此镜像变更触发器的 ImageStreamTag。它的类型是核心 Kubernetes 类型 OwnerReference

from 字段包含以下值得注意的字段

  • kind:对于镜像变更触发器,唯一支持的值是 ImageStreamTag

  • namespace:使用此字段指定 ImageStreamTag 的命名空间。

  • name:使用此字段指定 ImageStreamTag

镜像变更触发器状态

在您的构建配置中,buildConfig.status.imageChangeTriggersImageChangeTriggerStatus 元素的数组。每个 ImageChangeTriggerStatus 元素都包含前面示例中显示的 fromlastTriggeredImageIDlastTriggerTime 元素。

lastTriggerTime 最近的 ImageChangeTriggerStatus 触发了最近的构建。您可以使用其 namenamespace 来识别 buildConfig.spec.triggers 中触发构建的镜像变更触发器。

lastTriggerTime 最新的时间戳表示上次构建的 ImageChangeTriggerStatus。此 ImageChangeTriggerStatusbuildConfig.spec.triggers 中触发构建的镜像变更触发器具有相同的 namenamespace

其他资源

配置更改触发器

配置更改触发器允许在创建新的 BuildConfig 时自动调用构建。

以下是 BuildConfig 中的示例触发器定义 YAML。

  type: "ConfigChange"

配置更改触发器目前仅在创建新的 BuildConfig 时有效。在将来的版本中,配置更改触发器还将能够在 BuildConfig 更新时启动构建。

手动设置触发器

可以使用 oc set triggers 向构建配置添加和删除触发器。

步骤
  • 要在构建配置上设置 GitHub webhook 触发器,请输入以下命令

    $ oc set triggers bc <name> --from-github
  • 要设置镜像变更触发器,请输入以下命令

    $ oc set triggers bc <name> --from-image='<image>'
  • 要删除触发器,请输入以下命令

    $ oc set triggers bc <name> --from-bitbucket --remove

当 webhook 触发器已存在时,再次添加它会重新生成 webhook 密钥。

有关更多信息,请通过输入以下命令查阅帮助文档

$ oc set triggers --help

构建钩子

构建钩子允许将行为注入构建过程。

BuildConfig 对象的 postCommit 字段在运行构建输出镜像的临时容器内运行命令。该钩子在镜像的最后一层提交后且将其推送到注册表之前立即运行。

当前工作目录设置为镜像的 WORKDIR,这是容器镜像的默认工作目录。对于大多数镜像,这就是源代码所在的位置。

如果脚本或命令返回非零退出代码,或者启动临时容器失败,则钩子会失败。当钩子失败时,它会将构建标记为失败,并且镜像不会推送到注册表。可以通过查看构建日志来检查失败的原因。

构建钩子可用于运行单元测试,以在构建完成并使镜像在注册表中可用之前验证镜像。如果所有测试都通过并且测试运行程序返回退出代码0,则构建标记为成功。如果任何测试失败,则构建标记为失败。在所有情况下,构建日志都包含测试运行程序的输出,可用于识别失败的测试。

postCommit钩子不仅限于运行测试,还可以用于其他命令。因为它在临时容器中运行,所以钩子所做的更改不会持久化,这意味着运行钩子不会影响最终镜像。这种行为允许(除其他用途外)安装和使用测试依赖项,这些依赖项会自动丢弃,并且不会出现在最终镜像中。

配置post commit构建钩子

配置post-build钩子有多种方法。以下示例中的所有形式都是等效的,并且都运行bundle exec rake test --verbose

步骤
  • 使用以下选项之一配置post-build钩子

    选项 描述

    Shell脚本

    postCommit:
      script: "bundle exec rake test --verbose"

    script值是要使用/bin/sh -ic运行的shell脚本。当shell脚本适合执行构建钩子时,使用此选项。例如,用于运行如上所示的单元测试。要控制镜像入口点,或者如果镜像没有/bin/sh,请使用commandargs或两者。

    添加的-i标志是为了改进与CentOS和RHEL镜像一起工作的体验,并可能在未来的版本中移除。

    命令作为镜像入口点

    postCommit:
      command: ["/bin/bash", "-c", "bundle exec rake test --verbose"]

    在此形式中,command是要运行的命令,它以exec形式覆盖镜像入口点,如Dockerfile参考中所述。如果镜像没有/bin/sh,或者您不想使用shell,则需要这样做。在所有其他情况下,使用script可能更方便。

    带参数的命令

    postCommit:
      command: ["bundle", "exec", "rake", "test"]
      args: ["--verbose"]

    此形式等同于将参数附加到command

同时提供scriptcommand会创建无效的构建钩子。

使用CLI设置post commit构建钩子

oc set build-hook命令可用于为构建配置设置构建钩子。

步骤
  1. 完成以下操作之一

    • 要将命令设置为post-commit构建钩子,请输入以下命令

      $ oc set build-hook bc/mybc \
          --post-commit \
          --command \
          -- bundle exec rake test --verbose
    • 要将脚本设置为post-commit构建钩子,请输入以下命令

      $ oc set build-hook bc/mybc --post-commit --script="bundle exec rake test --verbose"