设置 EventListener
目录
本文档帮助您完成的操作概述主要功能配置说明基本结构主要字段说明spec.resources.kubernetesResourcespec.triggers安全配置权限指南默认 ServiceAccount 与自定义 ServiceAccount所需权限用户指南EventListener 触发器配置场景1. 命名空间级 EventListener2. 项目级 EventListener3. 全局级 EventListener规模网络配置NodePort 配置示例前提条件配置示例NodePort 的重要注意事项何时使用 NodePort从 NodePort 迁移到 Ingress小规模 + HTTPS + ALB Ingress 配置示例前提条件配置示例最佳实践常见问题参考链接本文档帮助您完成的操作
本文档将帮助您配置和部署 EventListener,以接收来自外部系统(例如 GitHub、GitLab 或自定义 Webhook)的 Webhook 事件,并自动触发 Tekton Pipelines。您将了解:
- 如何创建和配置 EventListener 资源
- 如何向外部系统公开 EventListener(使用 Ingress、LoadBalancer 或 NodePort)
- 如何配置权限和安全设置
- 如何根据您的环境选择合适的部署策略
前提条件:您应具备 Tekton Pipelines 和 Kubernetes 基本概念的知识。如果您不熟悉 EventListener 概念,建议先阅读深入理解 EventListener文档。
如需深入了解 EventListener 的概念、架构和原理,请参阅深入理解 EventListener文档。
概述
EventListener 是 Tekton Triggers 中的核心资源,负责接收和处理外部事件(例如 Webhook)。当外部系统触发事件时,EventListener 会根据配置的触发器创建 Kubernetes 资源(例如 PipelineRun)。
主要功能
EventListener 具有以下主要功能:
- 事件监听:提供 HTTP 端点,用于接收来自外部系统的 Webhook 事件
- 事件过滤:使用拦截器验证和过滤接收到的事件
- 资源创建:根据触发器定义自动创建 Kubernetes 资源
- 可扩展性:支持自定义拦截器和各种事件源
- 安全性:内置多种安全机制,例如 Webhook 验证
配置说明
基本结构
主要字段说明
spec.resources.kubernetesResource
用于配置 EventListener 的 Kubernetes 资源:
serviceType:Service 类型(NodePort/ClusterIP/LoadBalancer)servicePort:Service 端口spec:Pod 模板配置
spec.triggers
定义一组触发器配置:
name:触发器名称interceptors:拦截器配置列表bindings:触发器绑定配置template:触发器模板配置
安全配置
在 Kubernetes 上,如果未指定 account 或 account 为空,则配置的默认值为
triggers-default-sa,除非对其进行了覆盖;显式指定的非空 account 将保持不变。
OpenShift 的默认值仍为 pipeline。有关管理员覆盖、恢复和升级兼容性的说明,请参阅
Triggers 默认 ServiceAccount。
EventListener 支持多种安全配置:
- ServiceAccount:
- 默认 ServiceAccount(
triggers-default-sa):如果未指定spec.serviceAccountName,EventListener 将自动使用命名空间中的triggers-default-saServiceAccount。此 ServiceAccount 会自动获得 EventListener 在同一命名空间内处理触发器所需的命名空间范围权限。这些权限会自动绑定到 ServiceAccount 所在的命名空间。 - 自定义 ServiceAccount:当您需要处理跨多个命名空间的触发器时(例如配置了
namespaceSelector),必须指定具有集群范围权限的自定义 ServiceAccount。请确保指定的 ServiceAccount 已配置相应权限(请参阅下方的权限指南)。
- 默认 ServiceAccount(
- 拦截器验证:使用 CEL 拦截器验证事件。
- TLS:支持配置 HTTPS 证书。
权限指南
默认 ServiceAccount 与自定义 ServiceAccount
-
默认 ServiceAccount(
triggers-default-sa):如果未指定spec.serviceAccountName,EventListener 将自动使用命名空间中的triggers-default-saServiceAccount。此 ServiceAccount 会自动获得 EventListener 在同一命名空间内处理触发器所需的命名空间范围权限。这些权限会自动绑定到 ServiceAccount 所在的命名空间,因此您无需手动配置 Role 或 RoleBinding。 -
具有集群权限的自定义 ServiceAccount:当您将
namespaceSelector配置为监听来自多个命名空间的触发器(包括面向所有命名空间的'*')时,必须指定具有集群范围权限的自定义 ServiceAccount。triggers-default-saServiceAccount 对 Trigger 资源具有命名空间范围权限,并对 ClusterTriggerBindings 和 ClusterInterceptors 具有集群范围的读取权限。它无权访问其他命名空间中的命名空间范围 Trigger 资源。
所需权限
为了正常触发 pipeline 和 task,EventListener 使用的 ServiceAccount 需要具有以下权限:
对于内置 Webhook 身份验证,EventListener ServiceAccount 不需要读取 Secret API 的权限。GitHub、GitLab、Bitbucket 和 CEL compareSecret 的 Secret 验证在 core-interceptors 中执行,使用单独的 tekton-triggers-core-interceptors ServiceAccount。Slack 拦截器仅检查请求标头并提取已配置的字段,不会读取 Secret。默认 EventListener 集群角色仅授予其在 ClusterTriggerBindings 和 ClusterInterceptors 上的 get、list 和 watch 权限。通过 Secret 卷挂载的 HTTPS 证书不要求 EventListener ServiceAccount 读取 Secret API。
如果自定义 sidecar、自定义拦截器或 TaskRun 需要通过 Kubernetes API 读取 Secret,请使用专用 ServiceAccount,并在所需命名空间中为其配置 Role 和 RoleBinding。仅授予必要的操作和 Secret 名称;不要将 triggers-default-sa 用作通用 Secret 读取器。
可供参考的 ClusterRole:
用户指南
EventListener 的部署需要根据环境的规模和实际网络情况进行规划,具体配置方式如下:
EventListener 触发器配置场景
EventListener 支持三种不同的触发器配置场景,分别适用于不同的使用场景:
1. 命名空间级 EventListener
命名空间级 EventListener 通过在 EventListener spec 中显式配置 triggers 字段,绑定同一命名空间中的特定触发器。这是最简单的场景,适用于单命名空间部署。
使用场景和建议:
-
使用场景:
- 为单个项目或团队进行独立部署和管理
- 需要明确的资源隔离和权限控制
- 团队深入了解 EventListener 配置,并需要对每个触发器进行精细控制
- 不同命名空间需要不同的 EventListener 配置或资源限制
- 对性能和故障隔离有较高要求
-
推荐用于:
- 有经验的 DevOps 团队或需要高度自定义的场景
- 不同项目需要不同的 EventListener 配置、资源配额或安全策略时
- 需要在租户之间实现完全隔离的多租户环境
- 不同命名空间需要不同的副本数、资源限制或网络策略时
配置示例:
2. 项目级 EventListener
项目级 EventListener 使用 namespaceSelector 绑定多个指定命名空间中的触发器。适用于管理一组相关命名空间(例如项目或团队)中的触发器。
使用场景和建议:
-
使用场景:
- 多个相关项目或命名空间需要共享同一个 EventListener
- 在项目组或部门级别统一处理事件
- 需要在多个命名空间之间共享资源,但不涉及整个集群
- 有一定的性能隔离要求,但可以接受项目组内的资源共享
-
推荐用于:
- 需要在多个相关命名空间之间统一管理触发器的中型团队或项目组
- 多个项目使用相似的配置和资源要求,可以降低运维成本时
- 需要集中管理一组相关项目的 Webhook 事件时
- 对 EventListener 有一定了解,并能够配置和管理跨命名空间权限的团队
配置示例:
3. 全局级 EventListener
全局级 EventListener 使用带有通配符('*')的 namespaceSelector,绑定集群中所有命名空间的触发器。适用于在整个集群中集中处理事件。
使用场景和建议:
-
使用场景:
- 在集群范围内统一处理和管理事件
- 用户对性能隔离没有严格要求,可以接受资源共享
- 一次配置即可让所有用户开箱即用,无需在每个命名空间中单独配置
- 用户不需要深入了解 EventListener,由平台统一管理
- 规模较小到中等且事件量相对可控的集群
-
推荐用于:
- 由平台管理员统一配置和管理的平台场景
- 集群规模较小,且所有用户都需要使用相同的 EventListener 配置时
- 简化用户工作流,降低学习成本和配置复杂度
- 统一监控和故障排除的集中运维管理
- 注意:对于大规模集群或高并发场景,应考虑性能影响和故障隔离
配置示例:
对比表:
规模
在不同的规划场景中,可以使用不同的配置来满足不同的需求。
网络配置
根据环境的优先级和可用网络资源,可以选择不同的网络配置。
选择合适的网络配置
- 生产环境:使用带 HTTPS 的 LoadBalancer 或 Ingress,以确保安全性和可靠性
- 开发/测试环境:NodePort 足够使用,且更易于设置
- 自动管理:如果希望系统自动创建 Ingress 资源,请使用通过
TektonConfig配置的自动暴露功能 - 手动控制:如果希望手动控制 Ingress 资源,请按照下面的示例手动创建
NodePort 配置示例
NodePort 适用于开发、测试,或未配置 LoadBalancer 或 Ingress controller 的环境。此方法会在集群中每个节点的高端口(30000-32767)上暴露 EventListener Service。
前提条件
- Kubernetes 集群中的节点可从外部系统访问
- 至少知道一个节点的外部 IP 地址
- 防火墙规则应允许访问 NodePort 范围(30000-32767)
配置示例
使用 NodePort Service 创建 EventListener
将以下 YAML 保存为 eventlistener-nodeport.yaml:
获取 NodePort Webhook 地址
创建 EventListener 后,需要获取 NodePort 和节点 IP,以构造 Webhook URL:
替代方法:获取所有节点 IP 和 NodePort
Webhook URL 格式为:http://<node-ip>:<nodeport>
测试 NodePort Webhook
验证 EventListener 状态
NodePort 的重要注意事项
- 安全性:NodePort 使用 HTTP(而非 HTTPS),因此不适用于安全性要求较高的生产环境
- 可访问性:节点 IP 必须可被发送 Webhook 的外部系统访问
- 高可用性:如果某个节点发生故障,需要使用其他节点的 IP。请考虑在多个节点前配置负载均衡器
- 端口范围:NodePort 使用 30000-32767 范围内的端口。请确保防火墙允许访问这些端口
- 多个节点:可以使用任意节点的 IP 地址,因为所有节点上都可以访问该 NodePort
何时使用 NodePort
- 开发和测试:为本地开发或测试快速设置
- 内部网络:Webhook 发送方与集群节点位于同一内部网络时
- 无可用 LoadBalancer:集群没有 LoadBalancer Service 或 Ingress controller 时
- 成本考虑:希望避免 LoadBalancer 成本时
生产环境建议:对于生产环境,强烈建议使用带 HTTPS 的 LoadBalancer 或 Ingress,而不是 NodePort,因为 NodePort 不提供加密和适当的基于域名的路由。
从 NodePort 迁移到 Ingress
如果最初使用 NodePort 进行测试,现在希望迁移到使用 Ingress 的生产环境:
- 更新 EventListener Service 类型:在 EventListener spec 中,将
serviceType从NodePort修改为ClusterIP - 配置自动暴露(推荐):使用自动暴露功能 自动创建 Ingress 资源
- 或手动创建 Ingress:按照下面的示例手动创建 Ingress 资源
以下示例展示了如何配置带 Ingress 的 EventListener,以用于生产环境。
小规模 + HTTPS + ALB Ingress 配置示例
前提条件
在使用 Ingress 配置 EventListener 之前,请确保满足以下前提条件:
-
LoadBalancer/Gateway 配置:
- 集群中应已部署并配置 LoadBalancer 或 Gateway(例如 ALB)
- LoadBalancer 应可被发送 Webhook 的外部系统访问
- 有关配置 Load Balancer 的更多信息,请参阅 配置 Load Balancer。
-
域名和证书设置:
- 已正确配置域名,并指向 LoadBalancer
- TLS 证书已准备就绪(手动创建或通过 cert-manager 创建)
- DNS 记录已正确配置
-
Ingress Controller:
- 已正确部署和配置 Ingress controller(本示例使用 ALB)
- Ingress controller 已准备好处理 Ingress 资源
- 有关创建 Ingress 的更多信息,请参阅 创建 Ingress。
注意:如果使用自动暴露功能(通过 TektonConfig 配置),通常无需手动创建 Ingress 资源。系统会根据导出规则自动创建这些资源。本示例展示了在希望手动控制或未使用自动暴露功能时,如何手动创建 Ingress。
配置示例
创建命名空间(可选)
确保存在一个 Namespace,以便管理 EventListener 和其他权限;此处以 tekton-webhooks 为例。
创建 ClusterRole 和 ServiceAccount 并设置权限
-
默认 ServiceAccount(
triggers-default-sa):未指定spec.serviceAccountName时,EventListener 会自动使用命名空间中的triggers-default-saServiceAccount。此 ServiceAccount 会自动获得 EventListener 处理同一命名空间内触发器所需的命名空间范围权限。权限会自动绑定到 ServiceAccount 所在的命名空间,因此无需手动配置 Role 或 RoleBinding。 -
具有集群权限的自定义 ServiceAccount:当配置
namespaceSelector以监听来自多个命名空间的触发器(包括用于所有命名空间的'*')时,必须指定具有集群范围权限的自定义 ServiceAccount。triggers-default-saServiceAccount 对 Trigger 资源具有命名空间范围权限,对 ClusterTriggerBindings 和 ClusterInterceptors 具有集群范围的读取权限。但它无权访问其他命名空间中的命名空间范围 Trigger 资源。
namespaceSelector 必需配置:仅当使用 namespaceSelector 监听多个命名空间中的触发器时,才需要执行以下步骤。如果 EventListener 只处理同一命名空间内的触发器,则可以跳过这些步骤并使用默认的 triggers-default-sa ServiceAccount,该 ServiceAccount 会自动获得所需权限。
以下 YAML 用于 eventlistener-role.yaml。
使用上述 ClusterRole 和 ServiceAccount 创建绑定。
创建 EventListener
将以下 YAML 保存为 eventlistener.yaml。
ServiceAccount 选择:
- 如果只需要处理同一命名空间内的触发器,则可以省略
spec.serviceAccountName,以使用默认的triggers-default-saServiceAccount,该 ServiceAccount 会自动获得所需的命名空间范围权限。 - 由于本示例使用
namespaceSelector和'*'监听所有命名空间中的触发器,因此需要具有集群范围权限的自定义 ServiceAccount。因此,此处指定了serviceAccountName: "eventlistener"。
创建 Ingress 和 TLS Secret
需要将 <host> 设置为相应的域名和证书信息。
DNS 配置:使用域名配置 host 字段时,请确保:
- DNS 记录已正确配置,可将域名解析到 Ingress controller 的 IP 地址
- 对于本地测试,可以将域名添加到
/etc/hosts(Linux/Mac)或C:\Windows\System32\drivers\etc\hosts(Windows) - 发送 Webhook 的系统(GitHub、GitLab 等)必须能够解析该域名
验证域名可访问性
配置域名和 Ingress 后,确保 Webhook 域名可访问:
重要:确保基于 LoadBalancer 的 Webhook 域名可从外部系统(例如 GitHub、GitLab 或其他 Webhook 发送方)访问。如果域名不可访问,Webhook 将失败。请检查:
- DNS 记录已正确配置并完成传播
- LoadBalancer 已正确配置,并具有外部 IP/域名
- 防火墙规则允许流量访问 LoadBalancer
- TLS 证书有效(如果使用 HTTPS)
验证 Webhook 配置
可以使用以下 curl 测试配置是否正常。
最佳实践
-
资源限制:
- 为 EventListener Pod 设置适当的资源请求和限制。
- 根据实际负载调整副本数量。
-
安全性:
- 使用 HTTPS 和 Webhook Secrets。
- 配置遵循最小权限原则的 ServiceAccount。
- 使用拦截器验证所有传入事件。
-
可用性:
- 使用负载均衡器或 Ingress 暴露服务。
- 配置适当的健康检查。
- 实施高可用部署。
-
监控:
- 监控 EventListener 日志。
- 设置适当的告警机制。
- 跟踪事件处理性能。
常见问题
-
事件未触发 Pipeline
- 检查拦截器配置。
- 验证 Webhook 配置。
- 查看 EventListener 日志。
-
权限问题
- 确认 ServiceAccount 权限。
- 如果使用默认的
triggers-default-saServiceAccount,请验证其是否存在于命名空间中,以及是否已自动授予所需权限。 - 如果使用自定义 ServiceAccount,请检查 Role 和 RoleBinding 配置。
- 验证命名空间访问权限。
- 如果使用
namespaceSelector跨命名空间监听,请确保使用具有集群范围权限的自定义 ServiceAccount。triggers-default-saServiceAccount 仅具有命名空间范围的权限。
-
性能问题
- 调整资源限制。
- 优化拦截器配置。
- 考虑水平扩展。