1. Cilium 与 eBPF 基础:架构、原理与 Kubernetes 角色

1.1 Cilium 架构概述

Cilium 是一个基于 eBPF(Extended Berkeley Packet Filter)的云原生网络、安全与可观测性项目。其核心设计理念是将 eBPF 程序动态注入 Linux 内核,在不修改内核代码或应用容器的情况下,实现高性能的网络策略执行与安全审计。

Cilium 架构主要分为控制平面与数据平面两部分:

组件 部署位置 核心职责
Cilium Agent 每个 Kubernetes 节点(DaemonSet) 管理 eBPF 程序生命周期;与 Kubernetes API Server 交互,监听 Pod/Service/NetworkPolicy 事件;编译并加载 eBPF 程序到内核。
Cilium Operator 集群内单实例或高可用部署 处理集群级任务:IPAM(IP 地址管理)、CiliumEndpoint 同步、KVStore 维护、多集群互联。
Cilium CNI 插件 每个节点(二进制) 实现 CNI 接口,负责 Pod 网络接口创建与 IP 分配,调用 Agent 完成 eBPF 数据路径配置。
eBPF 程序 Linux 内核(数据平面) 在 XDP、TC、cgroup、socket 等 hook 点执行,处理数据包转发、负载均衡、网络策略过滤、可观测性数据采集。
故障排查要点: 当 Cilium Agent 异常退出或与 API Server 断连时,节点上已加载的 eBPF 程序仍会继续工作,但新的 Pod 创建或策略变更将无法生效。这是 Cilium 架构中“控制平面故障不影响已有数据平面”的关键设计。
Cilium 核心架构组件关系图 Kubernetes API Server Cilium Operator Cilium Agent eBPF 程序 (XDP / TC / cgroup) Linux 内核数据平面 Cilium CNI 插件 Pod 网络接口 控制平面故障不影响已有数据平面

1.2 eBPF 工作原理

eBPF 是一项允许用户在 Linux 内核中安全运行沙箱化程序的技术。Cilium 利用 eBPF 实现网络数据包处理、系统调用过滤和性能监控,而无需加载内核模块或修改内核源码。

eBPF 程序的生命周期包含以下关键步骤:

  1. 编写与编译: 开发者使用 C 语言编写 eBPF 程序,通过 LLVM/Clang 编译为 eBPF 字节码。
  2. 验证: 用户态工具(如 bpftool)或 Cilium Agent 将字节码加载到内核。内核的 eBPF 验证器(verifier)对字节码进行静态分析,确保程序不会导致内核崩溃、死循环或越权访问。
  3. 加载与 JIT 编译: 验证通过后,内核将 eBPF 字节码即时编译(JIT)为本地机器指令,提升执行效率。
  4. 挂载到 Hook 点: 将 eBPF 程序附加到指定的内核事件点(如网络数据包到达、系统调用入口、函数进入/退出)。
  5. 事件驱动执行: 当内核事件触发时,eBPF 程序自动执行,处理数据或收集信息,并通过 eBPF Maps 与用户态交互。
故障排查提示: 当遇到 Cilium 网络策略不生效时,应首先检查 eBPF 程序是否成功加载。使用 cilium bpf policy list 命令查看当前节点上的 eBPF 策略映射表,确认策略条目是否存在。
eBPF 程序生命周期与执行流程 1. 编写 C 代码 2. LLVM 编译 3. 内核验证器 4. JIT 加载 5. 挂载 Hook 点 6. 事件驱动执行 eBPF Maps 故障排查关键点 验证失败(Verifier Error)是常见故障原因,通常由循环、指针越界或栈访问违规导致

1.3 Cilium 在 Kubernetes 中的角色

在 Kubernetes 集群中,Cilium 承担了多项关键基础设施角色,替代了传统的 kube-proxy 和部分 CNI 插件的功能:

角色 传统实现 Cilium 实现(基于 eBPF) 故障排查关注点
CNI 网络插件 Flannel / Calico(iptables 模式) eBPF 直接接管 Pod 网络接口创建与数据转发,支持原生路由、Overlay(VXLAN/Geneve)和直接路由。 Pod 网络不通时,检查 cilium status 确认 Node 连通性,以及 cilium endpoint list 查看 Pod 身份标识。
Service 负载均衡 kube-proxy(iptables/IPVS) eBPF 在 XDP/TC 层实现 Service 负载均衡,支持 DSR(Direct Server Return)、Maglev 一致性哈希、Session Affinity。 Service 访问异常时,使用 cilium service list 查看 eBPF 中的 Service 映射表,对比 Kubernetes Service 对象。
网络策略引擎 Kubernetes NetworkPolicy + iptables eBPF 程序在 L3/L4/L7 层执行网络策略,支持 DNS 感知策略、HTTP/gRPC 协议过滤、CIDR 规则。 策略未生效时,执行 cilium bpf policy get <endpoint-id> 查看该端点的完整策略决策链。
可观测性数据源 单独部署 Prometheus Exporter + 抓包工具 eBPF 程序直接采集网络流数据(L3/L4/L7)、TCP 状态、DNS 请求,通过 Hubble 暴露指标和流日志。 流量数据缺失时,检查 Hubble 是否启用以及 cilium hubble port-forward 连接状态。
安全审计与身份识别 基于 IP 的防火墙规则 基于 Kubernetes 身份标识(Pod 标签、ServiceAccount)生成安全身份(Security Identity),eBPF 程序据此执行策略。 身份冲突时,使用 cilium identity list 查看集群内所有安全身份及其标签映射。
常见故障场景: 当 Cilium 与 kube-proxy 同时运行时,可能导致 Service 负载均衡规则冲突。Cilium 官方推荐在安装时设置 kubeProxyReplacement=true 以完全替代 kube-proxy。若未设置,需确保两者规则不重叠,否则会出现间歇性连接超时。

1.4 关键概念:安全身份(Security Identity)

Cilium 不依赖 Pod IP 来执行网络策略,而是为每个 Pod 分配一个基于其标签和安全上下文的 安全身份(Security Identity)。这个身份是一个 24 位的数字标识符,存储在 eBPF Maps 中,作为策略决策的核心依据。

身份分配流程:

  • Pod 创建时,Cilium Agent 读取其标签和 ServiceAccount。
  • Agent 计算标签组合的哈希值,生成 Security Identity。
  • 该身份被写入本地 eBPF Maps,并同步到集群中所有节点的 eBPF Maps。
  • 当数据包到达时,eBPF 程序提取源/目的 Pod 的身份,查找策略规则,决定允许或拒绝。
故障排查技巧: 当网络策略意外阻止了合法流量时,使用 cilium endpoint get <pod-endpoint-id> 查看该端点的 Security Identity 和标签列表。对比策略定义中的标签选择器,确认身份匹配是否正确。身份不匹配是策略故障的首要排查方向。