如果你正在处理Cilium eBPF,先别急着照搬网上的参数。当你第一次成功部署 Kubernetes 集群,看着 Pod 一个个启动,网络通信顺畅无比时,可能觉得容器网络没什么大不了的。但一旦集群规模扩大——比如 200 个节点、上万条网络策略规则——传统的 iptables + kube-proxy 模式就会暴露出严重的性能问题:CPU 飙升、连接延迟忽高忽低、甚至节点陷入半死不活的状态。这正是 Cilium 被越来越多团队选中的原因。它的核心手段是 eBPF 和 XDP,让数据包处理从“内核态规则遍历”变成了“内核级即时裁决”。这篇文章只讲原理和落地,不扯玄学。
Cilium eBPF:传统 iptables 到底卡在哪里?
链式遍历:规则越多,开销越大
Kubernetes 通过 kube-proxy 在节点的 Netfilter 框架中插入大量 iptables 规则,实现 Service 负载均衡、网络策略过滤。每个进入节点的数据包都需要经过 NAT 表、Filter 表的多条链,而每条链上的规则是按顺序匹配的。当规则数量从几十条增长到几千条时,数据包在每个节点上的匹配时间会线性甚至超线性增加。实际线上环境,5000 条规则时 kube-proxy 的 CPU 占用可能达到 2-3 核,转发延迟从微秒级跳到毫秒级。
内核态与用户态上下文切换
iptables 规则每增加或修改一次,都会触发 iptables-restore 将所有规则重新加载到内核中,这个过程中用户态和内核态频繁切换,同时会锁住 Netfilter 子系统,导致短暂的数据包处理停顿。在需要频繁更新 Endpoint 的高密度 Pod 场景下,这种停顿可以被明显感知。
桥接问题:容器网络还多一层桥接
大部分 CNI 插件(如 Calico、Flannel)在节点上创建网桥(cbr0 或 docker0),容器流量先经过网桥,再经过 iptables 做 SNAT 或策略过滤。网桥本身对二层处理有一定损耗,再加上 iptables 的三层处理,整个转发路径长且不可控。
相关阅读:此处可内链到“Cilium eBPF常见问题”专题。
进阶阅读:此处可内链到“Cilium eBPF性能优化”指南。
eBPF:让内核变成可编程的“微型应用商店”
eBPF 不是补丁,而是一套虚拟机
Linux 内核从 4.x 就开始集成 eBPF(extended Berkeley Packet Filter)。你可以把它理解成内核内部的一个沙箱化虚拟机——允许用户编写一段 C 或 Rust 代码,编译成 BPF 字节码后,安全地加载到内核的特定 Hook 点(如系统调用、网络设备、函数入口)。代码运行在内核态,但受验证器严格检查:不得有死循环、不得访问未授权的内存、不得执行特权指令。所以既快又安全。
为什么 eBPF 能绕过 iptables?
传统 iptables 是 Netfilter 框架的一个用户配置接口,数据包要经过很多预定义的 Hook 点。而 eBPF 程序可以直接挂载到网络设备(包括虚拟以太网对、网桥、物理网卡)的 tc(Traffic Control)层或 XDP(eXpress Data Path)层。换句话说,eBPF 在网络栈的最前端就拦截数据包,根本不给数据包走到 Netfilter 链条的机会——自然也就绕过了 iptables 的所有开销。
关联教程:此处可内链到“Cilium eBPF部署与验证”内容。
XDP:在网卡驱动里就把活干了
XDP 比 eBPF 更“早”
XDP 是 eBPF 的一个特殊 attach 类型,它运行在网络驱动接收数据包之后、内核协议栈处理之前。也就是说,数据包还在 RX 环上时,XDP 程序已经可以决定:丢弃、转发到另一个网口、提交给上层、还是修改数据包内容。由于不经过协议栈的 skb(套接字缓冲)分配和一系列的 Netfilter 检查,XDP 能达到线速处理,单核吞吐可达几十 Mpps(百万包每秒)。
XDP 对比 iptables 的转发路径
- 传统路径:网卡 -> 驱动 -> skb 分配 -> 协议栈(IP、TCP)-> Netfilter 钩子(iptables)-> 路由 -> 网卡发送。
- Cilium + XDP 路径:网卡 -> 驱动 -> XDP 程序(eBPF)-> 重定向到目标网卡(或虚拟网卡)-> 驱动发送。
这个差异在容器网络里尤其明显。节点上的每个 Pod 的 veth 对都可以被 XDP 程序接管,数据包从 Pod 出来的一瞬间就被 Cilium 决定去哪,而不需要经过任何 bridge 和 iptables 规则。
Cilium 的架构设计:如何组织 eBPF 和 XDP?
Cilium Agent 是大脑,eBPF 是手脚
Cilium 在每个节点上运行一个 Agent(通常以 DaemonSet 部署)。这个 Agent 负责与 Kubernetes API Server 交互,收集 Service、Endpoint、NetworkPolicy 等信息,然后编译成对应的 eBPF 程序(C 代码)并加载到内核。它本身不处理数据包,只负责管理 eBPF 对象。
数据面:三种 Hook 点协同
- XDP:用于入口流量(Ingress),直接挂载在物理网卡或 veth 对的主机端。适合做 DDoS 防护、负载均衡的快速重定向。
- TC Ingress/Egress:在协议栈的 tc 层挂载 eBPF,用于处理更复杂的逻辑(如 L7 协议过滤、IP 伪装)。Cilium 默认使用 tc 作为主力数据面,因为它的 API 更容易操作 skb。
- cgroup 挂载点:用于限制特定 cgroup 中进程的网络访问,主要用于安全策略。
用 Map 代替规则列表
传统 iptables 使用链表存储规则,匹配时遍历。Cilium 使用 eBPF Map(哈希表或数组),查表时间复杂度 O(1)。例如,流量策略记录在 bpf_policy_map 中,数据包到达时直接 key 查找,秒级匹配。当 Service Endpoint 变更时,Agent 只更新 Map 条目,不需要重载整个规则集,更新开销可忽略不计。
上手体验:用 kind 启动 Cilium 集群——Cilium eBPF
环境准备
确保你的 Linux 内核版本 ≥ 5.10(建议 5.15+)。使用 kind(Kubernetes in Docker)快速搭建测试集群:
kind create cluster --name cilium-demo
安装 Cilium
cilium install --version 1.15.0 --set kubeProxyReplacement=true
kubeProxyReplacement=true 是关键配置:完全接管 kube-proxy 的职责,关闭节点上的 iptables 转发。
验证 eBPF 数据面是否生效
cilium status --verbose
你会看到类似如下输出:
...
╟ Host Routing: Legacy
╟ KubeProxyReplacement: Disabled (iptables mode disabled: eBPF mode enabled)
╟ Bandwidth Manager: Enabled with EDT
...
同时可以查看挂载的 eBPF 程序:
bpftool prog list | grep cilium
你会看到一系列 cil_* 命名的程序,挂载在 tc 和 xdp 上。
测试网络延迟变化
部署一个测试 Pod:
kubectl run test --image=busybox -- sleep 3600
在 Pod 内执行 ping 外部 Service,观察延迟:
ping 10.96.0.1 (kubernetes service IP)
对比传统 iptables 模式(可以临时用 kube-proxy 重跑测试),你会发现延迟抖动明显减少,尤其是在 Service 名称解析和连接建立阶段。
想继续深入:此处可内链到“Cilium eBPF优化清单”文章。
风险与回滚:从 iptables 切换到 eBPF 需要注意什么?
内核版本兼容性
Cilium 1.15 要求内核 ≥ 4.19,但 XDP 降级功能会受限;推荐 5.10 以上。如果你的节点使用的是 CentOS 7(内核 3.10),基本无法运行 Cilium 的 eBPF 数据面,必须考虑升级内核。
kubeProxyReplacement 的副作用
开启完全替换后,节点上的 iptables 将不再用于 Kubernetes 流量。如果你有第三方工具也依赖 iptables(比如某些网络监控 agent、手动配置的 DNAT 规则),它们会失效。建议先在测试环境验证所有依赖。
回滚方案
cilium uninstall
kubeadm upgrade node ... 或重新启用 kube-proxy
Cilium 卸载后 eBPF 程序自动释放,节点恢复使用 iptables。注意 CNI 配置文件也会被清理,重新安装 kube-proxy 即可。
补充参考:此处可内链到“Cilium eBPF故障排查实例”。
总结:无 iptables 开销不是魔法,是内核工程取舍
先看关键判断
Cilium 并没有发明新硬件,而是把 Linux 内核自 2014 年就开始提供的 eBPF 能力真正用到了容器网络场景。它牺牲了 iptables 的通用性(任何用户都能写规则),换取了极高的性能和灵活性。对于日均千万级连接或超大规模集群来说,这个取舍非常值得。下一次当你面对 kube-proxy 导致的性能瓶颈时,别再想着拷打运维加机器了——试试 Cilium,把数据包处理权从小黑屋的 iptables 手里夺回来。按这个顺序复查,Cilium eBPF遇到异常时也更容易定位。
延伸阅读
