为什么要用VXLAN

随着云计算数据中心的大规模建设与运营,传统的依赖VLAN技术的二层网络技术面临着越来越多的问题:

  • vlan的数量限制

  4096个vlan远不能满足大规模云计算数据中心的需求

  • 物理网络基础设施的限制

   基于IP子网的区域划分限制了需要二层网络连通性的应用负载的部署

  • TOR交换机MAC表耗尽

    虚拟化以及东西向流量导致更多的MAC表项

  • 多租户场景

租户可以自定义网络,且无需考虑与其他租户IP地址的重叠。

目前解决这些问题的主要方案是基于overlay的大二层网络技术。典型的大二层网络技术由GRE技术和VXLAN技术。GRE技术不在本文的研讨范围之内,本博文将会专注介绍VXLAN的基本概念和技术原理。最后会详细介绍VXLAN的数据包在OpenStack环境中是如何流转的。

下面我们描述一个场景来进一步加深理解。

如下图所示,在OpenStack环境中已经占用了5000个VXLAN网络。因此,租户1创建了一个VXLAN ID为5001的网络,租户2创建了一个VXLAN ID为5002的网络。租户只需关心虚拟机在VXLAN网络上的连接,而无需关心物理服务器的网络是如何连接的。只要两台物理服务器能够通过物理网络通信,相同租户之间的VM就可以通过VXLAN通信。

openstack配置vlan网络 openstack vlan网络_openstack配置vlan网络

图1 VXLAN多租户应用场景

VXLAN的基本概念

VXLAN(VirtualeXtensible Local Area Network)是一种将二层报文用三层协议进行封装的技术,可以对二层网络在三层范围进行扩展。每个覆盖域被称为VXLAN segment,它的ID是由位于VXLAN数据包头中的VXLAN Network Identifier(VNI)标识的。VNI字段包含24 bits,故segments最大数量为2的24次方,约合16M个。并且只有在相同VXLAN segment内的虚拟机之间才可以相互通信。

根据VXLAN的封包方式,也可以将它看做一种隧道模式的网络覆盖技术,这种隧道是无状态的。隧道端点VTEP (VXLAN Tunnel End Point - an entity which originates and/orterminates VXLAN tunnels),它一般位于拥有虚拟机的hypervisor宿主机中,因此VNI(VXLAN Network Identifier or VXLAN Segment ID)和VXLAN隧道只有VTEP可见,对于虚拟机是透明的,那么不同的VXLAN segment中就允许具有相同MAC地址的虚拟机。并且VTEP也可以位于物理交换机或物理主机中,甚至可以使用软件来定义。VTEP (单播时是两个VTEP或多播时是多个VTEP)之间完全是通过L3协议交互的,这也就意味着VTEP间可以由Router相连,而非类似于GRE模式的固定端到端隧道连接。

上面的概念比较抽象,下面我提取几个关键点帮助大家理解

1.    VXLAN类似于VLAN技术,解决的是二层通信的问题;

2.    VXLAN ID用VNI表示,VNI字段包含24位,因此VXLAN的最大数量为2的24次方,约合16M个

3.    VXLAN是一种overlay技术,在云计算环境中体现的逻辑网络,它是基于物理网络之上的网络,在用户看来,物理网络是透明的。

4.    VXLAN采用的是隧道技术,只要隧道端到端之间是连通的,隧道两端的网络节点就可以属于同一个二层网络,并可以通信。

VXLAN技术原理

VXLAN是一种overlay网络技术,它在传统IP网络之上创建2层的逻辑网络。下面两点是overlay技术的基本特征:

  •  将原始数据包封装为新的头部,例如IPSec VPN,它把原始的IP帧封装到另外一个IP头部。
  • 在隧道的两个端点之间建立通信。例如,基于IPSec VPN基于因特网在两个站点之间建立隧道。

VXLAN将原始的MAC帧封装到一个UDP头部(如下图所示),云计算环境中的所有物理主机都充当了隧道的端口。它们被成为VTEPs(Virtual Tunnel Endpoints)。VXLAN数据包格式如下图所示:

openstack配置vlan网络 openstack vlan网络_单播_02

图2 VXLAN封包格式

主要字段说明

Outer MAC destination address (MAC addressof the tunnel endpoint VTEP)

Outer MAC source address (MAC address ofthe tunnel source VTEP)

Outer IP destination address (IP address ofthe tunnel endpoint VTEP)

