叠加网络还是直连路由?Cilium 两种数据路径的生产选型避坑指南
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
在 Kubernetes 网络插件(CNI)的选型讨论中,Cilium 几乎总被推到台前:基于 eBPF 的数据平面、内建的 Service 负载均衡、Hubble 可观测性、还有被反复宣传的"高性能"。但真正到了生产落地,绝大多数团队首先面对的并不是这些光环,而是一个更朴素、却决定后续所有架构决策的问题——Pod 跨节点流量到底走叠加(Overlay)还是直连路由(Direct/Native Routing)?
这个选择不仅影响首包延迟和吞吐,还牵扯到 MTU 计算、防火墙规则、NAT 行为、公有云 VPC 集成方式,甚至决定你能否无缝使用 BBR、XDP 加速等进阶特性。本文结合 Cilium 仓库源码与社区一线实践(网易数帆、腾讯云 TKE 的落地经验),把两种数据路径的原理、差异与生产避坑点一次讲透。
一、原理对比:隧道网格 vs 内核路由
Cilium 的数据路径选型在源码中对应一个非常直白的配置项:routing-mode。在 pkg/option/config.go 中,其取值被定义为一个三态枚举:
// RoutingModeNative specifies native routing mode RoutingModeNative = "native" // RoutingModeTunnel specifies tunneling mode RoutingModeTunnel = "tunnel" // RoutingModeHybrid specifies hybrid mode RoutingModeHybrid = "hybrid"叠加模式(Overlay / Tunneling):默认选项
值得注意的是,叠加模式是 Cilium 的默认行为。官方文档在 Documentation/network/concepts/routing.rst 中明确写到:"When no configuration is provided, Cilium automatically runs in this mode",并指出这是"对底层网络基础设施要求最少"的模式。
其原理是:所有 Cilium 节点之间形成一个UDP 封装的隧道网格(mesh),集群内跨节点的 Pod 流量全部通过 VXLAN 或 Geneve 封装后在底层 IP 网络上传送。封装协议与端口的默认值在源码中写得很清楚:
- 隧道设备名:
cilium_vxlan/cilium_geneve(见 pkg/defaults/node.go) - 默认端口:VXLAN 8472/UDP、Geneve 6081/UDP(见 pkg/defaults/defaults.go)
封装协议本身的枚举定义在 pkg/datapath/tunnel/tunnel.go:
const ( // VXLAN specifies VXLAN encapsulation VXLAN EncapProtocol = "vxlan" // Geneve specifies Geneve encapsulation Geneve EncapProtocol = "geneve" )这种"隧道网格"的架构带来了几个关键特性:底层网络完全不需要感知 PodCIDR,节点只要 IP/UDP 可达即可;Pod 地址空间不受底层限制;新节点加入集群后自动并入网格。更妙的是,VXLAN/Geneve 封装头部可以携带 Cilium 的安全身份(Security Identity)元数据,远端节点收到封装包后可以直接读取身份,省去一次身份查询——这是叠加模式下"身份上下文随包传输"的天然优化。
直连路由模式(Native Routing):交给内核
直连模式通过routing-mode: native启用。它的哲学截然相反:放弃封装,把非本节点 Pod 的流量直接交给 Linux 内核路由子系统,如同本机进程发包一样处理。这意味着底层网络必须有能力路由 PodCIDR。
官方文档用一张架构图描述了这种模型(见 native_routing.png):Pod 流量经 veth 进入宿主机,再通过内核路由表直接转发到对端节点,中间不经过任何隧道设备。
需要强调的是,直连路由并不等于"放弃 eBPF"。Cilium 的 eBPF 程序依然挂在 veth 与宿主机网络设备上,负责策略执行、Service 负载均衡等,只是跨节点转发这一跳从"封装/解封装"变成了"内核路由"。这也是为什么两种模式下都能用 eBPF 替换 kube-proxy——官方在 Documentation/network/kubernetes/kubeproxy-free.rst 中明确:"Cilium's eBPF kube-proxy replacement is supported in direct routing as well as in tunneling mode."
二、源码视角:MTU 与配置的真正差异
两种模式最直接、也最容易被忽视的差异藏在MTU 计算里。在 pkg/mtu/mtu.go 中,Cilium 精确量化了每种封装的字节开销:
// TunnelOverheadIPv{4,6} is an approximation for bytes used for tunnel // encapsulation. It accounts for: // IPv4 IPv6 // (Outer ethernet is not accounted against MTU size) // Outer IP header: 20B 40B // Outer UDP header: 8B 8B // Outer VXLAN header: 8B 8B // Original Ethernet: 14B 14B // --- --- // Total extra bytes: 50B 70B TunnelOverheadIPv4 = 50 TunnelOverheadIPv6 = 70也就是说,VXLAN 模式下每个包比直连模式多消耗 50 字节(IPv4 底层)。默认 1500 字节的物理 MTU 下,Pod 网卡 MTU 会被自动降为 1450。MTU 的连锁反应是真实存在的:网易数帆在其 Cilium 落地实践中就专门处理过链路 MTU 适配问题,社区里因"Pod 间大包无法传输"而排查 MTU 的案例也屡见不鲜。
配置入口同样有明确分工。叠加模式涉及三个参数(见 Documentation/network/concepts/routing.rst):
tunnel-protocol:封装协议,默认vxlan;underlay-protocol:底层 IP 族,默认auto(IPv4 优先,IPv6 兜底);tunnel-port:封装端口,默认 8472(VXLAN)/ 6081(Geneve)。
直连模式则要求必须配置ipv4-native-routing-cidr(如10.0.0.0/8),并配套以下可选项:
auto-direct-node-routes: true:所有节点共享同一 L2 网络时,由 Cilium 自动在各节点插入直达路由;direct-routing-skip-unreachable: true:配合 BGP 部署在多可用区场景下使用,避免流量总是绕经 BGP 路由器。
源码中的辅助函数把两种模式的语义边界刻画得很清晰(pkg/option/config.go):
// TunnelingEnabled returns true if tunneling is enabled. func (c *DaemonConfig) TunnelingEnabled() bool { // We check if routing mode is not native rather than checking if it's // tunneling because, in unit tests, RoutingMode is usually not set and we // would like for TunnelingEnabled to default to the actual default // (tunneling is enabled) in that case. return c.RoutingMode != RoutingModeNative } // RequiresNativeRouting returns true if the agent needs to use native routing to implement some features. func (c *DaemonConfig) RequiresNativeRouting() bool { return c.RoutingMode == RoutingModeNative || c.RoutingMode == RoutingModeHybrid }注意这里有个容易被误解的点:"native 以外的模式都算叠加",包括hybrid。混合模式(hybrid)在 Cilium 里意味着隧道与直连路由并存,由 Cilium 根据目标自动选择封装或直连路径——社区实践中,这种模式通常被用于"默认叠加保证可达、特定 CIDR 走直连换取性能"的折中场景。
三、性能与运维差异:不止是 50 字节
吞吐与延迟:直连更快,但别只看基准
叠加模式每包多 50 字节封装头、多一次隧道设备的进出,首包延迟与吞吐上限天然吃亏。官方文档也坦承:"this results in a lower maximum throughput rate for a particular network connection"。但官方同时给出了关键解法——巨型帧(Jumbo Frames):50 字节开销摊在 1500 字节上是 3.3%,摊在 9000 字节上就只剩 0.6%,差距被大幅抹平。
而直连路由的真正性能红利,更多来自与 eBPF 快速路径的叠加。比如带宽管理器(Bandwidth Manager)中的 BBR 拥塞控制,官方在 Documentation/network/kubernetes/bandwidth-manager.rst 中说明:带宽限制功能两种模式都支持,但BBR for Pods 依赖 eBPF Host-Routing 且要求内核 5.18+——eBPF 主机路由默认只在直连/混合模式下完整生效。这意味着如果追求极限吞吐与低延迟(如数据库、缓存类中间件),直连模式 + eBPF 主机路由 + BBR 是一条完整的性能链路。
运维差异:NAT、防火墙与网络策略
叠加模式的"物理网络无感"是有代价的:底层网络和防火墙必须放行 8472/UDP(VXLAN)或 6081/UDP(Geneve)。私有云或 IDC 里,这往往意味着要协调网络团队在交换机/安全组上额外开端口;而直连模式则没有隧道端口要求,却要求全网路由可达 PodCIDR。
MASQUERADE(源地址伪装)行为也截然不同。叠加模式下,节点间隧道流量本身就需要正确处理源地址,而直连模式依赖ipv4-native-routing-cidr划定"不需要 NAT 的 Pod 网段"(见 Documentation/network/concepts/masquerading.rst)。这个配置直接决定了直连模式下的 Pod 源 IP 能否原样到达对端——社区里有一个非常典型的坑:某团队从 Cilium v1.8.1 升级到 v1.11.1 后,业务 Pod 连 MySQL 突然报授权错误,排查发现是升级后 clientIP 变成了节点 IP,MASQUERADE 行为变化导致 MySQL 的 IP 白名单失效。这类问题在叠加/直连切换或版本升级时极易复现,升级前必须核对ipv4-native-routing-cidr与 MASQUERADE 配置。
可观测性:两者都能享受
有一点值得放心:无论哪种模式,Hubble 的流量观测、NetworkPolicy 的 L3/L4/L7 执行都是完整的。腾讯云 TKE 基于 Cilium 构建混合云容器网络的实践也验证了这一点——他们同时落地了 Overlay 与 Underlay 两套路径,靠 Cilium 统一数据面实现了全链路网络打通与可观测性,这正是 Cilium 相比"隧道只能用 Flannel、直连只能上 Calico"这类传统二分法方案的核心优势。
四、生产选型建议与常见坑清单
按环境选型的三条主线
1. 公有云 VPC 内:优先直连路由。云厂商 VPC 本身就是一个巨型 L2/L3 网络,天然路由 PodCIDR。AWS 场景直接用ipam: eni,Pod 拿到的就是 VPC 内可直接路由的 ENI 辅助 IP,连 SNAT 都省了;GKE 场景官方提供了gke.enabled: true一键开启 native routing + Kubernetes IPAM(见 Documentation/network/concepts/routing.rst)。此时叠加模式纯属浪费带宽。
2. 自建 IDC / 多云混合 / 底层网络不可控:默认叠加,保证可达优先。只要节点间 IP/UDP 互通,叠加模式就能工作,不依赖任何网络团队配合。对于"先跑起来再谈优化"的中小集群,这往往是性价比最高的起点。
3. 既要又要:混合模式过渡。如果一部分网段已打通路由、另一部分尚未打通,可用routing-mode: hybrid平滑过渡,不必一次性迁移全网。
五个高频避坑点
- 坑 1:MTU 不匹配。叠加模式 Pod MTU 会减 50(IPv4),如果物理网络本身用了巨型帧但没同步配置,或容器镜像里写死了 MTU,会出现"小包正常、大包黑洞"的诡异故障。排查命令顺手看下
ip link与路由 MTU 是否一致。 - 坑 2:防火墙漏放隧道端口。叠加模式部署完成后跨节点不通,十有八九是 8472/UDP(或 6081)被安全组/防火墙拦截。腾讯云 TKE 混合云实践中就专门处理过 VPC 与 IDC 网络互访的放行问题。
- 坑 3:直连模式的 PodCIDR 路由缺失。直连模式要求底层网络路由 PodCIDR,要么靠云 VPC 路由表、要么靠 BGP、要么靠
auto-direct-node-routes(仅限单一 L2 网络)。跨可用区/跨二层域时误开auto-direct-node-routes,流量会绕错路径,此时应改用 BGP +direct-routing-skip-unreachable。 - 坑 4:升级引发的 MASQUERADE 行为漂移。直连模式下升级 Cilium 或调整
ipv4-native-routing-cidr后,务必复核 Pod 间流量的源 IP 是否保持原样,尤其是数据库、Redis 等有 IP 白名单/授权机制的中间件。 - 坑 5:内核版本与特性的隐性绑定。叠加模式对内核要求相对宽松,但直连 + BBR + eBPF 主机路由等组合对内核版本(5.18+)有硬性要求。选型时先确认集群节点的内核版本分布,否则"想开开不了"比"开错了"更尴尬。这也是网易数帆等一线团队反复强调的 Cilium 落地前提:eBPF 特性高度依赖内核,务必先做版本清单核对。
结语
叠加与直连,本质不是"谁更先进"的路线之争,而是可达性优先与性能优先之间的工程权衡。Cilium 的巧妙之处在于,它把这种权衡做成了运行时配置(routing-mode+tunnel-protocol+ipv4-native-routing-cidr),让团队可以在同一套 eBPF 数据面下按环境切换、按网段混合。理解了封装开销、MTU 计算、NAT 语义与内核版本约束这四条主线,生产选型就不容易踩坑了。
【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考