3. Cilium 架构:核心组件详解

Cilium 采用分布式微服务架构,由多个协同工作的组件构成。理解每个组件的职责与交互方式,是进行缓存命中故障排查的基础。本章将深入解析 Cilium Agent、Cilium Operator、Cilium CNI 插件以及 Cilium DaemonSet 组件的核心功能与协作流程。

3.1 组件总览与职责划分

Cilium 架构主要分为控制平面与数据平面。控制平面负责策略管理、状态协调与 API 服务;数据平面则直接处理网络数据包,执行 eBPF 程序。下表列出了核心组件及其职责:

组件名称 部署形态 核心职责 故障排查关注点
Cilium Agent DaemonSet(每节点一个) 管理 eBPF 程序、端点 IP 分配、网络策略执行、服务负载均衡 eBPF map 状态、端点列表、策略命中计数
Cilium Operator Deployment(通常 1-2 副本) 集群级状态协调、IPAM 资源池管理、节点间隧道/路由配置 IP 池水位、节点连通性、CRD 状态
Cilium CNI 插件 二进制文件(由 kubelet 调用) 容器网络命名空间配置、veth pair 创建、调用 Agent 进行端点注册 CNI 调用日志、接口创建时序、Agent 响应延迟
Cilium DaemonSet DaemonSet(每节点一个) 承载 Agent 进程、监控 Agent 健康、确保 eBPF 文件系统挂载 Pod 状态、资源限制、启动参数

3.2 Cilium Agent:数据平面的核心

Cilium Agent 是运行在每个 Kubernetes 节点上的守护进程,是数据平面的核心执行者。它通过 eBPF 直接与 Linux 内核交互,实现高性能网络与安全策略。

  • eBPF 程序管理:Agent 负责将编译后的 eBPF 程序(如 TC、XDP、cgroup 程序)加载到内核中,并附加到对应的 hook 点。
  • 端点管理:维护本地节点上所有容器端点的状态,包括 IP 地址、安全标识(Security Identity)、标签信息。
  • 策略执行:将用户定义的网络策略(CiliumNetworkPolicy)转换为 eBPF map 中的规则,实现 L3/L4/L7 的访问控制。
  • 服务负载均衡:通过 eBPF 实现 kube-proxy 替代,处理 ClusterIP、NodePort、ExternalIP 等服务的流量转发。
  • 监控与指标暴露:通过 Prometheus 指标暴露 eBPF map 命中率、策略拒绝计数、端点状态变化等关键数据。
缓存命中故障关联:Agent 维护的 eBPF map(如 cilium_ct4、cilium_ct6)是连接跟踪缓存的核心。当缓存命中率下降时,首先应检查 Agent 是否正常更新这些 map,以及 map 大小是否被正确配置。

3.3 Cilium Operator:集群控制平面

Cilium Operator 是一个 Deployment 组件,负责处理集群级别的协调任务,不直接参与数据路径转发。

  • IPAM(IP 地址管理):管理集群级别的 IP 地址池,根据节点需求分配 CIDR 段,并回收已释放的 IP。
  • 节点间网络配置:在 Overlay 模式下,Operator 负责配置 VXLAN/Geneve 隧道的端点信息;在 Native Routing 模式下,则负责更新节点路由表。
  • CRD 状态同步:监控 CiliumEndpoint、CiliumNode 等自定义资源的状态变化,并触发 Agent 进行本地更新。
  • 故障恢复:当节点或 Agent 出现故障时,Operator 负责重新分配 IP 资源,并清理残留的端点状态。
排查提示:如果集群中出现 IP 地址冲突或节点间连通性异常,应优先检查 Operator 的日志和 IPAM 池状态。使用 cilium status 命令可以快速查看 Operator 的健康状况。

3.4 Cilium CNI 插件:容器网络入口

Cilium CNI 插件是一个轻量级二进制文件,由 kubelet 在创建或删除 Pod 时调用。它负责完成容器网络命名空间的初始化工作。

  1. 接口创建:在容器网络命名空间内创建 veth pair,一端留在宿主机,另一端放入容器。
  2. IP 分配:通过 Unix Socket 向本节点的 Cilium Agent 请求 IP 地址和安全标识。
  3. 路由配置:在容器内设置默认路由,指向宿主机端的 veth 接口。
  4. 端点注册:将新创建的端点信息(MAC、IP、标签)上报给 Agent,触发 eBPF map 的更新。
