jimyag's Blog

Cilium Netkit:容器网络设备与数据路径

Kubernetes Pod 网络常用 veth(Virtual Ethernet)连接容器与宿主机。本文看 Linux netkit 设备与 Cilium 的 Pod 设备模式如何改变这条数据路径,以及启用时有哪些内核和迁移条件。

背景:veth 的局限性

先看 veth 模式下的数据包路径。

网络命名空间与 veth

Kubernetes 中,每个 Pod 通常有独立的网络命名空间(Network Namespace)。veth 对连接两个命名空间很方便;评估其开销时,需要看设备与内核数据路径,而不能把经过命名空间边界等同于进程上下文切换。

  graph LR
    subgraph "Pod 命名空间"
        A[Container]
    end
    
    subgraph "Host 命名空间"
        B[veth peer]
        C[Host Networking<br/>Cilium Datapath]
        D[Host Network]
    end
    
    A -->|veth pair| B
    B --> C
    C --> D

veth 的工作原理:

  • veth 设备自 2008 年引入 Linux 内核
  • 创建一对虚拟以太网设备,一端在容器内,一端在宿主机上
  • 数据包在容器和宿主机之间传输时,需要跨越网络命名空间边界
  • 数据包跨设备与命名空间边界时,仍要经过相应的内核收发路径

veth 的性能瓶颈

根据 Cilium 官方文档和 FOSDEM 2025 的公开分享,veth 在大规模容器场景下主要有以下问题:

  1. 命名空间切换开销:数据包从容器到宿主机需要穿越命名空间边界
  2. 内核网络栈处理:数据包经过 veth 收发队列和相应的内核处理路径
  3. BPF 程序管理的复杂性:在 veth 上附加 BPF 程序需要针对 peer 设备单独管理
  4. 有限的 eBPF 可编程性:veth 并非为 eBPF 原生设计

Netkit 简介

什么是 Netkit

Netkit 是一种 BPF 可编程的网络设备(BPF Programmable Network Device),它专为容器网络场景设计。netkit 设备在 Linux 内核 6.7 中引入;但如果你关注的是 Cilium 的 netkit datapath mode,官方要求的内核版本是 6.8 及以上。

注意:不要将 Netkit 与早期的 Netkit(用于在单台服务器上创建虚拟网络的项目,已停止维护)混淆。

Netkit 的核心特性

  graph TB
    subgraph "Netkit 设备"
        A[Netdev<br/>主设备]
        B[Netdev<br/>对端设备]
    end
    
    subgraph "BPF Integration"
        C[Pod BPF Programs]
        D[TCX Attachments]
        E[eBPF Host-Routing]
    end
    
    A --> C
    A --> D
    A --> E
    A <-->|peer| B

关键特性:

  1. 面向容器场景设计:netkit 不是通用虚拟网卡的简单替代,而是围绕容器 datapath 设计
  2. 更适合与 Cilium 的 BPF datapath 配合:Pod 侧 BPF 程序可以挂到 netkit peer device 上
  3. TCX 支持:Cilium 在启用 netkit 时也会在其他非 netkit 设备上使用 tcx attachment
  4. 更低的 datapath 开销:配合 eBPF host-routing,可减少传统 veth 路径中的额外处理

技术原理:Netkit vs veth

veth 的数据包流程

使用 veth 时,数据包从容器到外部网络的路径如下:

1
Container → veth pair → Network Namespace Switch → Host Stack → External

每个步骤都涉及:

  • 上下文切换
  • 队列排队
  • 内核处理延迟

Netkit 的数据包流程

Netkit 优化了这一流程:

1
Container → netkit device → Pod BPF Program → eBPF Host-Routing → External

通过 eBPF Host-Routing 和 netkit 的组合,数据包可以:

  • 绕过部分宿主机上层网络栈
  • 减少传统 veth 模式下的额外 datapath 开销
  • 在 off-node ingress / egress 场景下实现更快的网络命名空间切换

netkit 与 tcx 的关系

  sequenceDiagram
    participant C as Container
    participant N as Netkit Peer
    participant BPF as Pod BPF Program
    participant H as Host Stack
    
    C->>N: 数据包入站
    N->>BPF: BPF 程序触发
    BPF->>BPF: 策略检查/转发决策
    alt 直接转发
        BPF->>H: Host-Routing Fast Path
    else 需要处理
        BPF->>N: 注入处理
        N->>H: 完整处理
    end

官方文档里,Cilium 对 netkit 的描述重点有两点:

  1. Pod BPF 程序挂载位置变化:Pod 相关 BPF 程序挂在 netkit peer device 上,并且只能从 host namespace 管理
  2. tcx attachment 一并启用:开启 netkit 后,Cilium 也会在非 netkit 设备上使用 tcx,以获得更高效的 attachment 方式

