Kubernetes (K8S) 网络原理

跨节点 Pod 通信

在 Kubernetes 集群中,Pod 可能分布在不同的节点上,但 Kubernetes 网络模型要求所有 Pod 之间能够直接通信,无需 NAT。本页将深入探讨不同节点上 Pod 之间的通信机制,以及各种 CNI 插件的实现方式。

跨节点 Pod 通信示意图

跨节点通信的挑战

与同节点 Pod 通信相比,跨节点 Pod 通信面临更多挑战:

为了解决这些挑战,Kubernetes 网络插件(CNI)采用了多种技术方案,主要分为以下几类:

跨节点通信实现方案

Overlay 网络
直接路由
BGP 路由
隧道技术

Overlay 网络

Overlay 网络是最常见的跨节点 Pod 通信方案,它在物理网络之上创建虚拟网络层。

VXLAN (Virtual Extensible LAN)

VXLAN 是一种常用的 Overlay 网络技术,它通过 UDP 封装二层以太网帧。

工作原理:

  1. Pod A 发送数据包到 Pod B(位于不同节点)
  2. 数据包到达 Pod A 所在节点的网络栈
  3. 节点检查路由表,发现目标 IP 属于 Pod 网络
  4. VXLAN 驱动将原始数据包封装在 UDP 数据包中
  5. 封装后的 UDP 数据包通过物理网络发送到目标节点
  6. 目标节点接收 UDP 数据包,解封装出原始数据包
  7. 解封装后的数据包通过本地路由发送到目标 Pod
# 查看 VXLAN 接口 ip -d link show type vxlan # 查看 VXLAN FDB 表(转发数据库) bridge fdb show dev flannel.1

VXLAN 的优缺点:

  • 优点:不依赖底层网络支持,适用于几乎所有环境
  • 缺点:有额外的封装/解封装开销,可能影响性能

使用 VXLAN 的 CNI 插件包括 Flannel(VXLAN 模式)、Calico(VXLAN 模式)、Weave Net 等。

直接路由

直接路由方案不使用封装,而是通过配置网络设备的路由表,使 Pod 网络可直接路由。

工作原理:

  1. 每个节点分配一个 Pod CIDR 子网(如节点 A 为 10.244.1.0/24,节点 B 为 10.244.2.0/24)
  2. 在每个节点上添加路由规则,指向其他节点的 Pod 子网
  3. 当 Pod A 发送数据包到 Pod B 时,数据包根据路由表直接发送到 Pod B 所在的节点
  4. 目标节点接收数据包,并根据本地路由将其转发到目标 Pod
# 查看节点上的路由表 ip route # 典型的直接路由规则 # 10.244.2.0/24 via 192.168.1.102 dev eth0

直接路由的优缺点:

  • 优点:无封装开销,性能更好
  • 缺点:要求底层网络支持 Pod CIDR 的路由,不适用于所有环境

使用直接路由的 CNI 插件包括 Flannel(host-gw 模式)、Calico(BGP 模式下的直接路由)等。

BGP 路由

BGP(边界网关协议)是一种动态路由协议,可以在节点之间分发路由信息。

工作原理:

  1. 每个节点运行 BGP 客户端(如 BIRD)
  2. 节点通过 BGP 协议向其他节点或路由器通告自己的 Pod CIDR
  3. 其他节点接收这些路由信息,并更新自己的路由表
  4. 当 Pod 需要跨节点通信时,数据包根据 BGP 分发的路由信息直接发送到目标节点

BGP 路由可以有两种模式:

  • 完全网状(Full mesh):每个节点与所有其他节点建立 BGP 连接
  • 路由反射器(Route Reflector):使用中心节点反射路由信息,减少连接数
# 查看 BGP 会话状态(Calico 示例) calicoctl node status # 查看 BGP 路由信息 ip route | grep bgp

BGP 路由的优缺点:

  • 优点:无封装开销,性能好;可以与现有网络基础设施集成
  • 缺点:配置相对复杂;要求网络设备支持 BGP

使用 BGP 路由的 CNI 插件主要是 Calico。

隧道技术

隧道技术是 Overlay 网络的一种形式,但使用不同的封装协议。

常见的隧道技术:

  • IPIP:将 IP 数据包封装在另一个 IP 数据包中
  • GRE:通用路由封装,支持多种协议
  • Geneve:通用网络虚拟化封装,VXLAN 的后继者
  • WireGuard:现代、安全的 VPN 隧道协议

IPIP 隧道工作原理:

  1. Pod A 发送数据包到 Pod B
  2. 源节点将原始 IP 数据包封装在外部 IP 数据包中
  3. 外部 IP 数据包的源地址是源节点的 IP,目标地址是目标节点的 IP
  4. 封装后的数据包通过物理网络发送到目标节点
  5. 目标节点接收数据包,解封装出原始 IP 数据包
  6. 解封装后的数据包通过本地路由发送到目标 Pod
# 查看 IPIP 隧道接口 ip -d link show type ipip # 查看隧道相关路由 ip route | grep tunl0

隧道技术的优缺点:

  • 优点:不依赖底层网络支持;某些隧道协议(如 WireGuard)提供内置加密
  • 缺点:有封装开销;某些隧道协议可能不被所有环境支持