常见故障点:CNI 插件调用超时或失败,会导致 Pod 无法获取 IP 地址,进而影响缓存命中。排查时应检查 kubelet 日志中的 CNI 调用记录,以及 Agent 的 Unix Socket 响应时间。

3.5 Cilium DaemonSet 组件:运行环境保障

Cilium DaemonSet 是 Agent 的 Kubernetes 封装,确保每个节点上都有一个 Agent 实例在运行,并提供必要的运行环境。

  • 特权模式:DaemonSet 配置了特权容器,允许 Agent 访问宿主机的 eBPF 系统调用和内核模块。
  • 文件系统挂载:挂载宿主机的 /sys/fs/bpf 目录,使 Agent 能够持久化 eBPF map 和程序。
  • 资源限制:通过 requests 和 limits 控制 Agent 的 CPU 和内存使用,防止其影响其他系统组件。
  • 健康检查:配置 liveness 和 readiness 探针,确保 Agent 进程在异常退出时能被自动重启。

3.6 组件协作流程与缓存更新路径

下图展示了当一个新的 Pod 被创建时,各组件之间的协作流程,以及 eBPF 缓存(连接跟踪表)的更新路径:

Cilium 组件协作与缓存更新流程 Cilium 组件协作与 eBPF 缓存更新流程 kubelet Cilium CNI Cilium Agent eBPF Map (CT) Cilium Operator 调用 CNI ADD 请求 IP & ID 更新 CT 表 上报端点状态 IPAM 分配确认 缓存更新关键路径说明 1. kubelet 调用 Cilium CNI 插件创建 Pod 网络。 2. CNI 插件向本地 Agent 请求 IP 和安全标识。 3. Agent 分配资源后,立即更新 eBPF 连接跟踪(CT)map。 4. Agent 异步上报端点状态给 Operator,用于集群级协调。 缓存命中故障排查要点 如果步骤 3 中 Agent 未能及时更新 CT map,后续数据包将无法命中缓存,导致性能下降。应检查 Agent 的 eBPF map 写入延迟和 map 容量。

3.7 组件间通信与数据流

各组件之间的通信方式决定了故障排查的切入点。下表总结了关键通信路径及其使用的协议:

通信路径 协议/接口 数据内容 故障排查方法
kubelet → CNI 插件 Unix Domain Socket (stdin/stdout) CNI 标准 JSON 配置 查看 kubelet 日志中的 CNI 插件调用记录
CNI 插件 → Agent Unix Domain Socket (特定路径) 端点创建请求、IP 分配请求 使用 cilium-dbg endpoint list 检查端点状态
Agent → eBPF Map bpf() 系统调用 连接跟踪条目、策略规则、负载均衡后端 使用 bpftool map dump 查看 map 内容
Agent → Operator gRPC over TCP (Kubernetes API) 端点状态更新、节点资源报告 检查 Operator 日志中的 gRPC 连接状态
Operator → Kubernetes API HTTP/HTTPS CRD 状态更新、IPAM 资源协调 使用 kubectl get ciliumnodes 查看节点状态

3.8 故障排查核心命令速查

针对每个组件,以下命令可以帮助快速定位缓存命中相关的问题:

Agent 状态检查:
# 查看 Agent 健康状态
cilium status

# 列出所有本地端点及其安全标识
cilium-dbg endpoint list

# 查看连接跟踪表大小与命中率
cilium-dbg bpf ct list global
Operator 状态检查:
# 查看 Operator Pod 日志
kubectl logs -n kube-system -l io.cilium/app=operator

# 查看 IPAM 池使用情况
kubectl get ciliumnodes -o yaml | grep -A 10 ipam
CNI 插件调用检查:
# 查看 kubelet 日志中的 CNI 调用
journalctl -u kubelet -f | grep -i cni

# 检查 CNI 配置文件是否存在
ls /etc/cni/net.d/05-cilium.conflist
最佳实践:在排查缓存命中故障时,建议按照“Agent → eBPF Map → CNI → Operator”的顺序逐步检查。Agent 是数据平面的核心,eBPF Map 是缓存的实际载体,CNI 负责端点创建,Operator 负责集群协调。任何一环的异常都可能导致缓存命中率下降。