Interceptor

Interceptor 是 Tekton Triggers 中一个强大的组件,用于在事件数据到达 TriggerBindings 和 TriggerTemplates 之前对其进行处理和过滤。它充当传入 webhook 事件的守门员和转换器,允许你验证、过滤和修改事件数据,确保只有相关事件触发你的流水线。

目录

术语说明

术语说明
Interceptor在事件数据到达 TriggerBindings 和 TriggerTemplates 之前处理 webhook 事件的组件。
ClusterInterceptor一个集群范围的 Interceptor,可在所有命名空间中使用。
CELCommon Expression Language,用于过滤和转换事件数据。
ExtensionsInterceptor 添加的额外数据字段,可被 TriggerBindings 访问。
Webhook在外部系统发生特定事件时发送事件数据的 HTTP 回调。

为什么需要 Interceptors

事件处理的挑战

在响应外部事件的 CI/CD 系统中,会遇到以下几个挑战:

  1. 事件验证:需要验证外部 webhook,确保其来自可信来源。
  2. 事件过滤:并非所有事件都应触发流水线,需要根据事件类型或内容进行过滤。
  3. 数据转换:原始 webhook 负载通常包含多余数据或需要重构。
  4. 安全问题:如果没有适当验证,webhook 端点可能容易被滥用。

如果没有 Interceptors,解决这些问题将需要:

  • 针对每个 webhook 源编写自定义验证代码
  • 在流水线定义中嵌入复杂逻辑
  • 在脚本中手动进行过滤和转换
  • 为每个集成单独实现安全机制

Interceptors 如何解决这些问题

Interceptors 提供了一种标准化、声明式的方式来:

  1. 验证事件:验证 webhook 签名和令牌以确保真实性。
  2. 过滤事件:仅处理基于类型、内容或其他条件的相关事件。
  3. 转换数据:提取、修改或添加数据,使其更适合流水线使用。
  4. 增强安全性:在所有 webhook 集成中实施一致的安全措施。
  5. 模块化逻辑:将事件处理逻辑与流水线执行分离。

这种方法在事件接收、处理和流水线执行之间创建了清晰的分离,使你的 CI/CD 系统更易维护且更安全。

优势

  • 增强安全性:在处理前验证 webhook 的真实性
  • 降低流水线复杂度:将过滤和转换逻辑移出流水线
  • 标准化处理:对不同来源的事件进行一致处理
  • 灵活性:可链式组合多个 interceptor 以满足复杂处理需求
  • 可扩展性:支持创建自定义 interceptor 以实现特殊处理
  • 可复用性:定义一次 interceptor,可在多个触发器中复用
  • 声明式配置:使用 Kubernetes 资源配置事件处理

适用场景

Interceptor 在以下场景中必不可少:

  1. 安全的 webhook 处理:需要验证 webhook 事件来自可信来源时。

  2. 条件流水线执行:仅在特定事件类型或内容(如仅在 main 分支的 push 事件)触发流水线时。

  3. 数据丰富:需要从复杂事件负载中提取特定数据或添加计算值时。

  4. 多源集成:集成多个 webhook 提供商(GitHub、GitLab、Bitbucket)并实现一致处理时。

  5. 自定义事件处理:实现标准 interceptor 之外的特殊事件处理逻辑时。

约束与限制

  • Interceptors 会增加事件处理的开销
  • 复杂的 CEL 表达式调试较困难
  • 自定义 interceptor 需要额外的部署和管理
  • 推荐使用 HTTPS,HTTP 支持将在未来版本中移除
  • Interceptors 必须妥善保护以防止未授权访问

原则

Interceptor 架构

Interceptor 位于 EventListener 和 Trigger 处理流水线之间:

  1. EventListener 接收 webhook 事件
  2. Interceptors 处理并过滤事件
  3. TriggerBindings 从处理后的事件中提取数据
  4. TriggerTemplates 使用提取的数据创建资源

Interceptor 可以串联,每个 interceptor 接收前一个的输出,支持复杂的处理流水线,每个 interceptor 执行特定功能。

Interceptor 类型

Tekton Triggers 支持两种 interceptor 实现:

  1. 独立 Interceptor:作为独立的 Kubernetes 服务实现

    • Interceptor:命名空间范围的自定义资源
    • ClusterInterceptor:集群范围的自定义资源
    • 更灵活且易于扩展
    • 可用任何支持 HTTP 服务的语言实现
  2. 内置 Interceptor:包含在 EventListener Pod 中

    • 如 GitHub、GitLab、Bitbucket、CEL 等
    • 保留以兼容旧版本
    • 使用简单但扩展性较差