Outer IP source address (IP address of thetunnel source VTEP)

Outer UDP header:Srcport 往往用于 load balancing,下文有提到;Dstport 即 VXLAN Port,默认值为 4789.

VNID:表示该帧的来源虚机所在的VXLAN 网段的 ID

特点:

VNID: 24-bits,最大 16777216。每个不同的 24-bits VNI 代表一个 VXLAN 网段。只有同一个网段中的虚机才能互相通信。

VXLAN Port:目的 UDP 端口,默认使用 4789 端口。用户可以自己配置。

两个 VTEP 之间的 VXLANtunnels 是无状态的。

VTEP 可以在虚拟交换机上,物理交换机或者物理服务器上通过软件或者硬件实现。

使用多播来传送未知目的的、广播或者多播帧。

在这里我们先复习一下单播、广播和多播的基础知识。接下来我会通过同一VXLAN的虚拟机如何做ARP地址解析的来详细描述数据包在传输路径中是如何流转的。

openstack配置vlan网络 openstack vlan网络_openstack配置vlan网络_03

图3 单播、广播、组播

1.单播:网络节点之间的通信就好像是人们之间的对话一样。如果一个人对另外一个人说话,那么用网络技术的术语来描述就是“单播”,此时信息的接收和传递只在两个节点之间进行。单播在网络中得到了广泛的应用,网络上绝大部分的数据都是以单播的形式传输的,只是一般网络用户不知道而已。例如,你在收发电子邮件、浏览网页时,必须与邮件服务器、Web服务器建立连接,此时使用的就是单播数据传输方式。但是通常使用“点对点通信”(Point to Point)代替“单播”,因为“单播”一般与“多播”和“广播”相对应使用。

2.多播:“多播”也可以称为“组播”,在网络技术的应用并不是很多,网上视频会议、网上视频点播特别适合采用多播方式。因为如果采用单播方式,逐个节点传输,有多少个目标节点,就会有多少次传送过程,这种方式显然效率极低,是不可取的;如果采用不区分目标、全部发送的广播方式,虽然一次可以传送完数据,但是显然达不到区分特定数据接收对象的目的。采用多播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的。IP网络的多播一般通过多播IP地址来实现。多播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址。

3.广播:“广播”在网络中的应用较多,如客户机通过DHCP自动获得IP地址的过程就是通过广播来实现的。但是同单播和多播相比,广播几乎占用了子网内网络的所有带宽。拿开会打一个比方吧,在会场上只能有一个人发言,想象一下如果所有的人同时都用麦克风发言,那会场上就会乱成一锅粥。集线器由于其工作原理决定了不可能过滤广播风暴,一般的交换机也没有这一功能,不过现在有的网络交换机(如全向的QS系列交换机)也有过滤广播风暴功能了,路由器本身就有隔离广播风暴的作用。   广播风暴不能完全杜绝,但是只能在同一子网内传播,就好像喇叭的声音只能在同一会场内传播一样,因此在由几百台甚至上千台电脑构成的大中型局域网中,一般进行子网划分,就像将一个大厅用墙壁隔离成许多小厅一样,以达到隔离广播风暴的目的。  在IP网络中,广播地址用IP地址“255.255.255.255”来表示,这个IP地址代表同一子网内所有的IP地址。

多播中相互通信的节点需要加入到同一个多播组中。

VTEP 通过组播寻址

VTEP提供VXLAN封装和解封装的功能,它运行在虚拟化主机上,如KVM或ESXi。

openstack配置vlan网络 openstack vlan网络_单播_04

图4 VTEP通过组播寻址

每个 VTEP 包含两个 VXLAN 隧道。VTEP-1 收到二层 ARP 帧1(A 要查找 B 的 MAC)后,发出一个 Dst IP 地址为VTEP多播组 239.1.1.1 的 VXLAN 封装 UDP 包。该包会达到 VTEP-2 和 VTEP-3。VTEP-3 收到后,因为目的 IP 地址不在它的范围内,丢弃该包,但是学习到了一条路径:MAC-A,VNI 10,VTEP-1-IP,它知道要到达 A 需要经过 VTEP-1 了。VTEP-2收到后,发现目的 IP 地址是机器 B,交给 B,同时添加学习到的规则 MAC-A,VNI 10,VTEP-1-IP。B 发回响应帧后,VTEP-2 直接使用VTEP-1 的 IP 直接将它封装成三层包,通过物理网络直接到达 VTEP-1,再由它交给 A。VTEP-1也学习到了一条规则 MAC-B,VNI 10,VTEP-2-IP。

