目录
什么是VXLAN?
VXLAN解决了什么问题?
VXLAN网络如何工作?
简单VXLAN实验
主机A
主机B
测试
什么是VXLAN?
VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),是由IETF定义的NVO3(Network Virtualization over Layer 3)标准技术之一,是对传统VLAN协议的一种扩展。VXLAN的特点是将L2的以太帧封装到UDP报文(即L2 over L4)中,并在L3网络中传输。
VXLAN解决了什么问题?
- 突破了VLAN技术4094个隔离网络的限制,在一个管理域中创建多达1600万个VXLAN网络。
- VXLAN提供了云服务厂商所需的规模的网络分段,以支持大量租户。
- 突破了物理网络边界的限制,传统虚拟二层网络(VLAN)是需要和物理网络做大量适配工作才能保证环境的迁移不会导致虚拟网络异常,overlay网络则不必关心底层物理网络是如何搭建的,只要能保证VXLAN端点相互之间可以联通即可。
VXLAN网络如何工作?
VXLAN隧道协议将二层以太网帧封装在三层UDP数据包中,使用户能够创建跨物理三层网络的虚拟化二层子网或网段。每个二层子网使用VXLAN网络标识符(VNI)作为唯一标识。报文格式如下图:
执行数据包封装和解封装的实体称为VXLAN隧道终结点(VTEP)。VTEP主要分为两类:硬件VTEP和软件VTEP。硬件VTEP我接触较少,这里就不再介绍了。
软件VTEP如下图所示:VTEP在数据包到达虚拟机之前进行了封装和解封装,使得虚拟机完全不需要知道VXLAN隧道以及它们之间的三层网络。
简单VXLAN实验
我们参照下图完成实验。
主机A
# 创建隧道网桥
ovs-vsctl add-br br-tun
# 创建隧道端口并指定远端IP和VXLAN ID
ovs-vsctl add-port br-tun vx01 -- set Interface vx01 type=vxlan options:remote_ip=192.168.2.12 options:key=1111
# 创建内部端口
ovs-vsctl add-port br-tun vnet0 -- set Interface vnet0 type=internal
# 创建netns用于模拟虚拟网络设备
ip netns add ns0
# 将内部端口移动到netns中
ip link set vnet0 netns ns0
# 启动网卡
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip link set vnet0 up
# 配置IP
ip netns exec ns0 ip addr add 192.168.0.1/24 dev vnet0
[root@node01 ~]# ovs-vsctl show
4a2b2b93-bf98-4fc5-a50f-927f86d8c6e8
Bridge br-tun
Port "vx01"
Interface "vx01"
type: vxlan
options: {key="1111", remote_ip="192.168.2.12"}
Port "vnet0"
Interface "vnet0"
type: internal
Port br-tun
Interface br-tun
type: internal
ovs_version: "2.11.0"
主机B
# 创建隧道网桥
ovs-vsctl add-br br-tun
# 创建隧道端口并指定远端IP和VXLAN ID
ovs-vsctl add-port br-tun vx01 -- set Interface vx01 type=vxlan options:remote_ip=192.168.2.11 options:key=1111
# 创建内部端口
ovs-vsctl add-port br-tun vnet0 -- set Interface vnet0 type=internal
# 创建netns用于模拟虚拟网络设备
ip netns add ns0
# 将内部端口移动到netns中
ip link set vnet0 netns ns0
# 启动网卡
ip netns exec ns0 ip link set lo up
ip netns exec ns0 ip link set vnet0 up
# 配置IP
ip netns exec ns0 ip addr add 192.168.0.2/24 dev vnet0
[root@node02 ~]# ovs-vsctl show
25dd36a4-1b9b-42e1-b365-7c534875a517
Bridge br-tun
Port br-tun
Interface br-tun
type: internal
Port "vnet0"
Interface "vnet0"
type: internal
Port "vx01"
Interface "vx01"
type: vxlan
options: {key="1111", remote_ip="192.168.2.11"}
ovs_version: "2.11.0"
测试
在主机A
上测试网络连通性 ip netns exec ns0 ping 192.168.0.2
[root@node01 ~]# ip netns exec ns0 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.617 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.413 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.426 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.376 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=0.437 ms
64 bytes from 192.168.0.2: icmp_seq=6 ttl=64 time=0.379 ms
64 bytes from 192.168.0.2: icmp_seq=7 ttl=64 time=0.363 ms
可以看到我们只使用一张网卡就成功的在已有的物理网络上建立了一个新的分布式二层网络。
在这个实验中我使用了固定的VXLAN ID 1111,只是为了简化实验,无其他含义。
当我们此时在主机B上对物理网卡eth0
使用tcpdump
抓包时。
tcpdump -l -n -vv -i eth0 'port 4789 and udp[8:2] = 0x0800 & 0x0800 and udp[11:4] = 1111 & 0x00FFFFFF'
可以看到类似我下面截取的数据包。
[root@node02 ~]# tcpdump -l -n -vv -i eth0 'port 4789 and udp[8:2] = 0x0800 & 0x0800 and udp[11:4] = 1111 & 0x00FFFFFF'
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:22:24.544957 IP (tos 0x0, ttl 64, id 2843, offset 0, flags [DF], proto UDP (17), length 134)
192.168.2.11.52033 > 192.168.2.12.4789: [no cksum] VXLAN, flags [I] (0x08), vni 1111
IP (tos 0x0, ttl 64, id 8607, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.1 > 192.168.0.2: ICMP echo request, id 2862, seq 7, length 64
10:22:24.545015 IP (tos 0x0, ttl 64, id 32291, offset 0, flags [DF], proto UDP (17), length 134)
192.168.2.12.51555 > 192.168.2.11.4789: [no cksum] VXLAN, flags [I] (0x08), vni 1111
前两行是underlay
网络的报文,也就是底层承载网络。分别是:
- 底层协议
proto UDP (17)
- 包长度
length 134
- 源和目的地址
192.168.2.11.52033 > 192.168.2.12.4789
- VXLAN ID:
vni 1111
后两行是overlay
网络的报文,也就是我们的虚拟网络。分别是:
- 承载的协议是
proto ICMP (1)
- 包长度
length 84
- 源和目的地址
192.168.0.1 > 192.168.0.2
可以看出这些信息和我们的实验环境非常匹配,只有包大小不太一致,这是因为underlay
网络的基础信息刚好占有了50个字节,不信你可以加一下上面的报文格式中的数字。