欢迎光临
我们一直在努力

深入理解 K8s 网络模型:不同节点间的 Pod 是如何通过隧道互相通信的

Kubernetes (K8s) 的核心设计要求之一是“IP-per-Pod”模型,即每个 Pod 都有一个唯一的 IP 地址,并且所有 Pod 都可以无需 NAT 地互相通信,无论它们位于哪个节点上。在单节点内部,这相对容易实现(通常通过 veth 对和 Linux 网桥)。但是,当 Pod 位于不同的物理或虚拟节点上时,就需要一个复杂的机制来确保这种无缝通信,这就是 K8s CNI 插件(如 Flannel 或 Calico)提供的覆盖网络(Overlay Network),其中最常见且具代表性的是 VXLAN 隧道技术

1. 为什么需要隧道?

想象两个 Pod:
* Pod A (IP: 10.244.1.5) 位于 Node 1 (IP: 192.168.1.10)
* Pod B (IP: 10.244.2.8) 位于 Node 2 (IP: 192.168.1.20)

当 Pod A 试图连接 Pod B 时,数据包的目标 IP 是 10.244.2.8。底层的物理网络路由器只知道 192.168.x.x 这个 Node IP 段,不知道 10.244.x.x 这个 Pod IP 段。为了让数据包能够跨越物理网络到达 Node 2,数据包必须被“封装”到 Node IP 地址空间中,这就是隧道的任务。

2. VXLAN:Mac-in-UDP 隧道技术

VXLAN(Virtual Extensible LAN)是一种网络虚拟化技术,它允许我们在现有的 L3 网络(IP 网络)上构建虚拟 L2 网络。它通过将原始的 L2 帧(带有 Pod 的 MAC/IP 地址)封装进一个标准的 UDP 数据包来实现这一目的。

关键组件:VTEP 和 VNI

  1. VTEP (VXLAN Tunnel Endpoint): 这是 K8s 节点上用于封装和解封装 VXLAN 数据包的虚拟网络接口,通常在 Flannel 中表现为 flannel.1 接口。
  2. VNI (VXLAN Network Identifier): 一个 24 位的 ID,用于标识一个特定的 VXLAN 网络。在 K8s 集群中,所有节点上的 Pod IP 都在同一个 VNI 下,确保它们属于同一个逻辑 L2 网络。

3. 跨节点通信的实操流程

我们以 Pod A (Node 1) 发送数据到 Pod B (Node 2) 为例,演示 VXLAN 如何工作:

步骤 1: 流量路由到 VTEP

当 Pod A 发送数据到 10.244.2.8 时,数据包离开 Pod A 的网络命名空间。Node 1 的主路由表会告诉内核:所有发往 10.244.2.0/24 子网的流量,都必须通过 flannel.1 (VTEP) 接口发送。

您可以在 Node 1 上使用以下命令查看路由表(假设 Flannel 为 10.244.1.0/24):

# 在 K8s Node 上执行
ip route | grep 10.244

# 预期输出示例 (注意,指向其他子网的流量通过 flannel.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

步骤 2: 数据包封装

  1. 数据包到达 flannel.1 接口。
  2. Flannel 需要知道 Node 2 的物理 IP (192.168.1.20) 才能发送数据。
  3. Flannel 通过其内置的 Forwarding Database (FDB) 查找(这些 FDB 条目通常由 Flannel DaemonSet 监听 K8s API Server 自动创建)。
  4. Flannel 将原始的 IP 数据包封装在一个 VXLAN 头中(包含 VNI)。
  5. 这个 VXLAN 数据包被进一步封装进一个标准的 UDP 数据包(目标端口 8472,目标 IP 192.168.1.20)。

封装层次:

物理网络头 (Node 2 IP) UDP 头 (Port 8472) VXLAN 头 (VNI) 原始数据包 (Pod A -> Pod B)

步骤 3: 跨越物理网络

现在,这个 UDP 数据包的目标是 192.168.1.20。它被视为普通的网络流量,顺利通过底层物理网络,从 Node 1 发送到 Node 2。

步骤 4: 数据包解封装

  1. Node 2 接收到这个 UDP 数据包(端口 8472)。
  2. 内核识别出这是 VXLAN 流量,并将其传递给 flannel.1 (VTEP) 接口。
  3. flannel.1 接口剥离 UDP 头和 VXLAN 头,还原出原始的 IP 数据包。
  4. 内核检查原始数据包的目标 IP (10.244.2.8),发现它属于 Node 2 上的一个 Pod,于是通过 Node 2 上的 CNI 网桥 (如 cni0) 转发给目标 Pod B。

检查 VTEP 转发数据库

您可以通过检查 VTEP 的 FDB 来查看 Node 是如何知道如何路由到其他子网的:

# 在 K8s Node 上执行,查看 flannel.1 的 FDB
# 这里的 MAC 地址是目标节点 flannel.1 接口的 MAC,以及对应的物理 IP
bridge fdb show dev flannel.1

# 预期输出示例
# 01:23:45:67:89:ab dev flannel.1 dst 192.168.1.20 permanent
# (表示:要到达这个 MAC 地址,请通过隧道发送到物理 IP 192.168.1.20)

总结

VXLAN 隧道是 K8s 实现跨节点通信的基石。它巧妙地将 Pod 的虚拟 L2 网络流量封装在底层物理网络的 L3 流量中,使得 Pod 间通信可以忽略底层物理拓扑的限制,实现了 K8s 所要求的“扁平网络”目标。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 深入理解 K8s 网络模型:不同节点间的 Pod 是如何通过隧道互相通信的
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址