Interceptor
Interceptor 是 Tekton Triggers 中一个强大的组件,用于在事件数据到达 TriggerBindings 和 TriggerTemplates 之前对其进行处理和过滤。它充当传入 webhook 事件的守门员和转换器,允许你验证、过滤和修改事件数据,确保只有相关事件触发你的流水线。
目录
术语说明
术语 | 说明 |
---|
Interceptor | 在事件数据到达 TriggerBindings 和 TriggerTemplates 之前处理 webhook 事件的组件。 |
ClusterInterceptor | 一个集群范围的 Interceptor,可在所有命名空间中使用。 |
CEL | Common Expression Language,用于过滤和转换事件数据。 |
Extensions | Interceptor 添加的额外数据字段,可被 TriggerBindings 访问。 |
Webhook | 在外部系统发生特定事件时发送事件数据的 HTTP 回调。 |
为什么需要 Interceptors
事件处理的挑战
在响应外部事件的 CI/CD 系统中,会遇到以下几个挑战:
- 事件验证:需要验证外部 webhook,确保其来自可信来源。
- 事件过滤:并非所有事件都应触发流水线,需要根据事件类型或内容进行过滤。
- 数据转换:原始 webhook 负载通常包含多余数据或需要重构。
- 安全问题:如果没有适当验证,webhook 端点可能容易被滥用。
如果没有 Interceptors,解决这些问题将需要:
- 针对每个 webhook 源编写自定义验证代码
- 在流水线定义中嵌入复杂逻辑
- 在脚本中手动进行过滤和转换
- 为每个集成单独实现安全机制
Interceptors 如何解决这些问题
Interceptors 提供了一种标准化、声明式的方式来:
- 验证事件:验证 webhook 签名和令牌以确保真实性。
- 过滤事件:仅处理基于类型、内容或其他条件的相关事件。
- 转换数据:提取、修改或添加数据,使其更适合流水线使用。
- 增强安全性:在所有 webhook 集成中实施一致的安全措施。
- 模块化逻辑:将事件处理逻辑与流水线执行分离。
这种方法在事件接收、处理和流水线执行之间创建了清晰的分离,使你的 CI/CD 系统更易维护且更安全。
优势
- 增强安全性:在处理前验证 webhook 的真实性
- 降低流水线复杂度:将过滤和转换逻辑移出流水线
- 标准化处理:对不同来源的事件进行一致处理
- 灵活性:可链式组合多个 interceptor 以满足复杂处理需求
- 可扩展性:支持创建自定义 interceptor 以实现特殊处理
- 可复用性:定义一次 interceptor,可在多个触发器中复用
- 声明式配置:使用 Kubernetes 资源配置事件处理
适用场景
Interceptor 在以下场景中必不可少:
-
安全的 webhook 处理:需要验证 webhook 事件来自可信来源时。
-
条件流水线执行:仅在特定事件类型或内容(如仅在 main 分支的 push 事件)触发流水线时。
-
数据丰富:需要从复杂事件负载中提取特定数据或添加计算值时。
-
多源集成:集成多个 webhook 提供商(GitHub、GitLab、Bitbucket)并实现一致处理时。
-
自定义事件处理:实现标准 interceptor 之外的特殊事件处理逻辑时。
约束与限制
- Interceptors 会增加事件处理的开销
- 复杂的 CEL 表达式调试较困难
- 自定义 interceptor 需要额外的部署和管理
- 推荐使用 HTTPS,HTTP 支持将在未来版本中移除
- Interceptors 必须妥善保护以防止未授权访问
原则
Interceptor 架构
Interceptor 位于 EventListener 和 Trigger 处理流水线之间:
- EventListener 接收 webhook 事件
- Interceptors 处理并过滤事件
- TriggerBindings 从处理后的事件中提取数据
- TriggerTemplates 使用提取的数据创建资源
Interceptor 可以串联,每个 interceptor 接收前一个的输出,支持复杂的处理流水线,每个 interceptor 执行特定功能。
Interceptor 类型
Tekton Triggers 支持两种 interceptor 实现:
-
独立 Interceptor:作为独立的 Kubernetes 服务实现
- Interceptor:命名空间范围的自定义资源
- ClusterInterceptor:集群范围的自定义资源
- 更灵活且易于扩展
- 可用任何支持 HTTP 服务的语言实现
-
内置 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 示例
-
创建自定义 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
-
创建自定义 interceptor 的 Service:
apiVersion: v1
kind: Service
metadata:
name: custom-interceptor-svc
spec:
selector:
app: custom-interceptor
ports:
- port: 80
targetPort: 8080
-
注册自定义 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,未来版本将强制要求。
适用场景
约束与限制
原则/参数说明
配置 interceptor 使用 HTTPS:
- 在 interceptor 上添加
server/type: https
标签
- 提供用于证书验证的 CA bundle
- 确保 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
参考资料