VXLAN-EVPN 多租户私有网络测试文档

VXLAN-EVPN 多租户私有网络测试文档

by cluaude code + glm5.1

1. 测试概述

1.1 目标

使用3台Ubuntu 24.04云主机 基于 VLAN + VXLAN/EVPN 技术构建多租户私有网络,验证:

  • 同子网跨 TOR 东西向流量(L2 跨节点转发)
  • EVPN 控制面 MAC/IP 自动学习与同步
  • BGP Route Reflector 路由反射架构
  • VXLAN 隧道封装正确性

1.2 测试拓扑

scss 复制代码
                    ┌──────────────────┐
                    │   RR (172.20.2.6)│
                    │  仅 BGP EVPN RR  │
                    │  无 VTEP/无数据面 │
                    └────────┬─────────┘
                             │ iBGP EVPN
                    ┌────────┴───────────────────────┐
                    │                                │
            ┌───────┴──────┐                 ┌───────┴──────┐
            │   node1      │                 │   node2      │
            │ 172.20.2.9   │                 │ 172.20.2.10  │
            │ VTEP + 计算   │                 │ VTEP + 计算  │
            │              │                 │              │
            │ vm1-sub100   │◄──── VXLAN ────►│ vm2-sub100   │
            │ 10.1.1.11    │    (VNI 10001)  │ 10.1.1.12    │
            │              │                 │
            │ vm1-sub200   │◄──── VXLAN ────►│ vm2-sub200   │
            │ 10.1.2.11    │    (VNI 10002)  │ 10.1.2.12    │
            └──────────────┘                 └──────────────┘

    Underlay: 172.20.2.0/24 (内网互通)
    Overlay:  VNI 10001 → 10.1.1.0/24 (子网1)
             VNI 10002 → 10.1.2.0/24 (子网2)

1.3 节点信息

节点 角色 内网 IP 外网 IP 网卡名
RR Route Reflector 172.20.2.6 112.51.122.186 enp0s16
node1 计算节点 172.20.2.9 112.51.122.182 enp0s16
node2 计算节点 172.20.2.10 112.51.122.180 enp0s16

1.4 Overlay 地址规划

VNI VLAN 子网 用途 node1 VM node2 VM
10001 - 10.1.1.0/24 租户子网1 10.1.1.11 10.1.1.12
10002 - 10.1.2.0/24 租户子网2 10.1.2.11 10.1.2.12

2. 环境准备

2.1 云主机要求

  • 3 台 VM 位于同一内网子网(Underlay 互通)
  • 安全组放行以下端口:
协议 端口 用途
TCP 179 BGP 邻居建立
UDP 4789 VXLAN 隧道数据
UDP 3784 BFD 快速故障检测
ICMP - 调试连通性

2.2 基础软件安装(三台均执行)

bash 复制代码
# 安装 FRR
apt update && apt install -y frr iproute2 bridge-utils tcpdump

# 开启内核转发
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.default.rp_filter=0
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf
echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf

2.3 启用 FRR 守护进程(三台均执行)

bash 复制代码
cat > /etc/frr/daemons <<'EOF'
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
bfdd=yes
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
EOF

systemctl enable frr
systemctl restart frr

3. RR 节点配置

3.1 设计说明

RR 仅运行 BGP EVPN 控制面,不做 VXLAN 数据转发,不接入任何 VM。

3.2 FRR 配置

bash 复制代码
cat > /etc/frr/frr.conf <<'EOF'
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.6
 !
 neighbor 172.20.2.9 remote-as 65000
 neighbor 172.20.2.9 description node1
 neighbor 172.20.2.9 update-source enp0s16
 neighbor 172.20.2.9 bfd
 !
 neighbor 172.20.2.10 remote-as 65000
 neighbor 172.20.2.10 description node2
 neighbor 172.20.2.10 update-source enp0s16
 neighbor 172.20.2.10 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.9 activate
  neighbor 172.20.2.10 activate
  neighbor 172.20.2.9 route-reflector-client
  neighbor 172.20.2.10 route-reflector-client
  retain route-target all
 exit-address-family
 !
 bgp bestpath as-path multipath-relax
!
EOF

systemctl restart frr

3.3 关键配置说明

配置项 作用
update-source enp0s16 指定 BGP TCP 连接使用的源接口
route-reflector-client 标记对端为 RR 客户端,反射其路由
retain route-target all RR 保留所有 RT 路由,不做本地 RT 过滤
bgp bestpath as-path multipath-relax 允许 AS-Path 长度不同的路由做 ECMP

4. node1 配置(计算节点)

4.1 数据面脚本

bash 复制代码
cat > /root/setup-vxlan.sh <<'SCRIPT'
#!/bin/bash
set -e

LOCAL_IP=172.20.2.9

