别再死记硬背了!用Flannel和CNI插件,5分钟搞懂K8s Pod跨节点通信的底层原理

当你第一次在Kubernetes集群中部署应用时,可能会被Pod间通信的复杂性吓到——为什么同一个节点的Pod能互相ping通,而跨节点通信却需要额外配置?这背后隐藏着一套精妙的网络设计哲学。本文将用最直观的方式,带你拆解Flannel与CNI插件如何编织这张透明的网络大网。

1. 为什么需要Overlay网络?

想象一下,你管理的Kubernetes集群有20个节点,每个节点运行着50个Pod。这些Pod需要像在同一个局域网内那样自由通信,但现实是:

  • 物理网络可能划分了多个子网
  • 云环境存在安全组隔离
  • 传统路由表无法动态适应Pod的创建销毁

这就是Overlay网络要解决的核心问题:在底层物理网络之上构建一个虚拟网络层,让所有Pod仿佛连接在同一个交换机上。Flannel通过以下三种典型模式实现这一目标:

模式封装协议性能损耗适用场景
VXLANUDP封装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设备此时会执行以下操作:

  1. 查询ARP缓存获取目标VTEP的MAC地址
    # 查看ARP缓存
    bridge fdb show dev flannel.1
    # 输出示例:
    00:15:5d:02:1a:01 dst 192.168.1.12 self permanent
    
  2. 进行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时,它会:

  1. 创建pause容器建立网络命名空间
  2. 调用配置的CNI插件(如Flannel)
  3. 插件执行以下操作:
    • 创建veth pair连接Pod和主机
    • 为Pod分配IP并设置路由
    • 更新节点网络配置

常见CNI插件对比

特性FlannelCalicoCilium
网络模型OverlayBGP路由eBPF
策略控制高级
性能损耗极低
适用规模<100节点任意大型集群

4. 排错实战:当网络不通时

遇到跨节点Pod通信失败时,可以按照以下步骤排查:

  1. 基础检查

    # 确认各节点flanneld服务状态
    systemctl status flanneld
    # 检查防火墙规则
    iptables -L -n | grep flannel
    
  2. 路由追踪

    # 在源Pod执行traceroute
    kubectl exec -it pod-a -- traceroute 10.244.2.3
    
  3. 抓包分析

    # 在目标节点捕获flannel.1接口流量
    tcpdump -i flannel.1 -nn -w /tmp/flannel.pcap
    
  4. 常见故障模式

    • MTU不匹配导致分片丢失
    • 云平台安全组阻断VXLAN端口(通常为8472/UDP)
    • 节点路由表未正确更新

记住这个黄金法则:Kubernetes网络问题的排查总是从Pod→cni0→flannel.1→物理网卡逐层向下

(正文结束)

更多推荐