linux 设备之间的 vxlan 实践
1. 软硬件环境
- PC 电脑 + VMware Workstation 虚拟机
- VMware 安装两个 ubuntu 虚拟机, 网络均采用桥接模式
在 ubuntu 虚拟机中使用 uname -r
命令查看 Linux 内核版本
root@cfpl:/# uname -r
5.15.0-71-generic
因为 Linux 内核从 Linux 3.7 版本开始支持 VXLAN,到了内核 3.12 版本对 VXLAN 的支持已经完备,支持单播和组播,IPv4 和 IPv6,我安装的两个ubuntu 分别是 20.04 和 22.04 , 内核版本均已满足。
两个虚拟机因选择了桥接模式,所以在同一网段下,配置如下:
- ubuntu1: wan 接口名称 ens33, IP 地址 192.168.4.220
- ubuntu2: wan 接口名称 ens33, IP 地址 192.168.4.217
2. vxlan 配置
2.1. 单播配置
# ubuntu1
ip link add vxlan0 type vxlan id 10 remote 192.168.4.217 local 192.168.4.220 dstport 4789 dev ens33
ip addr add 10.0.0.10/24 dev vxlan0
ip link set vxlan0 up
# ubuntu2
ip link add vxlan0 type vxlan id 10 remote 192.168.4.220 local 192.168.4.217 dstport 4789 dev ens33
ip addr add 10.0.0.20/24 dev vxlan0
ip link set vxlan0 up
经过以上设置后,使用 ifconfig
命令查看, 应该会存在 vxlan0 名称的网络接口
root@cfpl:/# ifconfig vxlan0
vxlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.0.0.10 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::876:69ff:fefc:3e4d prefixlen 64 scopeid 0x20<link>
ether 0a:76:69:fc:3e:4d txqueuelen 1000 (以太网)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 36 bytes 4734 (4.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
配置完成后, 在 ubuntu2 虚拟机上使用 ping 10.0.0.10
来测试是否连通
在 ubuntu1 上使用 wireshark 或者 tcpdump 工具在 ens33 接口进行抓包, 抓到的 Echo Request 如下
传统以太网帧无法穿越三层网络,VXLAN 通过 VTEP设备进行部署, VTEP 全称 VXLAN Tunnel Endpoint , VTEP设备可以对VXLAN报文进行封装与解封装,包括ARP请求报文和正常的VXLAN数据报文,通过解析VXLAN 报文中的 Virtual Network ID ( VNI) 来转发给不同的设备或网络接口,实验中 ubuntu1和 ubuntu2 虚拟机就是两个 VTEP设备。
我的理解是 vxlan 网络通过 VNI 划分不同的区域(segment), 同一 VNI 的 vxlan 网络设备可以进行通信(即使 IP 在不同网段,可以通过隧道进行通信,这个隧道是无连接状态的)
我们在 vxlan0 接口进行抓包, 可以看到收到的 Echo Request 包已经进行了解封装的,并且回复的 Echo Reply 包是也没有 outer 等报文头部的。
2.2. 组播配置
设置组播配置前先使用 ip link del vxlan0
删除 vxlan0 接口,或者新增加 vxlan1 接口(并且 VNI 不能与 vxlan0 相同) 以避免冲突
# ubuntu1
ip link add vxlan0 type vxlan id 10 group 239.1.1.1 dstport 4789 dev ens33
ip addr add 20.0.0.10/24 dev vxlan0
ip link set vxlan0 up
# ubuntu2
ip link add vxlan0 type vxlan id 10 group 239.1.1.1 dstport 4789 dev ens33
ip addr add 20.0.0.20/24 dev vxlan0
ip link set vxlan0 up
同样配置完成后, 在 ubuntu2 虚拟机上使用 ping 20.0.0.10
来测试是否连通
在同一 segment (VNI 相同)的 VTEP 设备可以相互通信,一开始 utuntu2 设备并不知道 utuntu1 设备 MAC 地址,需要发送一个 ARP 请求报文,这个报文是组播的,在 239.1.1.1 分组下的所有的 VETP 设备都能收到这个 ARP 包,只有判断是这个 20.0.0.10 IP 的设备才会做出响应,当 ubuntu1收到 ARP 报文,学习到了 outer IP,inter IP 以及 inter Mac 之间的联系,下次发包就不再是组播包了。
2.3. openwrt 环境的配置
首先使用 uname -r
查看内核版本,其次openwrt 可能存在ip命令可能支持不全以及内核选项 Kmod-vxlan
未打开的问题
在编译时进行如下操作
make menuconfig
Kernel modules
---> Network Support
---> <*> kmod-vxlan
Network
---> <*> vxlan
---> Routing and Redirection
<*> ip-bridge
<*> ip-full
在使用 ip link add type vxlan help
命令时,如能显示如下类似描述, 表示 ip link 命令是支持 vxlan 类型的
root@openwrt:/# ip link add type vxlan help
Usage: ... vxlan id VNI [ { group | remote } ADDR ] [ local ADDR ]
[ ttl TTL ] [ tos TOS ] [ dev PHYS_DEV ]
[ dstport PORT ] [ srcport MIN MAX ]
[ [no]learning ] [ [no]proxy ] [ [no]rsc ]
[ [no]l2miss ] [ [no]l3miss ]
[ ageing SECONDS ] [ maxaddress NUMBER ]
[ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]
[ [no]remcsumtx ] [ [no]remcsumrx ]
[ [no]external ] [ gbp ]
Where: VNI := 0-16777215
ADDR := { IP_ADDRESS | any }
TOS := { NUMBER | inherit }
TTL := { 1..255 | inherit }
参考:
https://blog.csdn.net/weixin_43614963/article/details/120705139
https://blog.csdn.net/weixin_30834169/article/details/112403777