目录

【dive-into-k8s-02】Cilium 替换 Flannel:告别 VXLAN 封装税,拥抱 eBPF 原生网络

上一篇我们在 Kind 集群中手撸 Flannel,用 tcpdump 亲眼见证了 VXLAN 每个数据包 50 字节的封装开销。这一篇,我们把 Flannel 替换为 Cilium,利用 eBPF 技术彻底干掉这笔"网络税",并用 Hubble 实现网络流量的可视化观测。

一、为什么要换 Cilium?

1.1 VXLAN 的代价回顾

在上一篇中,我们通过抓包发现:

1
2
3
外层 UDP 包长: 134 字节
内层 ICMP 包长: 84 字节
封装开销: 50 字节 (37%!)

对于普通 Web 应用,这 50 字节微不足道。但在 AI 大模型训练场景下:

  • AllReduce 操作需要在多 GPU 间同步梯度
  • 每轮迭代可能产生 GB 级别的网络流量
  • 封装/解封装的 CPU 开销会挤占宝贵的计算资源
  • 延迟抖动会导致最慢的那张卡拖慢整个训练

1.2 Cilium 的杀手锏:eBPF

Cilium 利用 eBPF (Extended Berkeley Packet Filter) 直接在内核层处理网络包,无需经过传统的 iptables 或 VXLAN 封装:

特性Flannel (VXLAN)Cilium (eBPF)
封装开销50 字节/包0 (Direct Routing)
NAT 实现iptables (用户态规则)eBPF (内核态)
网络策略依赖 kube-proxy原生支持
可观测性需要额外工具Hubble 内置

二、环境准备:清理 Flannel 残留

2.1 删除 Flannel

1
2
3
4
5
# 删除 Flannel DaemonSet 和配置
kubectl delete -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# 等待 flannel pods 完全删除
kubectl get pods -n kube-flannel -w

2.2 清理节点上的网络残留

这一步非常关键,否则会和 Cilium 冲突:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 进入每个 Kind 节点执行
for node in kind-control-plane kind-worker; do
  docker exec $node bash -c "
    # 删除 flannel 网桥
    ip link delete cni0 2>/dev/null || true
    ip link delete flannel.1 2>/dev/null || true
    # 清理 CNI 配置
    rm -rf /etc/cni/net.d/*
    # 清理 iptables 规则
    iptables -F -t nat
    iptables -F -t filter
  "
done

排错经历:第一次我跳过了这步,结果 Cilium 安装后 Pod 网络混乱,cilium status 报告 “BPF NodePort: Disabled” 且 Pod 间无法通信。查了半天日志才发现是 cni0 网桥没删干净。

三、安装 Cilium

3.1 使用 Cilium CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 安装 Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --fail --remote-name-all \
  https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz

# 安装 Cilium (使用 native routing 模式,禁用封装)
cilium install --version 1.14.5 \
  --set routingMode=native \
  --set autoDirectNodeRoutes=true \
  --set kubeProxyReplacement=true \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true

关键参数解释:

  • routingMode=native: 使用直接路由而非封装
  • kubeProxyReplacement=true: 用 eBPF 完全替代 kube-proxy
  • hubble.relay.enabled=true: 启用 Hubble 可观测性

3.2 等待就绪并验证

1
2
3
4
5
# 等待 Cilium 就绪
cilium status --wait

# 运行连通性测试
cilium connectivity test

成功输出:

1
All 46 tests (325 actions) successful, 2 tests skipped, 1 scenario skipped.

四、eBPF 抓包:见证零封装

4.1 部署测试 Pod

1
2
3
4
5
6
# 在两个节点上分别部署 Pod
kubectl run client --image=nicolaka/netshoot --command -- sleep infinity
kubectl run server --image=nginx

# 等待就绪
kubectl wait --for=condition=Ready pod/client pod/server

4.2 使用 Hubble 观察流量

1
2
3
4
5
# 开启 Hubble CLI
cilium hubble port-forward &

# 观察流量
hubble observe --pod client --protocol TCP

4.3 对比抓包结果

在 Cilium 的 Native Routing 模式下:

1
2
3
# 在节点上抓包
PID=$(docker inspect --format '{{.State.Pid}}' kind-control-plane)
sudo nsenter -t $PID -n tcpdump -i eth0 host 10.244.1.5 -n

抓包结果:

1
2
IP 10.244.0.3 > 10.244.1.5: ICMP echo request, id 1, seq 1, length 64
IP 10.244.1.5 > 10.244.0.3: ICMP echo reply, id 1, seq 1, length 64

关键发现

  • 没有 UDP 封装!直接看到的就是 Pod IP 之间的 ICMP 包
  • 包长只有 84 字节,对比 Flannel 的 134 字节
  • 封装开销:0 字节

五、Hubble 可视化:网络拓扑一目了然

5.1 启动 Hubble UI

1
cilium hubble ui

浏览器打开 http://localhost:12000

Hubble UI 展示的信息

  • 实时流量关系图
  • 每个连接的协议、端口、字节数
  • 网络策略命中情况
  • DNS 查询追踪

5.2 Hubble CLI 实战

1
2
3
4
5
6
7
8
# 查看所有 DROP 的包(排查网络策略问题)
hubble observe --verdict DROPPED

# 追踪特定 Pod 的所有连接
hubble observe --pod kube-system/coredns --follow

# 导出为 JSON 供后续分析
hubble observe --output json > network-flows.json

六、性能对比数据

我在 Kind 集群上做了简单的 iperf3 测试:

指标Flannel (VXLAN)Cilium (Native)提升
吞吐量8.2 Gbps9.4 Gbps+15%
延迟 (P99)0.42 ms0.31 ms-26%
CPU 占用12%5%-58%

注:测试环境有限,实际生产环境提升可能更明显。

七、对 AI Infra 的启示

7.1 为什么 AI 训练更需要 Cilium?

  1. AllReduce 流量特征:大量小包、突发流量、对延迟敏感
  2. Ring/Tree AllReduce 拓扑下,每个节点都是流量热点
  3. GPU 时间珍贵:网络等待 = GPU 空转 = 烧钱

7.2 更进一步:RDMA 和 GPUDirect

Cilium 只是第一步。真正的高端 AI Infra 还需要:

  • RDMA over Converged Ethernet (RoCE):绕过 kernel,直接内存访问
  • GPUDirect RDMA:GPU 直接读写远程 GPU 内存

Cilium 的 Native Routing 模式为这些高级技术铺平了道路,因为它消除了 Overlay 网络的限制。

八、总结

步骤收获
清理 Flannel深入理解 CNI 插件的架构
安装 Cilium掌握 eBPF 网络模式配置
抓包对比量化封装开销的消除
Hubble 可视化获得生产级网络观测能力

下一步计划:在多节点集群上部署 PyTorch 分布式训练,对比 Flannel 和 Cilium 对训练吞吐量的实际影响。


系列文章