使用 Harbor 事件触发器

概述

Harbor Event Triggers 允许你通过 Harbor 的 Webhook 事件自动触发 Tekton pipelines。它支持多种事件类型,包括 artifact push、pull、delete 以及 scanning completion,从而帮助你为容器镜像和 OCI charts 构建完整的 CI/CD 自动化工作流。

核心功能

  • 多事件类型支持:支持多种 Harbor 事件,例如 Push Artifact、Pull Artifact、Delete Artifact 和 Scanning Completed。
  • 标准化 Trigger 绑定:提供标准化的 ClusterTriggerBindings,以确保跨平台一致性。
  • 灵活的参数映射:自动从 Harbor 事件中提取关键信息,用于 pipeline 参数。
  • 多 artifact 类型支持:同时支持容器镜像和 OCI charts。

支持的事件类型

基本事件信息

所有输出变量都可用于 pipeline 参数映射。你可以使用 $(tt.params.<param name>) 访问参数值。

基础变量(适用于所有事件)

变量名描述示例值
event-type事件类型PUSH_ARTIFACT, PULL_ARTIFACT, DELETE_ARTIFACT, SCANNING_COMPLETED
occur-at事件发生时间1763369448
operator触发该事件的用户admin
repository-nameRepository 名称alpine
repository-namespaceRepository Namespacelibrary
repository-full-nameRepository 完整名称library/alpine
repository-typeRepository 类型public, private, chart
artifact-digestArtifact Digestsha256:c4975008127577bfc34169439e890db7cfb1cedccabe49c059c88f913cb27edd
artifact-tagArtifact Taglatest, v1.0.0(可选,如果 artifact 仅通过 digest 引用,则可能为空)
artifact-resource-urlArtifact Resource URL192.168.0.117/library/alpine:latest
WARNING

处理可选字段artifact-tag 字段是可选的,如果 artifact 仅通过 digest 引用,则 payload 中可能没有该字段。repository-date-created 字段适用于 push 和 pull 事件,但不适用于 delete 和 scanning 事件。

重要:如果 TriggerBinding 中引用的字段可能在 payload 中缺失,则你必须在 TriggerTemplate 中为该参数设置 default 值。否则,当字段缺失时,trigger 将失败。例如,如果 artifact-tag 可能缺失,请在 TriggerTemplate 的参数定义中添加 default: ""

1. Push Artifact 事件

当 artifact(容器镜像或 OCI chart)被推送到 Harbor repository 时触发。适用于:

  • 自动化镜像构建和部署
  • 镜像验证和测试
  • 自动打标签和版本管理
  • 多阶段构建 pipelines

Push Artifact 事件变量

变量名描述示例值
repository-date-createdRepository 创建时间1763369448

上面列出的所有基础变量也都可用。

2. Pull Artifact 事件

当 artifact 从 Harbor repository 被拉取时触发。适用于:

  • 使用情况跟踪和分析
  • 安全监控
  • 资源消耗跟踪
  • 部署验证

Pull Artifact 事件变量

变量名描述示例值
repository-date-createdRepository 创建时间1763369448

上面列出的所有基础变量也都可用。

3. Delete Artifact 事件

当 artifact 从 Harbor repository 中删除时触发。适用于:

  • 清理自动化
  • 审计日志记录
  • 资源管理
  • 合规性跟踪

Delete Artifact 事件变量

上面列出的所有基础变量都可用。请注意,repository-date-created 不适用于 delete 事件。

4. Scanning Completed 事件

当 artifact 的漏洞扫描完成时触发。适用于:

  • 安全策略执行
  • 自动化安全检查
  • 漏洞报告
  • 自动化修复工作流

Scanning Completed 事件变量

上面列出的所有基础变量都可用。请注意,repository-date-created 不适用于 scanning 事件。

WARNING

scan_overview 字段结构会因扫描类型不同而变化(SBOM、漏洞检查)。该结构使用动态 MIME type key(例如 application/vnd.security.vulnerability.report; version=1.1),因此无法在 TriggerBindings 中直接使用 JSONPath 解析。如果你需要提取详细的扫描结果(例如漏洞数量、扫描状态),请考虑使用 CEL interceptors,或针对不同扫描类型创建单独的 bindings。

TIP

有关事件结构的更多详细信息,请参阅 Harbor 官方 webhook 文档

配置指南

处理可选字段

Harbor 事件中的某些字段可能是可选的,或者会根据事件类型或 artifact 的引用方式而缺失。例如:

  • artifact-tag:如果 artifact 仅通过 digest 引用,则可能缺失
  • repository-date-created:适用于 push 和 pull 事件,但不适用于 delete 和 scanning 事件

重要:当你使用引用可选字段的 ClusterTriggerBindings 时,必须在 TriggerTemplate 中为这些参数提供默认值。如果 payload 中缺少某个字段且未提供默认值,trigger 将因 JSONPath 解析错误而失败。

示例:要处理可选的 artifact-tag 字段,请按如下方式配置 TriggerTemplate:

spec:
  params:
    - name: artifact-tag
      default: ""  # Optional field 的空字符串默认值

这样可以确保当 Harbor event payload 中缺少 tag 字段时,trigger 会使用空字符串,而不是失败。

前提条件

  1. 已在环境中创建 EventListener,并且能够处理目标 namespace 中的 Trigger。有关更多信息,请联系你的 platform administrator。
  2. Harbor 可以访问上述 EventListener
  3. 所需的 Pipeline 以及必要的运行配置已经创建。
  4. 你拥有修改 Harbor project 的 Webhook 设置的权限。

通过 Harbor UI 配置 Webhook

  1. 访问你的 Harbor project 设置。
  2. 导航到 Webhooks
  3. 点击 New Webhook
  4. 配置 webhook:
    • Name:输入一个描述性名称(例如,tekton-webhook
    • Endpoint URL:输入 EventListener URL,例如:
      http://<your-eventlistener-url>
      https://<your-eventlistener-url>
    • Auth Header:(可选)如有需要,配置认证 header。
    • Skip Certificate Verification:如果使用自签名证书,请启用此项。
  5. 按需选择事件类型:
    • Push Artifact:在 artifact 被推送时触发
    • Pull Artifact:在 artifact 被拉取时触发
    • Delete Artifact:在 artifact 被删除时触发
    • Scanning Completed:在漏洞扫描完成时触发
  6. 点击 Save

Pipeline Trigger 配置示例

如果目标是通过 trigger 实现持续集成,并满足以下需求:

  • 当镜像被推送时,自动触发自动化构建和部署。
  • 当扫描完成时,自动触发安全检查。
WARNING

事件类型过滤:如果你的 Harbor webhook 配置为发送多个事件类型(例如同时发送 Push Artifact 和 Pull Artifact),则你必须在 Triggers 中配置 CEL interceptors,按类型过滤事件。如果没有 interceptor,所有配置的事件类型都会触发同一个 pipeline,这可能导致非预期执行。

例如,如果你的 webhook 将 PUSH_ARTIFACTPULL_ARTIFACT 事件都发送到同一个 EventListener,而你的 Trigger 没有配置 interceptor,那么这两种事件都会触发该 pipeline。请使用 interceptor 将不同事件类型路由到不同的 Trigger 或 pipeline。

为简化本文档,我们假设 pipeline 已就绪,并提供如下参数:

参数名描述示例值
repository-full-name目标 pipeline 的 Repository 完整名称library/alpine
artifact-tagArtifact taglatest
artifact-digestArtifact digestsha256:c4975008127577bfc34169439e890db7cfb1cedccabe49c059c88f913cb27edd
TIP

请替换为你的实际 pipeline 信息。

信息描述
my-namespaceNamespace 名称
my-pipelinePipeline 名称
workspacesWorkspace 配置,请根据实际 pipeline workspace 配置和需求进行修改

接下来,我们只需要配置下面两个 trigger:

创建 Push Artifact Trigger

将以下 YAML 保存为 harbor-push-trigger.yaml

apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
    name: my-pipeline-push   # It is suggested to modify the prefix based on the pipeline name
    namespace: my-namespace  # Change to actual namespace
spec:
    bindings:
    - ref:
        kind: ClusterTriggerBinding
        name: harbor-push-artifact
    interceptors: # Filter to only process PUSH_ARTIFACT events
    - ref:
        kind: ClusterInterceptor
        name: cel
      params:
      - name: filter
        value: body.type == "PUSH_ARTIFACT"  # Only trigger on push events
    template:
      spec:
        params:
        - name: repository-full-name
        - name: artifact-tag
          default: ""  # Optional field: may be empty if artifact is referenced by digest only
        - name: artifact-digest
        resourcetemplates:
        - apiVersion: tekton.dev/v1
          kind: PipelineRun
          metadata:
              generateName: my-pipeline-push- # It is suggested to modify the prefix based on the pipeline name
          spec:
              pipelineRef:
                name: my-pipeline  # Change to actual pipeline name
              params:
              - name: repository-full-name
                value: $(tt.params.repository-full-name)
              - name: artifact-tag
                value: $(tt.params.artifact-tag)
              - name: artifact-digest
                value: $(tt.params.artifact-digest)
              workspaces: # Workspaces need to be modified based on pipeline requirements and environment configuration
              - name: output
                emptyDir: {}

在环境中创建该资源:

kubectl apply -f harbor-push-trigger.yaml
TIP

事件类型过滤示例:如果你的 Harbor webhook 配置为同时发送 Push 和 Pull 事件,并且你希望分别处理它们,可以创建独立的 Triggers,并通过 CEL interceptors 按事件类型过滤:

Push 事件 Trigger(如上所示):

interceptors:
- ref:
    kind: ClusterInterceptor
    name: cel
  params:
  - name: filter
    value: body.type == "PUSH_ARTIFACT"

Pull 事件 Trigger(如有需要):

interceptors:
- ref:
    kind: ClusterInterceptor
    name: cel
  params:
  - name: filter
    value: body.type == "PULL_ARTIFACT"

即使两种事件类型都发送到同一个 EventListener,这种方式也能确保 push 事件只触发 push pipeline,而 pull 事件只触发 pull pipeline。

创建 Scanning Completed Trigger

将以下 YAML 保存为 harbor-scanning-trigger.yaml

apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
  name: my-pipeline-scanning # It is suggested to modify the prefix based on the pipeline name
  namespace: my-namespace # Change to actual namespace
spec:
  bindings:
    - ref:
        kind: ClusterTriggerBinding
        name: harbor-scanning-completed
  interceptors: # Add Interceptor to filter successful scans only, or filter by vulnerability severity
  - ref:
      kind: ClusterInterceptor
      name: cel
    params:
    - name: filter
      value: |
        # Filter for successful scans only
        # Note: scan_overview structure varies by scan type, adjust the path accordingly
        # For vulnerability scans, the structure is: body.event_data.resources[0].scan_overview["application/vnd.security.vulnerability.report; version=1.1"].scan_status == "Success"
  template:
    spec:
      params:
        - name: repository-full-name
        - name: artifact-tag
          default: ""  # Optional field: may be empty if artifact is referenced by digest only
        - name: artifact-digest
      resourcetemplates:
      - apiVersion: tekton.dev/v1
        kind: PipelineRun
        metadata:
          generateName: my-pipeline-scan- # It is suggested to modify the prefix based on the pipeline name
        spec:
          pipelineRef:
            name: my-pipeline # Modify based on the pipeline name
          params:
            - name: repository-full-name
              value: $(tt.params.repository-full-name)
            - name: artifact-tag
              value: $(tt.params.artifact-tag)
            - name: artifact-digest
              value: $(tt.params.artifact-digest)
          workspaces: # Workspaces need to be modified based on pipeline requirements and environment configuration
            - name: output
              emptyDir: {}
TIP

请根据需要调整 Interceptor 配置。你可以基于扫描状态、漏洞严重级别等进行过滤。请注意,scan_overview 结构使用动态 MIME type key,因此你可能需要根据扫描类型调整 JSONPath 表达式。

在环境中创建该资源:

kubectl apply -f harbor-scanning-trigger.yaml

验证 Triggers

通过向 Harbor 推送镜像并触发漏洞扫描来进行验证。

CLI:

你可以使用 kubectl -n <namespace> get pipelinerun 获取 pipeline 执行状态。

Console:

访问 Pipelines > PipelineRuns 查看触发的 pipelines。

使用场景

使用场景 1:自动化镜像部署

场景:当容器镜像推送到 Harbor 时,自动将其部署到 staging 或 production 环境。

配置

  • 使用 harbor-push-artifact binding 创建 Trigger
  • 配置 pipeline 通过 artifact-resource-url 拉取镜像并将其部署到目标环境
  • 可选:使用 CEL interceptors 根据 repository namespace 或 tag 模式进行过滤

示例使用场景

  • 将带有 production 标签的镜像部署到 production 环境
  • 将来自特定 namespace 的镜像部署到 staging 环境
  • 仅对符合特定命名模式的镜像触发部署

使用场景 2:安全策略执行

场景:通过阻止包含严重漏洞的镜像部署来执行安全策略。

配置

  • 使用 harbor-scanning-completed binding 创建 Trigger
  • 使用 CEL interceptor 过滤包含严重漏洞的扫描
  • 配置 pipeline 以:
    • 从扫描结果中检查漏洞数量
    • 如果严重漏洞数量超过阈值,则阻止部署
    • 向安全团队发送通知

示例使用场景

  • 防止部署包含严重漏洞的镜像
  • 自动隔离存在高风险漏洞的镜像
  • 为合规性生成安全报告

使用场景 3:Artifact 生命周期管理

场景:根据使用模式和保留策略自动管理 artifact 生命周期。

配置

  • harbor-pull-artifactharbor-delete-artifact 事件创建 Triggers
  • 跟踪 artifact 的使用情况和年龄
  • 根据策略自动删除旧的或未使用的 artifact

示例使用场景

  • 归档 90 天内未被拉取的旧 artifact
  • 在部署到 production 后清理 development artifact
  • 确保符合数据保留策略

使用场景 4:多阶段 CI/CD pipeline

场景:构建一个完整的 CI/CD pipeline,在镜像推送时触发,执行测试,进行安全扫描,并根据扫描结果部署。

配置

  • 创建多个 Triggers:
    1. harbor-push-artifact trigger:启动构建和测试 pipeline
    2. harbor-scanning-completed trigger:如果扫描通过,则继续部署
  • 使用 pipeline 依赖和 workspaces 在各阶段之间共享 artifact

示例使用场景

  • Build → Test → Scan → Deploy 工作流
  • 并行测试和扫描,以获得更快反馈
  • 根据测试和扫描结果进行条件部署