传统二层网络靠 VLAN 做隔离,但 12 位的 VLAN ID 最多只能表达 4094 个广播域,再加上生成树收敛慢、跨机房二层延伸困难,早已无法承载虚拟化与容器时代的租户规模。Overlay 的思路是:底层(Underlay)仍然是一张普通的三层 IP 网络,把原始二层帧封装进 UDP 报文里,在 IP 之上「重建」出一张虚拟的二层网络。
本文从 Overlay 的动机讲起,依次拆解 VXLAN 与 Geneve 的报文格式与 VNI 语义、VTEP 的转发与地址学习机制、从泛洪学习到 BGP EVPN 的控制面演进、Linux 上的落地配置,最后落到 MTU、硬件卸载与常见排错。
一、Overlay 网络的动机与分层模型
1.1 从 VLAN 到 Overlay
VLAN 的问题不在「隔离」本身,而在于它的作用域被物理网络绑定:一个 VLAN 只能在一棵生成树上存在,跨机房延伸意味着把故障域也一起延伸。VXLAN 把「租户标识」从 12 位扩到 24 位,并用 UDP 封装解耦了虚拟网络与物理拓扑。
VLAN(802.1Q):
802.1Q Tag:12 位 VID → 4094 个广播域
作用域:受 STP 约束,跨机房需大二层延伸
VXLAN(RFC 7348):
外层 UDP + 24 位 VNI → 约 1600 万个虚拟网络
作用域:Overlay 逻辑网络,与物理拓扑解耦
承载:任意 IP 可达的 Underlay(ECMP、Spine-Leaf)
1.2 Underlay 与 Overlay 的分工
Overlay 不是替代 Underlay,而是叠在它之上。Underlay 只负责「IP 可达」这一件事,Overlay 负责租户隔离与二层语义,二者职责清晰是排错的前提。
| 层次 | 关注点 | 典型技术 | 排错入口 |
|---|---|---|---|
| Underlay | 物理/逻辑 IP 可达性 | OSPF、IS-IS、BGP、ECMP | ping、traceroute、路由表 |
| Overlay | 租户隔离与二层延伸 | VXLAN、Geneve、EVPN | fdb、vxlan 接口、抓包 |
| 控制面 | 隧道端点与 MAC/IP 分发 | 泛洪学习、BGP EVPN | evpn 表、邻居状态 |
| 数据面 | 封装/解封装与转发 | VTEP、硬件卸载 | tcpdump、ethtool -S |
一句话:Underlay 出问题,Overlay 一定不通;Overlay 不通,Underlay 往往没问题。
1.3 Overlay 的代价与权衡
Overlay 不是免费的午餐。每增加一层封装,就多一份头部开销、多一层排错复杂度,也把部分转发决策从硬件挪到了 CPU 或专用 ASIC 上。理解代价,才能在规模与复杂度之间做正确取舍。
Overlay 的三类代价:
1. 头部开销:每包多 50~60 字节,等效带宽下降约 3%~4%
2. 排错复杂度:内层问题被外层封装遮蔽,需两层同时看
3. 卸载依赖:无硬件卸载时,封装/解封装消耗大量 CPU
二、VXLAN 封装与报文结构
2.1 VXLAN 报文格式
VXLAN 把整个原始以太网帧作为净荷,前面加上 8 字节的 VXLAN 头(含 24 位 VNI),再套上外层 UDP/IP 头。外层 UDP 目的端口默认 4789。
VXLAN 封装(外层到内层):
+-------------------------------+
| Outer Ethernet (Underlay) |
+-------------------------------+
| Outer IP (src/dst VTEP IP) |
+-------------------------------+
| Outer UDP (src 随机, dst 4789)|
+-------------------------------+
| VXLAN Header (8 字节) |
| Flags(8) | Reserved(24) |
| VNI (24) | Reserved(8) |
+-------------------------------+
| Inner Ethernet (原帧) |
| Dst MAC | Src MAC | ... |
+-------------------------------+
| Inner IP / Payload |
+-------------------------------+
2.2 VNI 与租户隔离
VNI(VXLAN Network Identifier)是 Overlay 的租户标签。同一个 VNI 内的主机在逻辑上处于同一二层域,不同 VNI 默认完全隔离,即使它们跑在同一台物理交换机下。内层帧里的 VLAN Tag 在封装时被剥掉,VNI 承担了隔离语义。
| 字段 | 长度 | 作用 |
|---|---|---|
| Flags | 8 位 | I 位为 1 表示 VNI 有效 |
| VNI | 24 位 | 虚拟网络标识,约 1600 万 |
| 内层 VLAN | 可选 | 通常被剥离,VNI 取代其隔离作用 |
三、VTEP 与转发流程
3.1 VTEP 的角色与类型
VTEP(VXLAN Tunnel Endpoint)是封装与解封装的执行点,它有两个身份:面向 Overlay 的虚拟接口(承载原始帧),以及面向 Underlay 的物理 IP。VTEP 既可以是软件(Linux vxlan 设备、OVS),也可以是硬件(ToR 交换机)。
VTEP 类型:
软件 VTEP:Linux vxlan 网卡 / OVS / 容器 CNI
- 灵活、可编程,性能依赖 CPU 与卸载
硬件 VTEP:支持 VXLAN 的物理交换机
- 线速、低时延,配置与自动化强绑定
混合:主机软件 VTEP + 网关硬件 VTEP
3.2 同子网与跨子网转发路径
同 VNI 同子网的两台主机通信,VTEP 只需查 FDB(转发数据库)得到对端 VTEP IP,直接封装送达。跨子网则要把帧送到分布式网关,由网关做三层转发后再封装到目标 VNI。
同子网(VM-A → VM-B,同一 VNI):
VM-A → VTEP-A 查 FDB(dst MAC → VTEP-B IP)
→ 封装 UDP/IP → Underlay 送达 VTEP-B
→ 解封装 → VM-B
跨子网(VM-A 在 VNI 100 → VM-C 在 VNI 200):
VM-A → VTEP-A → 网关(IRB/SVI)三层转发
→ 改查 VNI 200 的 FDB → 封装 → VTEP-C → VM-C
3.3 多归属与 ESI
生产环境里,一台服务器常通过两条链路接入两台 ToR 交换机,希望做到「双活接入、链路故障零感知」。EVPN 用 ESI(Ethernet Segment Identifier)标识「同一个接入段」,配合全活(All-Active)多归属,实现流量的本地优先与快速切换。
多归属(All-Active)关键点:
- 两台 ToR 用同一 ESI 标识同一台服务器的接入段
- 服务器发出的帧,两台 ToR 都可能收到 → 需要 DF 选举
- DF(指定转发者)负责向 Overlay 转发 BUM 流量,避免重复
- 链路故障时,本地表项快速切换,无需等待路由收敛
四、控制面:从泛洪学习到 EVPN
4.1 数据面学习(泛洪与学习)
最原始的 VXLAN 没有控制面:未知单播、广播、组播流量在 VNI 内泛洪,VTEP 从收到的报文里「逆向学习」源 MAC 与源 VTEP 的映射。这套机制简单但代价明显。
泛洪学习的工作方式:
1. VM-A 首次访问 VM-B(未知单播)
2. VTEP-A 在 VNI 内泛洪(组播组或 ingress-replication 列表)
3. 只有 VM-B 应答,VTEP-A 学习:MAC-B → VTEP-B
4. 后续流量单播直达
代价:
- 泛洪放大:租户越多,广播风暴风险越高
- 学习依赖流量:静默主机无表项,首包必泛洪
- 组播依赖:Underlay 需支持 PIM 或退化为单播复制
4.2 BGP EVPN 控制面
EVPN(RFC 7432)把 MAC/IP 可达性变成 BGP 路由,用 MP-BGP 在 VTEP 之间分发。它带来三个好处:无需泛洪、支持多归属(ESI)、支持 ARP 抑制。这是现代数据中心 Overlay 的标准做法。
| 路由类型 | 名称 | 作用 |
|---|---|---|
| Type 2 | MAC/IP Advertisement | 通告主机 MAC/IP 与 VTEP 映射 |
| Type 3 | Inclusive Multicast | 建立 BUM 流量的复制列表 |
| Type 5 | IP Prefix | 通告三层前缀,用于跨子网 |
EVPN 收敛后的转发:
VTEP-A 本地有 MAC-B → VTEP-B 的 EVPN 表项
首包即单播,无泛洪
ARP 请求由本地 EVPN 缓存直接应答(ARP 抑制)
五、Geneve:可扩展的隧道封装
5.1 Geneve 头部结构
Geneve(RFC 8926)是 VXLAN 的「通用化」后继:它把头部做成可变长 TLV 选项,允许携带额外元数据(如安全组 ID、策略标签),并且 VNI 之外的字段不再浪费。默认 UDP 端口 6081。
Geneve 头部:
+-----------------------------------+
| Ver(2) | Opt Len(6) | OAM | Rsvd |
| Protocol Type (16, 通常 0x6558) |
| VNI (24) | Reserved (8) |
+-----------------------------------+
| Options (可变长 TLV) |
| Class(16) | Type(8) | Rsvd(3)+Len(5)
| Value ... |
+-----------------------------------+
| Inner Frame |
+-----------------------------------+
5.2 VXLAN 与 Geneve 选型对比
| 维度 | VXLAN | Geneve |
|---|---|---|
| 标准 | RFC 7348 | RFC 8926 |
| 头部 | 固定 8 字节 | 8 字节 + 可变 TLV |
| 扩展性 | 弱,元数据无处安放 | 强,TLV 可携带策略标签 |
| 默认端口 | 4789 | 6081 |
| 典型用户 | 传统 DC、多数硬件 VTEP | 云原生 CNI、SDN 控制器 |
| 硬件支持 | 广泛 | 逐步完善 |
六、Linux 上的 Overlay 实现
6.1 用 iproute2 建立 VXLAN 隧道
在 Linux 上创建 VXLAN 设备只需要两条命令:先建 vxlan 网卡指定 VNI 与本地 VTEP 地址,再把它挂进网桥。对端可以是单播、组播或 external(由 EVPN 填充)。
# 建立 VXLAN 设备,VNI=100,本地 VTEP 为 10.0.0.1
ip link add vxlan100 type vxlan \
id 100 \
local 10.0.0.1 \
dstport 4789 \
nolearning
# 挂到网桥,供容器/虚拟机接入
ip link set vxlan100 master br-overlay
ip link set vxlan100 up
ip link set br-overlay up
# 手工添加 FDB 表项(nolearning 模式下必需)
bridge fdb append 00:00:00:00:00:00 \
dev vxlan100 dst 10.0.0.2
6.2 FDB 表项与抓包验证
验证 Overlay 是否正常,先看 FDB,再抓 Underlay 上的 UDP 4789 报文。若 FDB 有表项但抓不到包,问题多半在 Underlay 路由;若抓到包但对端无响应,则检查对端 VNI 与安全组。
# 查看 FDB 表项
bridge fdb show dev vxlan100
# 抓取 Underlay 上的 VXLAN 封装流量
tcpdump -i eth0 -n udp port 4789 -c 5
# 典型抓包输出
# 10.0.0.1.52000 > 10.0.0.2.4789: VXLAN, flags [I] (0x08),
# vni 100, ethertype IPv4
七、MTU、性能与常见排错
7.1 MTU 与分片
VXLAN 封装会额外增加 50 字节(外层以太 14 + IP 20 + UDP 8 + VXLAN 8),若 Underlay MTU 为 1500,则内层可用 MTU 只有 1450。不调整 MTU 会导致大包被丢弃或分片,表现为「ping 通、传文件卡死」。
MTU 计算:
外层以太 14 + 外层 IP 20 + UDP 8 + VXLAN 8 = 50 字节
内层可用 MTU = Underlay MTU - 50
1500 - 50 = 1450(VM/容器的 MTU 应设为 1450)
症状:小包正常、大包丢失、SSH 卡在认证后
诊断:ping -M do -s 1472 <peer> # 1472+28=1500
7.2 硬件卸载与排错清单
现代网卡支持 VXLAN/Geneve 的封装卸载(TX offload)与校验和卸载,能显著降低 CPU 占用。排错时先确认卸载状态,再按「Underlay → FDB → VNI → MTU」顺序逐层排查。
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 完全不通 | Underlay 路由缺失 | ping 对端 VTEP IP |
| 首包丢、后续通 | FDB 未收敛 | bridge fdb show |
| 大包丢、小包通 | MTU 未下调 | ping -M do -s 1472 |
| 单向不通 | 安全组/防火墙挡 UDP 4789 | tcpdump 双向抓包 |
| CPU 飙高 | 未开启封装卸载 | ethtool -k eth0 看 tx-udp_tnl-segmentation |
7.3 一个真实的排错案例
某集群扩容后,新节点上的 Pod 能 ping 通同节点 Pod,却无法访问跨节点服务,且只在传输大响应体时超时。按分层顺序排查:Underlay 的 VTEP IP 互 ping 正常,FDB 表项齐全,最终定位到新节点容器 MTU 仍为 1500 而非 1450——小包(TCP 握手)通,大包(响应体)被静默丢弃。
排错路径复盘:
1. ping 对端 VTEP IP → 通,排除 Underlay
2. bridge fdb show → 表项齐全,排除控制面
3. curl 小文件 → 正常
4. curl 大文件 → 卡住,怀疑 MTU
5. ping -M do -s 1472 peer → 失败,确认 MTU 问题
6. 调整容器 MTU 至 1450 → 恢复
八、总结
| 主题 | 核心知识点 | 落地建议 |
|---|---|---|
| 动机 | VLAN 4094 上限与 STP 约束 | 大规模租户直接上 Overlay |
| 封装 | VXLAN 8 字节头 + 24 位 VNI | 端口统一 4789,硬件 VTEP 对齐 |
| 转发 | VTEP 查 FDB 封装送达 | 同子网直连、跨子网走网关 |
| 控制面 | 泛洪学习 vs BGP EVPN | 生产环境优先 EVPN,避免泛洪 |
| Geneve | TLV 可扩展元数据 | 云原生 CNI 与 SDN 场景选 Geneve |
| 排错 | MTU 少 50 字节 | 内层统一 1450,按层排查 |
Overlay 的价值在于把网络虚拟化从硬件里解放出来:租户数量不再受 VLAN 位宽限制,二层拓扑不再被物理布线绑定。但它也把故障域从「一根线」扩展到「Underlay 路由 + 控制面 + MTU + 卸载」四层,排错必须分层。对后端与网络工程师来说,理解 VXLAN 报文结构、VNI 语义与 EVPN 控制面,是读懂云网络、容器 CNI 与 Service Mesh 数据面的共同底座——看见封包,才能定位封包之外的问题。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。