目录

什么是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包如何构造 vxlan实现_UDP

执行数据包封装和解封装的实体称为VXLAN隧道终结点(VTEP)。VTEP主要分为两类:硬件VTEP和软件VTEP。硬件VTEP我接触较少,这里就不再介绍了。

软件VTEP如下图所示:VTEP在数据包到达虚拟机之前进行了封装和解封装,使得虚拟机完全不需要知道VXLAN隧道以及它们之间的三层网络。

vxlan包如何构造 vxlan实现_Open vSwitch_02

简单VXLAN实验

我们参照下图完成实验。

vxlan包如何构造 vxlan实现_网络_03

主机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个字节,不信你可以加一下上面的报文格式中的数字。