×

构建触发器

在定义BuildConfig时,您可以定义触发器来控制BuildConfig应该在什么情况下运行。以下构建触发器可用

  • Webhook

  • 镜像变更

  • 配置变更

Webhook触发器

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

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

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

oc new-appoc 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 Container Platform中特定命名空间的system:webhook角色绑定。system:webhook角色绑定允许用户从不使用OpenShift Container Platform身份验证机制的外部系统触发构建。默认情况下,未经身份验证的用户无权访问非公共角色绑定。这是OpenShift Container Platform 4.16之前的版本的一个变化。

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

如果需要允许未经身份验证的用户访问集群,您可以通过将未经身份验证的用户添加到每个所需命名空间中的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 webhook

当存储库更新时,GitHub webhook处理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. 将此URL复制并粘贴到GitHub的GitHub Web控制台中。

    3. 在您的GitHub存储库中,从**设置→Webhook**选择**添加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 Webhook

当仓库更新时,GitLab Webhook 会处理 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 Webhook

Bitbucket Webhook 处理当仓库更新时 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参数。

使用通用 Webhook

通用 Webhook 可从任何能够发出 Web 请求的系统调用。与其他 Webhook 一样,您必须指定一个密钥,该密钥是调用方必须用来触发构建的 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 Container Platform 也允许通过通用 Webhook 触发构建。此行为是为了向后兼容性而保留的。如果提供了无效的请求有效负载,OpenShift Container Platform 会在HTTP 200 OK响应中以 JSON 格式返回警告。

显示 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>定义为在 OpenShift Container Platform 中运行的名为docker-registry的服务。

  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字段中定义的ImageStreamTag。此处的imageChange对象必须为空。
    2 一种图像变更触发器,它监控任意的图像流。在这种情况下,imageChange部分必须包含一个from字段,该字段引用要监控的ImageStreamTag

当对策略图像流使用图像变更触发器时,生成的构建会提供一个指向与该标签对应的最新图像的不变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

除了为所有Strategy类型设置image字段外,对于自定义构建,还会检查OPENSHIFT_CUSTOM_BUILD_BASE_IMAGE环境变量。如果它不存在,则使用不变的图像引用创建它。如果它存在,则使用不变的图像引用更新它。

如果由于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 Container Platform 4.8中已弃用,将在未来的版本中被忽略。它包含从此BuildConfig触发上次构建时ImageStreamTag解析的图像引用。

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

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

from字段具有以下值得注意的字段

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

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

  • name:使用此字段指定ImageStreamTag

图像变更触发器状态

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

具有最新lastTriggerTimeImageChangeTriggerStatus触发了最近的构建。您可以使用它的namenamespace来标识在buildConfig.spec.triggers中触发构建的图像变更触发器。

具有最新时间戳的lastTriggerTime表示上次构建的ImageChangeTriggerStatus。此ImageChangeTriggerStatus与触发构建的buildConfig.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"