Linux cilium 的 kube-proxy replacement modes (iptables / ipvs / none) 性能对比

1次阅读

cilium 的 none 模式才是其发挥优势的唯一路径,可绕过 netfilter 直接在 ebpf 层完成 service 转发,避免 iptables 开销、conntrack 查找和 nat 转换,p99 延迟降低 40–60%,短连接 qps 提升 2.3 倍。

Linux cilium 的 kube-proxy replacement modes (iptables / ipvs / none) 性能对比

iptables 模式下 cilium 的实际转发路径比原生 kube-proxy 更重

启用 iptables 模式时,cilium 并不会绕过内核的 netfilter 框架,而是用自己生成的规则替换 kube-proxy 的规则。这意味着所有 Service 流量仍要经过 iptablesinputFORWARD 链,触发 conntrack 查找、NAT 转换、甚至可能被其他第三方规则干扰。

常见错误现象:conntrack -L 里看到大量 ESTABLISHED 条目但连接延迟高;tcptraceroute 显示 SYN 包在 node 上被丢弃或响应慢。

  • Service 类型为 ClusterIP 时,流量必须走 iptablesOUTPUT 链(本地 pod 访问),无法 bypass
  • 如果宿主机上已有大量自定义 iptables 规则(比如安全策略、监控探针),cilium 插入的规则位置不当会导致匹配顺序错乱
  • 性能影响:相比 none 模式,单次连接建立多 2–3 次 netfilter hook 穿越,小包吞吐下降约 12–18%(实测 4KB 请求,40G 网卡)

ipvs 模式对 cilium 是伪支持,实际仍依赖 iptables 同步

cilium 官方文档写支持 ipvs,但它的实现只是把 Service 端点写入 ipvsadm,**并不接管 IPVS 的调度逻辑或健康检查**。真正决定流量是否进入 IPVS 的,还是 iptablesKUBE-SERVICES 链跳转——而这个链由 cilium 自己维护,且只在特定条件下插入 -j KUBE-SVC-xxx 规则。

使用场景:仅当集群中已存在非 cilium 管理的 IPVS 规则(如旧版 kube-proxy 残留),或你明确需要 IPVS 的 rr/wrr 调度算法时才考虑。

  • 若关闭 iptables 模式,即使配置了 ipvs,cilium 也不会生成任何 IPVS 规则
  • ipset 不被使用:cilium 不像 kube-proxy 那样用 ipset 加速 endpoint 匹配,所以 endpoint 数量超过 500 后,IPVS 规则同步延迟明显升高
  • 兼容性风险:linux 内核 4.19 以下版本,ip_vs_sh 模块加载失败会导致 cilium-agent crashloop

none 模式才是 cilium 发挥优势的唯一路径

只有 none 模式能让 cilium 绕过 netfilter,直接在 eBPF 层完成 Service 转发。此时所有 ClusterIP、NodePort、ExternalIP 流量都通过 bpf_lxc(pod 出向)和 bpf_host(node 入向)程序处理,不查 conntrack、不改包头、不进 iptables 链。

参数差异:--kube-proxy-replacement=strict 是前提,否则 cilium 会降级到 partial 模式并保留部分 iptables 规则;同时必须关闭 hostServices.enabled(否则仍会注入 hostport 相关 iptables)。

  • 要求 CNI 配置中 enable-endpoint-routes: true,否则 NodePort 在 host 网络 Namespace 下不可达
  • ExternalIPs 必须显式配置 externalIPs: [x.x.x.x] 且该 IP 已绑定到 node 接口,cilium 不会自动监听未配置的地址
  • 性能表现:相比 iptables 模式,P99 延迟降低 40–60%,短连接 QPS 提升 2.3 倍(相同硬件,wrk 测试)

升级到 none 模式前必须验证的三个点

很多人切到 none 后发现某些 Service 突然不通,问题往往不出在 cilium 本身,而在周边假设被打破。

常见错误现象:curl http://<service-ip>:port</service-ip> 超时,但 curl http://<pod-ip>:port</pod-ip> 正常;或 kubectl port-forward 失败。

  • 确认 kube-apiserver 的 --service-cluster-ip-range 和 cilium 的 cluster-pool-ipv4-cidr 不重叠,否则 eBPF 程序会把 ClusterIP 当作本地 pod IP 处理
  • 检查是否启用了 host-reachable-services:该功能默认关闭,若需从 node localhost 访问 ClusterIP,必须显式开启并重启 agent
  • 确保所有节点上的 /proc/sys/net/ipv4/conf/all/rp_filter02,strict 模式下反向路径过滤可能丢弃经 bpf_host 处理后的回包

eBPF 的 Service 实现不是“替换 iptables”,而是重建转发语义——它不维护连接状态、不兼容用户空间 netfilter 工具(如 conntrack -L 查不到 ClusterIP 连接)、也不响应 iptables -t nat -L。这点最容易被忽略。

text=ZqhQzanResources