性能提升

基准测试结果

公开资料普遍给出的结论是:netkit 的收益主要体现在降低延迟和减少 datapath 开销,但提升幅度与 workload、内核版本、是否启用 eBPF host-routing 等因素强相关,因此不宜脱离测试上下文直接给出统一数字。

例如,Meta 在 FOSDEM 2025 的分享中给出的一个案例是:同机 4 份副本叠加运行时,P99 延迟曾因 SoftIRQ 压力超过 12 秒;启用 netkit 后,P99 延迟下降到约 100ms。这个数字很亮眼,但它描述的是特定场景下的实测结果,不应直接外推到所有环境。

ByteDance 的实践

字节跳动(ByteDance)是 netkit 技术的早期采用者之一。公开报道显示,他们正在面向百万级容器规模推进这项技术,并已在多个集群中落地验证。

“设置 veth 和 netkit 没有太大区别,但要达到最佳性能,eBPF 程序需要针对 netkit 进行优化。” —— The New Stack 报道

从公开材料看,字节跳动关注的重点包括:

  1. 大规模部署验证:逐步验证 netkit 在大规模容器场景下的稳定性
  2. 内核能力补齐:他们分享过在较老内核上回补相关能力的实践
  3. CNI / eBPF 适配:为了发挥 netkit 的收益,需要配套更新 CNI 和 BPF 程序

Meta 的贡献

Meta 的工程师也在积极推动 Netkit 的发展:

  • 在 FOSDEM 2025 上分享了 Netkit 的实践经验
  • 优化 Meta 容器平台的网络性能
  • 推动 Netkit 在云原生生态中的 adoption

Cilium 集成

Cilium 1.16+ 的 netkit 支持

Cilium 1.16 开始支持把 netkit 作为新的 datapath mode 使用,但它默认仍然使用 veth。

配置方式:

1
2
3
4
5
6
7
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set routingMode=native \
  --set bpf.datapathMode=netkit \
  --set bpf.masquerade=true \
  --set kubeProxyReplacement=true

如果你要按节点逐步灰度,也可以使用 CiliumNodeConfig 覆盖对应 agent 配置;但本质上仍然是覆盖 bpf.datapathMode 等参数,而不是单独写一个 netkit.enabled=true 开关。

自动检测与回退

Cilium 对 netkit 的行为要分两种情况理解:

  • bpf.datapathMode=netkit:如果内核或依赖能力不满足要求,Cilium 会启动失败,而不是自动回退
  • bpf.datapathMode=auto:只有在这个模式下,Cilium 才会在运行时检测是否支持 netkit,支持则使用 netkit,否则回退到 veth

性能调优建议

1
2
3
4
5
# 检查当前 Device Mode
cilium status

# 或在 Cilium Pod 内检查关键状态
kubectl -n kube-system exec <cilium-pod> -c cilium-agent -- cilium status

需要重点确认两项:

  • Device Mode 是否为 netkit
  • Host Routing 是否为 BPF

最佳实践:

  1. 区分内核引入版本与 Cilium 要求版本:Linux netkit 是 6.7 引入,但 Cilium 官方要求 netkit mode 使用 6.8+
  2. 配合 eBPF Host-Routing 使用:这是官方强调的前提条件之一
  3. 按节点灰度,而不是原地替换:官方明确说明,已有 veth Pod 的集群不能直接 in-place 切到 netkit
  4. 启用 kubeProxyReplacement 与 BPF masquerade:这是官方示例中的推荐组合

总结

netkit 代表了容器网络设备设计的一次重要演进。对 Cilium 用户来说,它的价值不只是“换一种 Pod 网卡”,而是和 eBPF host-routing、tcx attachment 等能力一起,尽量减少传统 veth 模式里的额外 datapath 开销。

关键要点:

  • netkit 设备在 Linux 内核 6.7 引入,但 Cilium 官方要求 netkit datapath mode 使用 6.8+ 内核
  • Cilium 1.16+ 已支持 netkit datapath mode,不过默认仍然是 veth
  • netkit 通常需要和 eBPF host-routing 组合使用,收益主要体现在降低延迟和减少 datapath 开销
  • bpf.datapathMode=netkit 不会自动回退;只有 auto 模式才会在支持时启用 netkit、否则回退到 veth
  • 已有 veth Pod 的集群不能直接原地切换到 netkit,更适合按节点灰度迁移

是否启用 netkit,应结合内核版本、Cilium 配置、现有 Pod 的设备模式和目标工作负载实测。


参考资料:

#Kubernetes #Cilium #Netkit #EBPF #Network #Performance