容器跨主机网络通信(进阶)
在前文中,我们了解了 Flannel UDP 模式的工作原理、容器跨主机通信的路由与 TUN 设备应用,以及由用户态与内核态切换带来的性能瓶颈问题。接下来,我们将继续深入,了解 Flannel VXLAN 模式,利用与 UDP 模式类似的 IP 信息、网络配置和基本流程,展示 VXLAN 如何在内核态完成封装与解封,从而实现高效且扩展性更好的 Overlay 网络。
UDP 模式中,Node 1 上 container-1(IP:100.96.1.2)发送到 Node 2 上 container-2(IP:100.96.2.3)的 IP 包经过 docker0、flannel0 TUN 设备后,由 flanneld 进程进行 UDP 封装,再通过宿主机间的 UDP 链接传输。性能瓶颈主要在用户态与内核态之间频繁的数据拷贝和上下文切换。
而 VXLAN 模式通过内核态封装,能够大幅降低开销,并以虚拟二层网络实现数据交换。
一、Flannel VXLAN 模式概述
VXLAN(Virtual Extensible LAN)技术通过内核态实现数据包的封装和解封装,在现有三层网络之上构建一层逻辑的二层网络,从而使得分布在不同宿主机甚至不同数据中心的容器或虚拟机能够像在同一局域网中那样通信。Flannel VXLAN 模式正是为了规避 UDP 模式中因用户态处理产生的性能瓶颈。
- 核心优势:
- 封装和解封装完全在内核态完成,避免了频繁的用户态与内核态切换
- 利用内核的零拷贝机制,可显著提升数据传输效率
二、IP 配置与网络环境
网络环境:
- Node 1:
- Flannel 分配子网:100.96.1.0/24
- docker0 网桥 IP:100.96.1.1
- 容器 container-1 IP:100.96.1.2
- VXLAN VTEP 设备(命名为 flannel.1)IP:10.1.15.1
- Node 2:
- Flannel 分配子网:100.96.2.0/24
- docker0 网桥 IP:100.96.2.1
- 容器 container-2 IP:100.96.2.3
- VXLAN VTEP 设备(命名为 flannel.1)IP:10.1.16.1
在 UDP 模式中,数据包从 container-1(100.96.1.2)经 docker0 传递给 flannel0。对于 VXLAN 模式,数据包同样从容器出发,但经过路由规则被引导到 VTEP 设备 flannel.1 进行封装。此处,flanneld 会根据各节点在 Etcd 中维护的子网映射关系,确保每个节点的 VTEP 信息正确下发,从而保证数据包能够在各宿主机之间准确传输。
实际环境中,Flannel 会自动维护各节点的子网和 VTEP 映射,用户只需关注整体配置;这里的 IP 仅作为示例。
三、VXLAN 数据封装与转发流程
以下流程描述了 VXLAN 模式下,数据包由 Node 1 传输至 Node 2 的完整过程,与 UDP 模式类似,但封装操作均在内核态完成。
3.1 原始数据包生成与流向入口
- 数据包产生:
container-1(IP:100.96.1.2)向 container-2(IP:100.96.2.3)发起通信,生成原始 IP 包。 - 本地路由决策:
数据包经过 docker0 网桥,由 Node 1 的内核根据路由规则发现目标不在本地子网,转发给 VXLAN 入口,即 flannel.1 VTEP 设备。
3.2 内部数据帧的封装
-
内部封装:
当数据包进入 flannel.1 后,内核首先为原始 IP 包添加一个二层 Ethernet 头部,形成“内部数据帧”。 -
MAC 地址获取:
与 UDP 模式类似,flanneld 在各节点启动时会下放目标 VTEP 设备的 ARP 记录到所有节点。例如,在 Node 1 上可以见到如下记录:$ ip neigh show dev flannel.1 10.1.16.1 lladdr 5e:f8:4f:00:e3:37 PERMANENT
这里 10.1.16.1 就是 Node 2 上 flannel.1 的 IP,而相应的 MAC 地址由系统或 flanneld 统一配置。
3.3 外部数据帧的封装
接下来,内核在内部数据帧外侧继续封装,生成外部数据包:
- 添加 VXLAN Header
内核在内部数据帧前加入 VXLAN 头,关键字段 VNI(VXLAN Network Identifier)用于标识该数据包所属的逻辑二层网络。Flannel 默认 VNI 值为 1,因此所有 VXLAN 隧道设备通常命名为 flannel.1。 - 封装成 UDP 包
在 VXLAN 头的外侧,再加上 IP 与 UDP 头部。此时:- IP 头:目的 IP 由 FDB(Forwarding Database)提供,如 Node 2 的物理 IP( 10.168.0.3)被设置为外部 IP 包的目的地址。
- UDP 头:目标端口为 VXLAN 标准端口(通常为 4789)。
- 形成外部数据帧
最终,内核输出的外部数据帧包含两个层次的信息:- Inner Ethernet Frame:内嵌原始数据包及其 Ethernet 头(目标为 container-2 的 IP 100.96.2.3)。
- Outer 封装:由 VXLAN Header、UDP/IP 头及外层 Ethernet 头组成,确保数据包在物理网络中的正确传输。
3.4 数据转发与目标节点解封
- 数据发送:
Node 1 的 flannel.1 设备将外部数据帧通过实际网卡(如 eth0)发出,数据包经过物理网络转发至 Node 2。 - VTEP 设备解封:
在 Node 2,上层物理网络将数据包交付到 flannel.1 VTEP 设备。内核识别 VXLAN Header(VNI=1),剥离外层封装,恢复出内部数据帧。 - 数据转发到容器:
内部数据帧中的原始 IP 包(目标 IP:100.96.2.3)由 Node 2 的内核根据路由策略转发至 docker0 网桥,最终进入 container-2 的 Network Namespace。
四、UDP 模式与 VXLAN 模式的对比
二者在数据包处理上的主要差异包括:
- 封装位置:
- UDP 模式:封装和解封装在用户态 flanneld 进程中进行,涉及多次用户态/内核态切换。
- VXLAN 模式:封装和解封操作完全在内核态中完成,利用 VTEP 设备及内核网络模块,大大降低了处理延时和 CPU 开销。
- 数据传输效率:
内核态的 VXLAN 封装可实现零拷贝和更高效的数据转发,尤其在大流量环境下表现出更好的性能优势。 - 网络透明性:
VXLAN 模式通过在三层网络上“覆盖”出一个虚拟二层网络,使得各节点间的 ARP 和 FDB 信息均由 flanneld 统一下发,避免了传统 L3 缺省学习过程中可能出现的延迟问题。