3. Cilium 组件架构:Agent、Operator、CNI 插件、Hubble Relay 的核心职责与版本依赖关系
Cilium 采用微服务化的控制面与数据面分离架构,核心组件包括 Cilium Agent、Cilium Operator、Cilium-CNI 插件 以及可选的 Hubble Relay。在准入控制校验版本漂移时,必须理解每个组件的职责边界及其版本耦合规则,否则极易出现组件间协议不兼容或功能降级。
3.1 组件核心职责对比
| 组件名称 | 部署形态 | 核心职责 | 关键数据面/控制面接口 |
|---|---|---|---|
| Cilium Agent | DaemonSet(每节点一个) | 管理 eBPF 程序加载、端点(Endpoint)生命周期、网络策略执行、服务负载均衡、监控指标暴露 | 与 kube-apiserver 通信获取 Endpoint/Service/Policy;通过 Unix Socket 与 Cilium-CNI 交互 |
| Cilium Operator | Deployment(通常 1~2 副本) | 集群级协调:IPAM(IP 地址管理)、CiliumNetworkPolicy 状态同步、节点间隧道/路由配置、CRD 状态清理 | 仅控制面操作,不参与数据面转发;依赖 kube-apiserver 和 etcd |
| Cilium-CNI 插件 | 二进制文件(位于 /opt/cni/bin/) | 接收 kubelet CNI 调用,将 Pod 网络命名空间加入 Cilium 管理;调用 Agent 的 gRPC 接口完成端点创建 | 通过本地 Unix Socket 与同节点 Agent 通信;不直接访问 kube-apiserver |
| Hubble Relay | Deployment(可选组件) | 聚合集群内所有 Hubble 观测数据,提供全局 API 和 CLI 查询能力;支持多集群联邦 | gRPC 连接各节点 Hubble 服务;依赖 Cilium Agent 暴露的观测数据 |
版本漂移校验要点: Agent 与 CNI 插件必须使用完全相同的版本(二进制同时发布),因为两者通过内部 protobuf 协议通信,字段变更会导致端点创建失败。Operator 和 Hubble Relay 允许小版本差异,但大版本必须对齐 Agent 的 API 版本。
3.2 组件间通信与版本依赖关系
下图展示了四个组件之间的通信链路及版本耦合边界。箭头方向表示调用或数据流方向,标注了协议类型和版本约束等级。
3.3 版本漂移典型场景与影响
在准入控制校验中,以下三种版本漂移场景需要重点拦截:
- Agent 与 CNI 插件版本不一致: 最常见且破坏性最大。CNI 插件调用 Agent 的 gRPC 接口创建端点时,若 protobuf 消息结构不匹配,会导致 Pod 创建失败,kubelet 反复重试直至超时。
- Operator 版本高于 Agent: Operator 可能下发 Agent 不支持的 CRD 字段或 IPAM 策略,导致 Agent 日志报错、策略无法生效。
- Hubble Relay 版本低于 Agent: Relay 无法解析 Agent 上报的新观测字段,导致 Hubble UI/CLI 查询结果缺失或解析异常。
准入校验策略建议: 在 Helm 升级或 Operator 部署准入 Webhook 中,强制校验 Agent 与 CNI 插件的镜像 tag 完全一致;对 Operator 和 Hubble Relay 使用 semver 比较,拒绝大版本不匹配的变更请求。
3.4 组件版本矩阵示例
以下表格展示了 Cilium v1.14.x 系列中各组件的版本兼容关系,供准入控制规则编写参考:
| Cilium 版本 | Agent 版本 | CNI 插件版本 | Operator 版本 | Hubble Relay 版本 | 兼容性 |
|---|---|---|---|---|---|
| v1.14.0 | v1.14.0 | v1.14.0 | v1.14.0 | v1.14.0 | ✅ 完全兼容 |
| v1.14.1 | v1.14.1 | v1.14.0 | v1.14.1 | v1.14.1 | ❌ Agent/CNI 不匹配 |
| v1.14.2 | v1.14.2 | v1.14.2 | v1.14.0 | v1.14.2 | ⚠️ Operator 降级,功能受限 |
| v1.14.3 | v1.14.3 | v1.14.3 | v1.14.3 | v1.14.0 | ⚠️ Relay 无法解析新字段 |
3.5 版本校验的代码级实现参考
在准入控制 Webhook 中,可以通过解析容器镜像 tag 或读取 Cilium Agent 的版本端点来实现校验。以下是一个简化版的 Go 伪代码片段:
// 伪代码:准入控制版本校验逻辑
func validateCiliumVersions(pod corev1.Pod) error {
agentVersion := getImageTag(pod, "cilium-agent")
cniVersion := getImageTag(pod, "cilium-cni")
operatorVersion := getImageTag(pod, "cilium-operator")
relayVersion := getImageTag(pod, "hubble-relay")
// 规则1:Agent 与 CNI 必须完全一致
if agentVersion != cniVersion {
return fmt.Errorf("Agent version %s != CNI version %s", agentVersion, cniVersion)
}
// 规则2:Operator 大版本必须与 Agent 一致
if semver.Major(agentVersion) != semver.Major(operatorVersion) {
return fmt.Errorf("Agent major %d != Operator major %d",
semver.Major(agentVersion), semver.Major(operatorVersion))
}
// 规则3:Relay 版本不能低于 Agent 版本
if semver.Compare(relayVersion, agentVersion) < 0 {
return fmt.Errorf("Relay version %s < Agent version %s", relayVersion, agentVersion)
}
return nil
}
注意: 上述代码仅为示例,生产环境中还需考虑 pre-release 标签(如 rc1、alpha)的比较逻辑,以及未部署 Hubble Relay 时的跳过处理。建议使用
blang/semver 或 Masterminds/semver 库进行语义化版本比较。