# 清理旧配置
ip link del br-10001 2>/dev/null || true
ip link del br-10002 2>/dev/null || true
ip link del vni10001 2>/dev/null || true
ip link del vni10002 2>/dev/null || true
ip netns del vm1-sub100 2>/dev/null || true
ip netns del vm1-sub200 2>/dev/null || true
ip link del veth-vm1 2>/dev/null || true
ip link del veth-vm2 2>/dev/null || true

# VNI 10001
ip link add vni10001 type vxlan id 10001 \
  local ${LOCAL_IP} dstport 4789 nolearning
ip link set vni10001 up

# VNI 10002
ip link add vni10002 type vxlan id 10002 \
  local ${LOCAL_IP} dstport 4789 nolearning
ip link set vni10002 up

# Bridge
ip link add br-10001 type bridge
ip link set vni10001 master br-10001
ip link set br-10001 up

ip link add br-10002 type bridge
ip link set vni10002 master br-10002
ip link set br-10002 up

# VM: vm1-sub100 (10.1.1.11)
ip netns add vm1-sub100
ip link add veth-vm1 type veth peer name eth0 netns vm1-sub100
ip link set veth-vm1 master br-10001
ip link set veth-vm1 up
ip netns exec vm1-sub100 ip link set eth0 up
ip netns exec vm1-sub100 ip addr add 10.1.1.11/24 dev eth0
ip netns exec vm1-sub100 ip route add default via 10.1.1.1

# VM: vm1-sub200 (10.1.2.11)
ip netns add vm1-sub200
ip link add veth-vm2 type veth peer name eth0 netns vm1-sub200
ip link set veth-vm2 master br-10002
ip link set veth-vm2 up
ip netns exec vm1-sub200 ip link set eth0 up
ip netns exec vm1-sub200 ip addr add 10.1.2.11/24 dev eth0
ip netns exec vm1-sub200 ip route add default via 10.1.2.1

echo "=== node1 数据面配置完成 ==="
ip -br addr | grep -E 'br-|vni|veth'
SCRIPT

chmod +x /root/setup-vxlan.sh
bash /root/setup-vxlan.sh

4.2 FRR 配置

bash 复制代码
cat > /etc/frr/frr.conf <<'EOF'
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.9
 !
 neighbor 172.20.2.6 remote-as 65000
 neighbor 172.20.2.6 description RR
 neighbor 172.20.2.6 update-source enp0s16
 neighbor 172.20.2.6 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.6 activate
  advertise-all-vni
  vni 10001
   rd 65000:10001
   route-target import 65000:10001
   route-target export 65000:10001
  exit-vni
  vni 10002
   rd 65000:10002
   route-target import 65000:10002
   route-target export 65000:10002
  exit-vni
 exit-address-family
!
EOF

systemctl restart frr

5. node2 配置(计算节点)

5.1 数据面脚本

bash 复制代码
cat > /root/setup-vxlan.sh <<'SCRIPT'
#!/bin/bash
set -e

LOCAL_IP=172.20.2.10

# 清理旧配置
ip link del br-10001 2>/dev/null || true
ip link del br-10002 2>/dev/null || true
ip link del vni10001 2>/dev/null || true
ip link del vni10002 2>/dev/null || true
ip netns del vm2-sub100 2>/dev/null || true
ip netns del vm2-sub200 2>/dev/null || true
ip link del veth-vm3 2>/dev/null || true
ip link del veth-vm4 2>/dev/null || true

# VNI 10001
ip link add vni10001 type vxlan id 10001 \
  local ${LOCAL_IP} dstport 4789 nolearning
ip link set vni10001 up

# VNI 10002
ip link add vni10002 type vxlan id 10002 \
  local ${LOCAL_IP} dstport 4789 nolearning
ip link set vni10002 up

# Bridge
ip link add br-10001 type bridge
ip link set vni10001 master br-10001
ip link set br-10001 up

ip link add br-10002 type bridge
ip link set vni10002 master br-10002
ip link set br-10002 up

# VM: vm2-sub100 (10.1.1.12)
ip netns add vm2-sub100
ip link add veth-vm3 type veth peer name eth0 netns vm2-sub100
ip link set veth-vm3 master br-10001
ip link set veth-vm3 up
ip netns exec vm2-sub100 ip link set eth0 up
ip netns exec vm2-sub100 ip addr add 10.1.1.12/24 dev eth0
ip netns exec vm2-sub100 ip route add default via 10.1.1.1

# VM: vm2-sub200 (10.1.2.12)
ip netns add vm2-sub200
ip link add veth-vm4 type veth peer name eth0 netns vm2-sub200
ip link set veth-vm4 master br-10002
ip link set veth-vm4 up
ip netns exec vm2-sub200 ip link set eth0 up
ip netns exec vm2-sub200 ip addr add 10.1.2.12/24 dev eth0
ip netns exec vm2-sub200 ip route add default via 10.1.2.1

