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 架构中“控制平面故障不影响已有数据平面”的关键设计。
1.2 eBPF 工作原理
eBPF 是一项允许用户在 Linux 内核中安全运行沙箱化程序的技术。Cilium 利用 eBPF 实现网络数据包处理、系统调用过滤和性能监控,而无需加载内核模块或修改内核源码。
eBPF 程序的生命周期包含以下关键步骤:
- 编写与编译: 开发者使用 C 语言编写 eBPF 程序,通过 LLVM/Clang 编译为 eBPF 字节码。
- 验证: 用户态工具(如 bpftool)或 Cilium Agent 将字节码加载到内核。内核的 eBPF 验证器(verifier)对字节码进行静态分析,确保程序不会导致内核崩溃、死循环或越权访问。
- 加载与 JIT 编译: 验证通过后,内核将 eBPF 字节码即时编译(JIT)为本地机器指令,提升执行效率。
- 挂载到 Hook 点: 将 eBPF 程序附加到指定的内核事件点(如网络数据包到达、系统调用入口、函数进入/退出)。
- 事件驱动执行: 当内核事件触发时,eBPF 程序自动执行,处理数据或收集信息,并通过 eBPF Maps 与用户态交互。
故障排查提示: 当遇到 Cilium 网络策略不生效时,应首先检查 eBPF 程序是否成功加载。使用
cilium bpf policy list 命令查看当前节点上的 eBPF 策略映射表,确认策略条目是否存在。
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 和标签列表。对比策略定义中的标签选择器,确认身份匹配是否正确。身份不匹配是策略故障的首要排查方向。