Kubernetes 网络先分清三件事:谁给 Pod 插网线,谁在跨节点时封包,谁把 Service VIP 翻译成 Pod IP。三者没有调用关系,只在包的路径上碰头。
- CNI:规范 + 插件。kubelet 调它给 Pod 配 IP、veth、路由、网桥。Flannel、Calico、Cilium 都是实现。
- VTEP:VXLAN 隧道端点。Flannel 上是
flannel.1。跨节点时把内层帧封进 UDP/4789,对端再剥开。 - kube-proxy:看 Service / EndpointSlice,在节点上写 iptables 或 IPVS。它不负责 Pod 能否互相 ping。
| 组件 | 职责 | 挂了会怎样 |
|---|---|---|
| CNI | 造 Pod 网络,维护 VTEP | Pod 没网,跨节点断 |
| VTEP | 封装 / 解封装 | 跨节点断,本机 Pod 还通 |
| kube-proxy | VIP → Pod IP | Service 废,Pod 直连还在 |
下面用 Flannel VXLAN 走三种包。设定不变:
- Underlay
192.168.1.0/24,Node1192.168.1.10,Node2192.168.1.20 - Overlay
10.244.0.0/16,Node1 是10.244.0.0/24,Node2 是10.244.1.0/24 - Pod-A
10.244.0.2,Pod-C 同节点10.244.0.3,Pod-B 在 Node210.244.1.2 - Service
demo-svcClusterIP10.96.100.10,后端只有 Pod-B - VTEP 设备都是
flannel.1,VNI10001,UDP4789
同节点:只有 cni0
Pod-A 和 Pod-C 在同一个 /24。ARP 广播能直接问到对端 MAC。帧出 eth0,进 cni0 网桥,从另一条 veth 进 Pod-C。没有封装,kube-proxy 不在场。
主机路由里,本机 Pod 网段指向 cni0。只有目的地址落到别的节点的 /24,才会进 flannel.1。
跨节点:下一跳是远端 VTEP
这里容易写成「Pod-A ARP 问出 Pod-B 的 MAC」。Flannel VXLAN 不是一张跨节点大二层。每个节点一块 /24,跨网段是 L3。
- Pod-A 看 10.244.1.2 不在自己网段,以太网目的 MAC 填 cni0(默认网关)。
- 包进 Node1 主机网络命名空间。路由类似
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink。10.244.1.0是对端 VTEP 在 overlay 上的地址。 - 邻表 / FDB 给出 VTEP2 的 MAC,以及外层要送到的 Node2
192.168.1.20。 - 内层:源 IP 仍是 Pod-A,目的 IP 仍是 Pod-B,目的 MAC 是 VTEP2。外面再套 VXLAN 头、UDP/4789、外层 IP Node1 → Node2。
- Underlay 只看见普通 UDP。Node2 收到后交给
flannel.1,核验 VNI,剥头,再经 cni0 送到 Pod-B。
回程对称:VTEP2 封,VTEP1 剥。Pod 始终看不见 192.168.1.0/24。
Service:本机 DNAT 一次
生产里很少直接打 Pod IP,而是打 Service 名。
- Pod-A 问 CoreDNS,得到 ClusterIP
10.96.100.10。 - 包的目的 IP 是 VIP,目的 MAC 仍是 cni0,进入 Node1。
- Node1 的
PREROUTING命中 kube-proxy 写的KUBE-SERVICES,DNAT 成10.244.1.2。源 IP 仍是 Pod-A。 - 之后和上一节完全一样:走
flannel.1,VXLAN 到 Node2,送到 Pod-B。 - Pod-B 回包:源 Pod-B、目的 Pod-A。隧道回到 Node1 之后,这台机器上的 conntrack 按原连接把源地址改回 VIP,再交给 Pod-A。
不是 Node2 再做一次 SNAT。ClusterIP 的「看起来像访问 VIP」靠的是源节点那条连接跟踪。NodePort、从节点访问本机 Service、hairpin,才会再走到 MASQUERADE。
kube-proxy 只改这一次地址。隧道仍是 CNI 的事。两边故障域是分开的:proxy 挂了,Pod IP 直连还在。
三条 CNI,对 VXLAN 的态度不同
Flannel 默认就是这条内核 VXLAN,图简单,没有 NetworkPolicy。Calico 首选 BGP 直连,公有云不让跑 BGP 时才上 vxlan.calico,策略仍在。Cilium 用 eBPF 走封装或干脆原生路由,还能看 L7。
| Flannel | Calico | Cilium | |
|---|---|---|---|
| VXLAN | 默认 Overlay | BGP 不可用时的备选 | eBPF 加速,可被原生路由替代 |
| 封装实现 | 内核 VXLAN | 内核 VXLAN | eBPF,少走协议栈 |
| 策略 | 无 | L3/L4 | L3–L7 |
| 可观察性 | 弱 | 中 | Hubble |
| 更合适 | 小集群、先跑通 | 要策略的中大集群 | 要性能和 L7 的大规模 |
选型按「先要连通,再要策略,再要观测」即可。排查时先问包走的是上面三条里的哪一条:本机桥、跨节点隧道,还是先被 DNAT 再进隧道。五条链本身见 iptables。