HostB-A与Host-B通信的数据流向

openstack配置vlan网络 openstack vlan网络_UDP_05

图5 数据流向

发送端Host-A:

如果 Linux 的 MAC 表中包含该 MAC 地址对应的目的 VTEP 地址,则使用它;

如果是单播地址,但是 LInux 的MAC 表中不包含该 MAC 地址对应的目的 VTEP IP,那么使用该 VNI 对应的组播地址。

添加Headers:依次添加VXLAN header,UDP header,IPheader。

接收端:

UDP监听:因为 VXLAN 利用了 UDP,所以它在接收的时候势必须要有一个 UDP server 在监听某个端口,这个是在 VXLAN 初始化的时候完成的。

IP包剥离:一层一层剥离出原始的数据帧,交给 TCP/IP 栈,由它交给虚机。

实验:使用OpenvSwitch搭建VXLAN网络




openstack配置vlan网络 openstack vlan网络_openstack配置vlan网络_06



图6 VXLAN实验


 配置Host1

启动好OVS服务后,我们先配置一下Host1。

在Host1上添加名为br0和br1的两个网桥:

# ovs-vsctl add-br br0
# ovs-vsctl add-br br1

在br0上添加一个端口,将eth0挂载到br0上。这样做的目的是方便我们在虚拟网桥上添加多个端口供我们使用,这样不必受限于eth0的有限端口。

# ovs-vsctl add-port br0 eth0

此时我们将原先eth0分配的ip清除并指定给br0,让虚拟机网络能通过br0继续工作。

# ifconfig eth0 0 up && ifconfig br0 192.168.146.131/24 up

根据实际情况配置一下br0的网关。

# route add default gw 192.168.146.2 br0

给br1网桥分配一个ip。

# ifconfig br1 10.0.0.1/24 up

配置Host2

按Host1同样步骤来配置Host2。

# ovs-vsctl add-br br0
# ovs-vsctl add-br br1
# ovs-vsctl add-port br0 eth0
# ifconfig eth0 0 up && ifconfig br0 192.168.146.136/24 up
# route add default gw 192.168.146.2 br0

给Host2的br1网桥分配一个和Host1中br1不同网段的ip。

# ifconfig br1 10.0.1.1/24 up

搭建VXLAN隧道

在搭建隧道之前我们先测试一下两台虚拟机Host1和Host2上的br0和br1两两之间是否能相互通信。

root@ubuntu:~# ping 192.168.146.136        ## Host1 ping Host2的br0
PING192.168.146.136(192.168.146.136)56(84)bytesofdata.
64bytesfrom192.168.146.136:icmp_seq=1ttl=64time=1.88ms
64bytesfrom192.168.146.136:icmp_seq=2ttl=64time=0.703ms
root@ubuntu:~# ping 10.0.1.1        ## Host1 ping Host2的br1
PING 192.168.146.136 (192.168.146.136) 56(84) bytes of data.

br1和另一方的br1则不能通信,我们搭建隧道的目的就是让两台机器的br1(数据层面)能够实现通信。


1. 在Host1上设置VXLAN,远端ip设置为Host2能对外通信的br0的ip。

# ovs-vsctl add-port br1 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.146.136

2. 在Host2上设置VXLAN,远端ip设置为Host1能对外通信的br0的ip。

# ovs-vsctl add-port br1 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.146.131

验证VxLAN隧道

两台机器的br1互ping可以实现正常通信:

root@ubuntu:~# ping 10.0.1.1
PING10.0.1.1(10.0.1.1)56(84)bytesofdata.
64bytesfrom10.0.1.1:icmp_seq=1ttl=64time=15.4ms
64bytesfrom10.0.1.1:icmp_seq=2ttl=64time=0.715ms
……
 
root@ubuntu:~# ping 10.0.1.1
PING10.0.1.1(10.0.1.1)56(84)bytesofdata.
64bytesfrom10.0.1.1:icmp_seq=1ttl=64time=15.4ms
64bytesfrom10.0.1.1:icmp_seq=2ttl=64time=0.715ms


结论

本实验搭建了基于Open vSwitch的VXLAN隧道,实现了不同网段内网机器的通信。实验是基于Open vSwitch的虚拟交换机进行实验的,有条件的朋友可以在真实环境中实验一下。