别再死记硬背了!用Flannel和CNI插件,5分钟搞懂K8s Pod跨节点通信的底层原理
别再死记硬背了!用Flannel和CNI插件,5分钟搞懂K8s Pod跨节点通信的底层原理
当你第一次在Kubernetes集群中部署应用时,可能会被Pod间通信的复杂性吓到——为什么同一个节点的Pod能互相ping通,而跨节点通信却需要额外配置?这背后隐藏着一套精妙的网络设计哲学。本文将用最直观的方式,带你拆解Flannel与CNI插件如何编织这张透明的网络大网。
1. 为什么需要Overlay网络?
想象一下,你管理的Kubernetes集群有20个节点,每个节点运行着50个Pod。这些Pod需要像在同一个局域网内那样自由通信,但现实是:
- 物理网络可能划分了多个子网
- 云环境存在安全组隔离
- 传统路由表无法动态适应Pod的创建销毁
这就是Overlay网络要解决的核心问题:在底层物理网络之上构建一个虚拟网络层,让所有Pod仿佛连接在同一个交换机上。Flannel通过以下三种典型模式实现这一目标:
| 模式 | 封装协议 | 性能损耗 | 适用场景 |
|---|---|---|---|
| VXLAN | UDP封装 | 15-20% | 跨云/跨数据中心 |
| Host-GW | 直接路由 | <5% | 同子网物理机集群 |
| DirectRouting | 智能路由 | 5-10% | 混合环境(部分跨子网) |
提示:生产环境推荐使用DirectRouting模式,它会在同子网节点间自动切换为Host-GW模式,跨子网时降级为VXLAN。
2. 数据包的奇幻漂流:从Pod A到Pod B
让我们跟踪一个真实的数据包旅程,假设Pod A(10.244.1.5)要访问Pod B(10.244.2.3):
2.1 出发前的准备
# 在Pod A中执行路由检查
ip route show
# 输出示例:
default via 10.244.1.1 dev eth0
10.244.0.0/16 via 10.244.1.1 dev eth0
这段路由告诉我们:
- 所有非本Pod的流量都会发给网关10.244.1.1(即cni0网桥)
- 整个集群的Pod CIDR(10.244.0.0/16)都走这条路径
2.2 关键中转站:cni0与flannel.1
当数据包到达cni0网桥后,会根据节点路由表进行下一跳判断:
# 在Node1上查看路由表
ip route list
# 关键条目:
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1
10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
这个路由表揭示了一个重要事实:
- 目标Pod B的IP(10.244.2.3)匹配到第三条路由
- 数据包被转发到flannel.1这个VTEP设备
2.3 隧道封装的艺术
flannel.1设备此时会执行以下操作:
- 查询ARP缓存获取目标VTEP的MAC地址
# 查看ARP缓存 bridge fdb show dev flannel.1 # 输出示例: 00:15:5d:02:1a:01 dst 192.168.1.12 self permanent - 进行VXLAN封装:
- 外层源IP:Node1的物理IP(192.168.1.11)
- 外层目的IP:Node2的物理IP(192.168.1.12)
- 内层原始帧:保留原始Pod A→Pod B的IP包
注意:在DirectRouting模式下,如果Node1和Node2同属一个子网,flannel会跳过VXLAN封装,直接通过主机路由转发,性能提升显著。
3. CNI插件的幕后工作
CNI(Container Network Interface)就像Kubernetes网络的USB接口标准,它定义了插件必须实现的规范:
// 简化的CNI插件接口定义
type CNI interface {
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error)
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}
当kubelet创建Pod时,它会:
- 创建pause容器建立网络命名空间
- 调用配置的CNI插件(如Flannel)
- 插件执行以下操作:
- 创建veth pair连接Pod和主机
- 为Pod分配IP并设置路由
- 更新节点网络配置
常见CNI插件对比:
| 特性 | Flannel | Calico | Cilium |
|---|---|---|---|
| 网络模型 | Overlay | BGP路由 | eBPF |
| 策略控制 | 无 | 有 | 高级 |
| 性能损耗 | 中 | 低 | 极低 |
| 适用规模 | <100节点 | 任意 | 大型集群 |
4. 排错实战:当网络不通时
遇到跨节点Pod通信失败时,可以按照以下步骤排查:
-
基础检查:
# 确认各节点flanneld服务状态 systemctl status flanneld # 检查防火墙规则 iptables -L -n | grep flannel -
路由追踪:
# 在源Pod执行traceroute kubectl exec -it pod-a -- traceroute 10.244.2.3 -
抓包分析:
# 在目标节点捕获flannel.1接口流量 tcpdump -i flannel.1 -nn -w /tmp/flannel.pcap -
常见故障模式:
- MTU不匹配导致分片丢失
- 云平台安全组阻断VXLAN端口(通常为8472/UDP)
- 节点路由表未正确更新
记住这个黄金法则:Kubernetes网络问题的排查总是从Pod→cni0→flannel.1→物理网卡逐层向下。
(正文结束)
更多推荐
所有评论(0)