使用隧道技术的 CNI 插件包括 Calico(IPIP 模式)、Flannel(GRE 模式)等。

主要 CNI 插件的跨节点通信实现

Flannel

Flannel 支持多种跨节点通信后端:

1. VXLAN 模式(默认)

  • 使用 VXLAN 封装,创建 flannel.1 接口
  • 维护 VTEP(VXLAN 隧道端点)映射表
  • 适用于大多数环境,不依赖特殊网络配置

2. host-gw 模式

  • 使用直接路由,无封装
  • 要求节点在同一二层网络
  • 性能更好,但适用范围更窄

3. UDP 模式(已弃用)

  • 使用 UDP 封装,但性能较差
  • 主要用于不支持 VXLAN 的环境
# Flannel 配置示例(ConfigMap) kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg data: net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } }

Calico

Calico 提供了多种跨节点通信选项:

1. BGP 模式(默认)

  • 使用 BGP 协议分发路由信息
  • 无封装,直接路由,性能最佳
  • 支持与现有 BGP 路由器集成
  • 支持 AS 号配置和路由策略

2. IPIP 模式

  • 使用 IPIP 隧道封装
  • 适用于不支持直接路由的环境
  • 可以配置为仅在跨子网时使用 IPIP

3. VXLAN 模式

  • 使用 VXLAN 封装,类似于 Flannel
  • 适用于不支持 IPIP 的环境
# Calico BGP 配置示例 calicoctl apply -f - << EOF apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: default-ipv4-ippool spec: cidr: 10.244.0.0/16 ipipMode: Never natOutgoing: true EOF

Weave Net

Weave Net 使用自己的跨节点通信机制:

1. 基于 VXLAN 的 Overlay 网络

  • 使用 VXLAN 或自定义 UDP 封装
  • 节点之间建立全网状连接
  • 支持自动发现和连接新节点

2. Fast Datapath

  • 使用 VXLAN 内核模块优化性能
  • 当可能时自动切换到 Fast Datapath
  • 结合了 Overlay 网络的兼容性和直接路由的性能

3. 加密通信

  • 支持节点间通信加密(NaCl)
  • 提供安全但有一定性能开销

Cilium

Cilium 基于 eBPF 技术,提供高性能的跨节点通信:

1. VXLAN 或 Geneve 封装

  • 使用 eBPF 优化的 VXLAN/Geneve 封装
  • 比传统实现更高效

2. 直接路由

  • 支持直接路由模式,无封装
  • 可以与 BGP 集成

3. WireGuard 加密

  • 支持使用 WireGuard 加密节点间通信
  • 提供高性能的加密通信

4. 身份感知路由

  • 基于工作负载身份而非仅 IP 地址进行路由
  • 提供更精细的安全控制

跨节点通信的性能考虑

跨节点 Pod 通信的性能受多种因素影响:

影响性能的因素

性能优化建议

# 调整 MTU 示例(Flannel VXLAN) # VXLAN 的开销约为 50 字节,所以如果物理网络 MTU 是 1500, # 则 flannel.1 的 MTU 应设为 1450 ip link set dev flannel.1 mtu 1450 # 测试跨节点网络性能 # 在节点 A 上运行 iperf 服务器 kubectl run iperf-server --image=networkstatic/iperf3 --port=5201 -- iperf3 -s # 在节点 B 上运行 iperf 客户端 kubectl run iperf-client --image=networkstatic/iperf3 --overrides='{"spec": {"nodeName": "node-b"}}' --rm -it -- iperf3 -c iperf-server

故障排除

跨节点 Pod 通信中可能遇到的常见问题及解决方法:

连接问题

症状:不同节点上的 Pod 无法相互通信

可能原因:

  • CNI 插件配置错误
  • 节点间网络连接问题
  • 防火墙阻止了 Pod 网络流量
  • 路由配置错误
  • MTU 配置不当

排查步骤:

# 测试 Pod 间连通性 kubectl exec -it -- ping # 测试节点间连通性 ping # 检查节点上的路由 ip route # 检查 CNI 插件状态 kubectl get pods -n kube-system -l k8s-app=calico-node kubectl logs -n kube-system -l k8s-app=calico-node # 检查防火墙规则 iptables -L

性能问题

症状:跨节点通信延迟高或吞吐量低

可能原因:

  • 使用了 Overlay 网络而非直接路由
  • MTU 设置不当导致分片
  • 底层网络拥塞
  • 节点资源(CPU/内存)不足

排查步骤:

# 检查 MTU 设置 ip link show # 测试网络性能 kubectl exec -it -- iperf3 -c # 检查节点资源使用情况 kubectl top nodes # 监控网络接口 sar -n DEV 1

封装/路由问题

症状:特定的通信模式失败,如跨子网通信

可能原因:

  • VXLAN/IPIP 配置错误
  • BGP 会话未建立
  • 底层网络不支持所选通信模式

排查步骤:

# 检查 VXLAN 接口 ip -d link show type vxlan # 检查 BGP 状态(Calico) calicoctl node status # 抓包分析 tcpdump -i any -n udp port 4789 # VXLAN tcpdump -i any -n proto 4 # IPIP tcpdump -i any -n tcp port 179 # BGP

相关资源

要了解更多关于跨节点 Pod 通信的信息,可以参考以下资源:

了解网络命名空间