echo "=== node2 数据面配置完成 ==="
ip -br addr | grep -E 'br-|vni|veth'
SCRIPT

chmod +x /root/setup-vxlan.sh
bash /root/setup-vxlan.sh

5.2 FRR 配置

bash 复制代码
cat > /etc/frr/frr.conf <<'EOF'
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.10
 !
 neighbor 172.20.2.6 remote-as 65000
 neighbor 172.20.2.6 description RR
 neighbor 172.20.2.6 update-source enp0s16
 neighbor 172.20.2.6 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.6 activate
  advertise-all-vni
  vni 10001
   rd 65000:10001
   route-target import 65000:10001
   route-target export 65000:10001
  exit-vni
  vni 10002
   rd 65000:10002
   route-target import 65000:10002
   route-target export 65000:10002
  exit-vni
 exit-address-family
!
EOF

systemctl restart frr

6. 部署操作顺序

yaml 复制代码
步骤 1: 三台均安装 FRR + 开启内核转发 + 配置 daemons
步骤 2: 配置 RR 的 frr.conf → 重启 frr
步骤 3: node1 执行 setup-vxlan.sh(数据面)
步骤 4: node1 配置 frr.conf → 重启 frr
步骤 5: node2 执行 setup-vxlan.sh(数据面)
步骤 6: node2 配置 frr.conf → 重启 frr
步骤 7: 等待 10 秒 BGP 收敛
步骤 8: 执行验证(第 7 章)

7. 验证与测试

7.1 BGP 邻居验证

bash 复制代码
# 在 RR 上执行
vtysh -c "show bgp l2vpn evpn summary"

期望输出

vbnet 复制代码
Neighbor        V    AS  MsgRcvd MsgSent  Up/Down  State/PfxRcd
172.20.2.9      4  65000     xxx     xxx   xx:xx:xx        4     ← node1
172.20.2.10     4  65000     xxx     xxx   xx:xx:xx        4     ← node2

7.2 EVPN 路由验证

bash 复制代码
# 在 RR 上查看收到的所有 EVPN 路由
vtysh -c "show bgp l2vpn evpn route"

# 在计算节点上查看 VNI 状态
vtysh -c "show evpn vni"

# 查看 MAC 表
vtysh -c "show evpn mac vni 10001"
vtysh -c "show evpn mac vni 10002"

期望输出(node1 上):

csharp 复制代码
VNI        Type VxLAN IF    # MACs  # ARPs  # Remote VTEPs  Tenant VRF
10001      L2   vni10001    2       0       1               default
10002      L2   vni10002    2       0       1               default

7.3 FDB 转发表验证

bash 复制代码
bridge fdb show | grep extern_learn

期望输出

lua 复制代码
<远端VM-MAC> dev vni10001 dst 172.20.2.10 self extern_learn
<远端VM-MAC> dev vni10002 dst 172.20.2.10 self extern_learn

7.4 同子网跨 TOR 连通性测试

bash 复制代码
# 测试 1: VNI 10001 - node1 → node2
ip netns exec vm1-sub100 ping -c 3 10.1.1.12

# 测试 2: VNI 10002 - node1 → node2
ip netns exec vm1-sub200 ping -c 3 10.1.2.12

# 测试 3: 反向 - node2 → node1
ip netns exec vm2-sub100 ping -c 3 10.1.1.11

# 测试 4: 反向 - node2 → node1
ip netns exec vm2-sub200 ping -c 3 10.1.2.11

期望结果:全部 0% 丢包,延迟 < 2ms

7.5 VXLAN 封装验证

bash 复制代码
# 在 node1 上抓包
tcpdump -i enp0s16 udp port 4789 -nn -c 5 &
ip netns exec vm1-sub100 ping -c 2 10.1.1.12

期望看到

yaml 复制代码
IP 172.20.2.9.xxxxx > 172.20.2.10.4789: VXLAN, vni 10001
  IP 10.1.1.11 > 10.1.1.12: ICMP echo request

IP 172.20.2.10.xxxxx > 172.20.2.9.4789: VXLAN, vni 10001
  IP 10.1.1.12 > 10.1.1.11: ICMP echo reply

8. 踩坑记录与注意事项

8.1 网卡名称

云环境网卡名通常为 enp0s16 等。update-source 必须指定实际网卡名。

验证方法

bash 复制代码
ip -br addr

8.2 FRR 命令差异

FRR 8.x 的正确命令是 advertise-all-vni(无 s),而非 advertise-all-vnis

8.3 VNI 类型误识别

如果配置文件中存在残留的 vni <ID> 块(不在 address-family l2vpn evpn 下),FRR 会将其识别为 L3 VNI。