Interceptor 结构

一个基本的 Interceptor 资源结构如下:

apiVersion: triggers.tekton.dev/v1alpha1
kind: Interceptor
metadata:
  name: my-interceptor
spec:
  clientConfig:
    service:
      name: my-interceptor-svc
      namespace: default
      path: "/optional-path"  # 可选
      port: 8081  # 默认为 80

在 Trigger 中引用示例:

triggers:
  - name: trigger-with-interceptor
    interceptors:
      - ref:
          name: "my-interceptor"
          kind: Interceptor  # 或 ClusterInterceptor
          namespace: default  # 仅 Interceptor 需要
        params:  # 可选参数
          - name: "param1"
            value: "value1"

配置示例

GitHub Interceptor 示例

triggers:
  - name: github-push-trigger
    interceptors:
      - ref:
          name: "github"
        params:
          - name: "secretRef"
            value:
              secretName: github-secret
              secretKey: secretToken
          - name: "eventTypes"
            value: ["push"]
          - name: "branches"
            value: ["main", "release/*"]

GitLab Interceptor + CEL 示例

triggers:
  - name: gitlab-merge-request-trigger
    interceptors:
      - ref:
          name: "gitlab"
        params:
          - name: "secretRef"
            value:
              secretName: gitlab-secret
              secretKey: secretToken
          - name: "eventTypes"
            value: ["Merge Request Hook"]
      - ref:
          name: "cel"
        params:
          - name: "filter"
            value: "body.object_attributes.state == 'opened' || body.object_attributes.state == 'reopened'"
          - name: "overlays"
            value:
              - key: truncated_sha
                expression: "body.object_attributes.last_commit.id.truncate(7)"

自定义 Interceptor 示例

  1. 创建自定义 interceptor 的 Deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-interceptor
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: custom-interceptor
      template:
        metadata:
          labels:
            app: custom-interceptor
        spec:
          containers:
            - name: custom-interceptor
              image: custom-interceptor:latest
              ports:
                - containerPort: 8080
  2. 创建自定义 interceptor 的 Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: custom-interceptor-svc
    spec:
      selector:
        app: custom-interceptor
      ports:
        - port: 80
          targetPort: 8080
  3. 注册自定义 interceptor:

    apiVersion: triggers.tekton.dev/v1alpha1
    kind: ClusterInterceptor
    metadata:
      name: custom-interceptor
    spec:
      clientConfig:
        service:
          name: custom-interceptor-svc
          namespace: default
          port: 80

与 Interceptor 相关的重要参数说明

CEL 表达式

CEL(Common Expression Language)是 CEL interceptor 用于过滤和转换事件数据的强大工具。

适用场景

  • 基于复杂条件过滤事件
  • 从事件负载中提取特定数据
  • 基于现有数据创建新字段
  • 实现条件逻辑

约束与限制

  • 复杂表达式调试困难
  • 功能受限于 CEL 提供的能力
  • 复杂表达式可能影响性能

原则/参数说明

常见 CEL 模式:

  • 访问 body 字段:body.repository.full_name
  • 访问 header 字段:header.X-GitHub-Event
  • 字符串操作:body.ref.split('/')[2]
  • 条件判断:body.action in ['opened', 'reopened', 'synchronize']
  • 布尔逻辑:body.pull_request.base.ref == 'main' && body.action == 'opened'

配置示例

- ref:
    name: "cel"
  params:
    - name: "filter"
      value: "header.match('X-GitHub-Event', 'pull_request') && body.action in ['opened', 'reopened', 'synchronize']"
    - name: "overlays"
      value:
        - key: branch_name
          expression: "body.pull_request.head.ref"
        - key: is_main_target
          expression: "body.pull_request.base.ref == 'main'"

HTTPS 配置

建议使用 HTTPS 运行 interceptor,未来版本将强制要求。

适用场景

  • 生产环境
  • 处理敏感数据
  • 满足安全合规要求

约束与限制

  • 需要妥善管理证书
  • 配置较 HTTP 复杂

原则/参数说明

配置 interceptor 使用 HTTPS:

  1. 在 interceptor 上添加 server/type: https 标签
  2. 提供用于证书验证的 CA bundle
  3. 确保 interceptor 服务配置为提供 HTTPS

配置示例

apiVersion: triggers.tekton.dev/v1alpha1
kind: Interceptor
metadata:
  name: secure-interceptor
  labels:
    server/type: https
spec:
  clientConfig:
    caBundle: "BASE64_ENCODED_CA_BUNDLE"
    service:
      name: secure-interceptor-svc
      namespace: default
      port: 8443

参考资料