二层穿透的硬核:BGP多线主机上构建EVPN/VXLAN分布式网络的底层原理与FRR实战
痛点:为什么三层穿透不够用?
传统内网穿透(frp、WireGuard)工作在L3层面,虽然能打通IP通信,但面对需要广播、ARP、DHCP的遗留应用(如数据库集群、Windows AD域)时,L3桥接往往需要额外配置Proxy ARP或NAT规则。真正的解决方案是在BGP多线主机之间拉起一条跨越公网的L2通道,让多个机房像一个交换机下的子网一样工作。EVPN+VXLAN正是为这种场景而生的工业级技术。
核心架构:VXLAN数据平面 + BGP控制平面
- VXLAN:将L2帧封装在UDP(端口4789)中,使用24-bit VNI(类似VLAN ID)隔离租户。Linux内核原生支持VXLAN隧道端点(VTEP)。
- BGP EVPN:通过BGP扩展(Address Family L2VPN EVPN)在VTEP之间交换MAC可达性信息。关键路由类型:Type-2(MAC/IP)和Type-3(IMET组播)。
- FRR (Free Range Routing):轻量级路由套件,在BGP多线主机上运行作为EVPN路由反射器或EBGP对等体。
在BGP多线主机上部署EVPN(实战代码)
假设两台BGP多线主机,公网IP分别为 203.0.113.1 和 203.0.113.2,内网都需接入 10.10.10.0/24 的L2网络。
1. 创建VXLAN接口和网桥
# 主机A
ip link add vxlan100 type vxlan id 100 \
dstport 4789 local 203.0.113.1 \
nolearning
ip link set vxlan100 up
brctl addbr br100
brctl addif br100 vxlan100
# 注意:内核VXLAN默认使用内核FDB,但EVPN控制平面需关闭学习(nolearning)
两台主机重复类似配置,仅将 local 地址改为各自公网IP。
2. 使用FRR配置BGP EVPN
安装FRR后,编辑 /etc/frr/frr.conf:
router bgp 65001
bgp router-id 203.0.113.1
neighbor 203.0.113.2 remote-as 65001
neighbor 203.0.113.2 update-source 203.0.113.1
!
address-family l2vpn evpn
neighbor 203.0.113.2 activate
advertise-all-vni # 通告所有本地VNI
exit-address-family
另一台主机类似,AS号相同(IBGP),确保 bgp router-id 不同。重启FRR:systemctl restart frr。
3. 将本地VNI映射到BGP
通过 vtysh 进入FRR CLI,指定每个VNI关联的BGP RT/RD:
router bgp 65001
address-family l2vpn evpn
vni 100
rd 203.0.113.1:100
route-target import 65001:100
route-target export 65001:100
此时FRR会自动将本端VXLAN接口的MAC地址通过Type-2路由通告给对端。用 show bgp l2vpn evpn route 查看。
底层原理深度解析
MAC学习流程
- 当主机A下的虚拟机发送第一个ARP请求时,br100从vxlan100接口收到数据包(因为桥接模式)。
- 由于配置了
nolearning,内核不会自动学习远端MAC的VTEP映射;控制平面完全依赖BGP EVPN。 - FRR通过netlink监听本端VXLAN接口的本地MAC变化,并生成Type-2路由:
MAC=00:11:22:33:44:55, IP=10.10.10.1, VNI=100, VTEP=203.0.113.1。 - 对端FRR收到路由后,通过netlink将MAC与远端VTEP映射写入内核FDB:
bridge fdb add 00:11:22:33:44:55 dev vxlan100 dst 203.0.113.1。 - 此后,主机B下的流量直接通过VXLAN单播到达主机A,无需组播泛滥。
多路径与故障切换(BGP多线优势)
如果BGP多线主机拥有多个公网IP(例如轻云互联提供5个BGP IP),可以创建一个VXLAN隧道池:
# 创建多条VXLAN隧道绑定不同源IP
ip link add vxlan100-1 type vxlan id 100 dstport 4789 local 203.0.113.1
ip link add vxlan100-2 type vxlan id 100 dstport 4789 local 203.0.113.3
brctl addif br100 vxlan100-1
brctl addif br100 vxlan100-2
在BGP EVPN中,对同一MAC地址可以通告多个VTEP(等价多路径),FRR支持ECMP。当一条公网链路故障时,BGP withdraw该VTEP对应的路由,流量自动切换到另一条隧道。
排错与验证
抓包确认VXLAN封装
# 抓取目标端口4789的VXLAN报文(内核层能看到双层IP)
tcpdump -ni any udp port 4789 -X
检查EVPN路由表
vtysh -c "show bgp l2vpn evpn route json" | jq '.routes[] | select(.prefix=="10.10.10.1/32")'
输出应包含 remoteVtepList 指向对端公网IP。
内核FDB确认
bridge fdb show dev vxlan100
# 输出示例: 00:11:22:33:44:55 dst 203.0.113.2 self permanent
# 若缺少条目,检查FRR是否成功写入
性能优化要点
- 开启VXLAN的UDP校验和卸载(
ethtool -K eth0 tx-udp_tnl-csum-segmentation on)可降低CPU负载。 - 使用多队列VXLAN(
ip link set vxlan100 ... txqueuelen 10000)提升吞吐。 - BGP多线主机出口带宽通常充裕,但需注意MTU问题:VXLAN开销50字节,建议底层接口设置MTU 1500+50。
总结
EVPN/VXLAN方案将内网穿透的复杂性从应用层下沉到内核与路由协议层,利用BGP多线主机的公网多IP特性实现无单点故障的L2桥接。无论是容器跨主机互联,还是传统VM迁移,这套体系都远胜于用户态代理。实际操作中,轻云互联的BGP多线主机提供了稳定的公网链路和充足带宽,让我们在部署时无需担心VXLAN隧道的UDP丢包问题,只需专注于控制平面调优。