1. Knative Eventing 架构总览:控制面与数据面组件职责划分

Knative Eventing 是 Knative 生态中负责事件驱动架构的核心子系统。要理解触发器(Trigger)在控制面通信机制中的角色,首先需要厘清整个 Eventing 架构的两大平面:控制面(Control Plane)与数据面(Data Plane)。控制面负责事件路由规则的定义、状态管理和元数据协调;数据面则负责事件的实际传输、过滤和投递。

1.1 核心组件全景

Knative Eventing 围绕几个关键抽象构建,下表列出了主要组件及其所属平面:

组件 所属平面 核心职责 典型实现
Broker 控制面 + 数据面 事件网格入口,管理事件路由策略,维护 Trigger 列表 InMemoryBroker、RabbitMQBroker、KafkaBroker
Trigger 控制面 定义事件过滤规则(属性/类型)并绑定到目标 Sink CRD 资源,由 Broker 控制器协调
Channel 数据面 事件缓冲、持久化、多订阅分发 InMemoryChannel、KafkaChannel、NATSChannel
Source 数据面 事件生产者,从外部系统生成或导入事件 ApiServerSource、PingSource、KafkaSource
Sink 数据面 事件消费者,接收并处理事件 Service、Function、Knative Service
Subscription 控制面 将 Channel 与 Sink 关联,定义事件投递链路 CRD 资源,由 Channel 控制器解析
关键理解:Broker 是唯一横跨控制面与数据面的组件。它既通过 Kubernetes CRD 存储 Trigger 规则(控制面),又通过内置的 Channel 或自定义实现完成事件的实际路由(数据面)。这种双重身份是故障排查时最容易混淆的边界。

1.2 控制面组件职责详解

控制面组件负责事件路由的声明式配置与状态协调。它们不直接参与事件字节流的传输,而是通过 Kubernetes API Server 维护资源对象,驱动数据面组件做出相应行为。

  • Broker(控制面部分):作为事件网格的命名空间级入口,Broker 资源本身存储了所有关联 Trigger 的引用列表。Broker 控制器监听 Trigger 的创建、更新、删除事件,并动态更新内部路由表。Broker 的 .spec.config 字段定义了底层数据面实现(如使用哪个 Channel 类型)。
  • Trigger:定义事件过滤条件(.spec.filter)和目标 Sink(.spec.subscriber)。Trigger 控制器将过滤规则写入 Broker 的数据面配置,确保只有匹配的事件被转发。Trigger 的状态(.status.conditions)反映了其是否成功绑定到 Broker 且 Sink 可达。
  • Subscription:在 Channel 模式下,Subscription 将 Channel 与一个或多个 Sink 绑定。它定义了事件投递的拓扑结构,包括重试策略和死信队列(DLQ)配置。
故障排查要点:控制面组件的问题通常表现为 Trigger 或 Subscription 的 Ready 条件为 False。常见原因包括:Broker 未就绪、Sink 地址不可解析、过滤表达式语法错误、RBAC 权限不足。排查时应首先检查 kubectl get trigger -o yaml 中的 status.conditions 字段。

1.3 数据面组件职责详解

数据面组件负责事件的实际传输、缓冲、过滤和投递。它们运行在 Pod 中,处理事件字节流,是性能瓶颈和运行时故障的高发区。

  • Source:事件生产者。Source 控制器将外部事件(如 Kubernetes API 变更、定时心跳、Kafka 消息)转换为 CloudEvents 格式,并发送到指定的 Broker 或 Sink。Source 通常包含一个接收器适配器(Adapter)Pod,负责轮询或监听外部系统。
  • Channel:事件缓冲区。Channel 提供事件的临时存储和扇出能力。当多个 Trigger 或 Subscription 匹配同一事件时,Channel 负责复制事件并分发给所有订阅者。Channel 的实现决定了事件的持久性、顺序保证和吞吐量。
  • Sink:事件消费者。Sink 可以是任何可寻址的 HTTP 端点(如 Knative Service、Kubernetes Service、甚至外部 URL)。事件最终被投递到 Sink 的 / 路径(默认),由用户代码处理。

1.4 控制面与数据面的交互流程

下图展示了从 Source 产生事件到 Sink 消费事件的完整路径,并标注了控制面与数据面的边界:

Knative Eventing 控制面与数据面交互流程 控制面(Control Plane) 数据面(Data Plane) Broker CRD Trigger CRD Subscription CRD Source Channel Broker 数据面 Sink 说明: 虚线箭头表示控制面通过 Kubernetes API 将 Trigger/Subscription 规则写入 Broker 和 Channel 的数据面配置。 实线箭头表示事件在数据面中的实际流动路径:Source → Channel → Broker 数据面 → Sink。 Kubernetes API Server Pod 内运行时

1.5 平面职责对比总结

下表从多个维度对比控制面与数据面的差异,帮助在故障排查时快速定位问题平面:

对比维度 控制面 数据面
资源类型 CRD 对象(Broker、Trigger、Subscription) Pod、Service、ConfigMap(Channel 实现、Source Adapter)
通信协议 Kubernetes API(HTTP/gRPC) HTTP/HTTPS(CloudEvents 格式)
状态来源 etcd(通过 API Server) Pod 日志、指标、事件
故障表现 资源状态为 False、Reconciling 循环 事件丢失、投递延迟、HTTP 5xx 错误
排查工具 kubectl describe、kubectl get events kubectl logs、kubectl port-forward、指标监控
典型瓶颈 API Server QPS、控制器并发 网络带宽、Pod 资源限制、Channel 持久化性能
常见误区:很多初学者将 Trigger 视为数据面组件,认为它直接参与事件过滤和转发。实际上,Trigger 只是一个控制面声明,真正的过滤逻辑由 Broker 的数据面实现(如 InMemoryBroker 的过滤器)在事件到达时执行。Trigger 的状态异常通常反映的是控制面协调失败,而非数据面事件丢失。

1.6 平面边界与故障排查切入点

在实际故障排查中,明确控制面与数据面的边界可以大幅缩小排查范围。以下是一个典型的排查决策树:

  1. 检查 Trigger 状态:kubectl get trigger -n <namespace>。如果 READY 列为 True,说明控制面配置已成功下发,问题大概率在数据面。
  2. 检查 Broker 数据面 Pod:kubectl get pods -n knative-eventing。Broker 的数据面实现(如 in-memory-channel-dispatcher)必须处于 Running 状态。
  3. 检查 Source Adapter 日志:确认 Source 是否成功生成事件并发送到 Broker 入口地址。
  4. 检查 Sink 可达性:从 Broker Pod 内部 curl Sink 地址,验证网络连通性和响应状态码。

通过以上步骤,可以快速判断故障发生在控制面协调阶段还是数据面传输阶段,为后续深入排查奠定基础。