修复

bash 复制代码
vtysh -c "configure terminal" -c "no vni <ID>"

8.4 RD 格式

VNI 下的 RD 格式为 ASN:NN(如 65000:10001),不支持 auto

8.5 RR 的 retain route-target all

RR 节点必须 配置 retain route-target all,否则 RR 会按本地 RT 过滤路由。


9. 清理脚本

如需重置环境,在 node1 和 node2 上执行:

bash 复制代码
# 清理数据面
ip link del br-10001 2>/dev/null || true
ip link del br-10002 2>/dev/null || true
ip link del vni10001 2>/dev/null || true
ip link del vni10002 2>/dev/null || true
ip netns del vm1-sub100 2>/dev/null || true
ip netns del vm1-sub200 2>/dev/null || true
ip netns del vm2-sub100 2>/dev/null || true
ip netns del vm2-sub200 2>/dev/null || true
ip link del veth-vm1 2>/dev/null || true
ip link del veth-vm2 2>/dev/null || true
ip link del veth-vm3 2>/dev/null || true
ip link del veth-vm4 2>/dev/null || true

10. 附录:完整配置文件

10.1 RR - /etc/frr/frr.conf

ini 复制代码
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.6
 neighbor 172.20.2.9 remote-as 65000
 neighbor 172.20.2.9 description node1
 neighbor 172.20.2.9 update-source enp0s16
 neighbor 172.20.2.9 bfd
 neighbor 172.20.2.10 remote-as 65000
 neighbor 172.20.2.10 description node2
 neighbor 172.20.2.10 update-source enp0s16
 neighbor 172.20.2.10 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.9 activate
  neighbor 172.20.2.10 activate
  neighbor 172.20.2.9 route-reflector-client
  neighbor 172.20.2.10 route-reflector-client
  retain route-target all
 exit-address-family
 !
 bgp bestpath as-path multipath-relax
!

10.2 node1 - /etc/frr/frr.conf

ini 复制代码
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.9
 neighbor 172.20.2.6 remote-as 65000
 neighbor 172.20.2.6 description RR
 neighbor 172.20.2.6 update-source enp0s16
 neighbor 172.20.2.6 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.6 activate
  advertise-all-vni
  vni 10001
   rd 65000:10001
   route-target import 65000:10001
   route-target export 65000:10001
  exit-vni
  vni 10002
   rd 65000:10002
   route-target import 65000:10002
   route-target export 65000:10002
  exit-vni
 exit-address-family
!

10.3 node2 - /etc/frr/frr.conf

ini 复制代码
frr version 8.4.4
frr defaults traditional
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65000
 bgp router-id 172.20.2.10
 neighbor 172.20.2.6 remote-as 65000
 neighbor 172.20.2.6 description RR
 neighbor 172.20.2.6 update-source enp0s16
 neighbor 172.20.2.6 bfd
 !
 address-family l2vpn evpn
  neighbor 172.20.2.6 activate
  advertise-all-vni
  vni 10001
   rd 65000:10001
   route-target import 65000:10001
   route-target export 65000:10001
  exit-vni
  vni 10002
   rd 65000:10002
   route-target import 65000:10002
   route-target export 65000:10002
  exit-vni
 exit-address-family
!

11. 部署验证结果

实际测试结果

测试项 结果
BGP 邻居 (RR ↔ node1) ✅ Established,收到 4 条路由
BGP 邻居 (RR ↔ node2) ✅ Established,收到 4 条路由
EVPN Type 2 路由 ✅ 4 条 MAC 路由正常同步
EVPN Type 3 路由 ✅ 4 条 Inclusive Multicast 路由
VNI 10001 连通性 ✅ 0% 丢包,平均延迟 0.77ms
VNI 10002 连通性 ✅ 0% 丢包,平均延迟 0.64ms
相关推荐
BING_Algorithm1 小时前
Java开发常用网络协议解析
后端·网络协议
LucianaiB1 小时前
【腾讯位置服务开发者征文大赛】基于飞书 CLI + 腾讯位置的科研与产业地理情报可视化 Skill
后端
MacroZheng1 小时前
面试官:“你连Claude Code都没用过吗?”,我怼回去:“就没用过又怎么了?”
人工智能·后端·claude
用户298698530141 小时前
Java 实战:将 Markdown 文档转换为 Word 与 PDF
java·后端
掘金者阿豪1 小时前
Python 操作金仓数据库的完全指南(下篇):SQL执行、批量操作与扩展功能
后端
渐儿1 小时前
深度学习优化:从 SGD 到 Adam 的进化之路
后端
渐儿1 小时前
LLM模型部署与推理优化技术详解
后端
掘金者阿豪1 小时前
Python 操作金仓数据库的完全指南(上篇):连接管理与高可用
后端