本文首发于我的公众号码农之屋(id: Spider1818),专注于干货分享,包含但不限于Java编程、网络技术、Linux内核及实操、容器技术等。欢迎大家关注,二维码文末可以扫。
导读:云时代的到来,导致传统二层网络技术,在链路使用率、收敛时间等方面都不满足需求,即便使用VLAN隔离用户和虚拟机,理论上也只能支持4K个标签。VXLAN主要是解决VLAN有限标签的问题。
传统的交换网络解决了二层的互通及隔离问题,这个架构发展了几十年已经相当成熟。而随着云时代的到来,却逐渐暴露出了一些主要的缺点。
1)多租户环境和虚拟机迁移
为了满足在云网络中海量虚拟机迁移前后业务不中断的需要,要求虚拟机迁移前后的IP不能变化,继而要求网络必须是大二层结构。传统的二层网络技术,在链路使用率、收敛时间等方面都不能满足需要。
2)VLAN的局限
随着云业务的运营,租户数量剧增。传统交换网络用VLAN来隔离用户和虚拟机,但理论上只支持最多4K个标签的VLAN,已无法满足需求。
为了解决上述局限性,不论是网络设备厂商,还是虚拟化软件厂商,都提出了一些新的Overlay解决方案。
网络设备厂商,基于硬件设备开发出了EVI(Ethernet Virtualization Interconnect)、TRILL(TransparentInterconnection of Lots of Links)、SPB(Shortest Path Bridging)等大二层技术。这些技术通过网络边缘设备对流量进行封装/解封装,构造一个逻辑的二层拓扑,同时对链路充分利用、表项资源分担、多租户等问题采取各自的解决方法。此类技术一般要求网络边缘设备必须支持相应的协议,优点是硬件设备表项容量大、转发速度快。
虚拟化软件厂商,从自身出发,提出了VXLAN(Virtual eXtensible LAN)、NVGRE(Network Virtualization Using Generic RoutingEncapsulation)、STT(A StatelessTransport Tunneling Protocol for Network Virtualization)等一系列技术。这部分技术利用主机上的虚拟交换机(vSwitch)作为网络边缘设备,对流量进行封装/解封装。优点是对网络硬件设备没有过多要求。
通过表1,我们可以看到这几种Overlay技术对比。其中,虚拟化软件厂商提出的Overlay技术由于天然支持vSwitch,在云计算网络中更有优势。
表1 各种Overlay技术比较
通过表2,可以看到VXLAN、NVGRE、STT这三种技术的区别。与NVGRE相比,VXLAN不需要改变报文结构即可支持L2~L4的链路负载均衡;与STT相比,VXLAN不需要修改传输层结构,与传统网络设备完美兼容。由此,VXLAN脱颖而出,成为了SDN环境下的主流Overlay技术。
表2 VXLAN、NVGRE及STT对比
VXLAN采用MAC-in-UDP的报文封装模式,可实现二层网络在三层范围内进行扩展,满足数据中心大二层虚拟机迁移的需求。在VXLAN网络中,属于相同VXLAN的虚拟机处于同一个逻辑二层网络,彼此之间二层互通;属于不同VXLAN的虚拟机之间二层隔离。
VXLAN最初只在虚拟交换机实现,但虚拟交换机天然具有转发性能低下的缺点,并不适合大流量的网络环境。于是,各硬件厂商也纷纷推出支持VXLAN的硬件产品,与虚拟交换机一起,共同成为网络边缘设备,最终使VXLAN技术能够适应各种网络。
图1 VXLAN网络基本模型
• VNI(VXLAN网络标识符):VXLAN通过VXLAN ID来标识,其长度为24比特。16M个标签数解决了VLAN标签不足的缺点。
• VTEP(VXLAN隧道端点):VXLAN的边缘设备。VXLAN的相关处理都在VTEP上进行,例如识别以太网数据帧所属的VXLAN、基于VXLAN对数据帧进行二层转发、封装/解封装报文等。VTEP可以是一台独立的物理设备,也可以是虚拟机所在服务器的虚拟交换机。
• VXLAN Tunnel:两个VTEP之间点到点的逻辑隧道。VTEP为数据帧封装VXLAN头、UDP头、IP头后,通过VXLAN隧道将封装后的报文转发给远端VTEP,远端VTEP对其进行解封装。
• VSI(Virtual Switching Instance,虚拟交换实例):VTEP上为一个VXLAN提供二层交换服务的虚拟交换实例。VSI可以看作是VTEP上的一台基于VXLAN进行二层转发的虚拟交换机,它具有传统以太网交换机的所有功能,包括源MAC地址学习、MAC地址老化、泛洪等。
• VSI-Interface(VSI的虚拟三层接口):类似于Vlan-Interface,用来处理跨VNI即跨VXLAN的流量。VSI-Interface与VSI一一对应,在没有跨VNI流量时可以没有VSI-Interface。
图2 VTEP中的对应关系
现有VTEP设备中,一般用“接口+VLAN”的方式来区分流量与VSI的对应关系,而VSI与VXLAN Tunnel之间既可以建立全连接,也可以根据需求进行关联。
RFC7348规定了VXLAN报文的格式:
图3 VXLAN报文一般封装
• Outer MAC Header:封装外层以太头,14字节,如果有VLANTAG则为18字节。其中,源MAC地址为源VM所属VTEP的MAC地址,目的MAC地址为到达目的VTEP的路径上下一跳设备的MAC地址。类型字段为0x0800,指示内层封装的是IP报文。
• Outer IP Header:封装外层IP头,20字节。其中,源IP地址为源VM所属VTEP的IP地址,目的IP地址为目的VM所属VTEP的IP地址。协议字段为0x11,指示内层封装的是UDP报文。
• UDP Header:UDP报文头,8字节。其中,UDP目的端口号固定为4789,指示内层封装报文为VXLAN报文。UDP源端口号为随机任意值,可以用于VTEP之间多路径负载分担的计算。
• VXLAN Header:VXLAN协议新定义的VXLAN头,8字节。
• Flags:8 bit,RRRRIRRR。“I”位为1时,表示VXLAN头中的VXLAN ID有效;为0,表示VXLAN ID无效。“R”位保留未用,设置为0。
• VXLAN ID(VNI):24 bit,用于标识一个单独的VXLAN网络。
• Reserved:分别为24 bit和8 bit。保留位。
• Original L2 Frame:原始以太网报文。
从报文的封装可以看出,VXLAN头和原始二层报文是作为UDP报文的载荷存在的。在VTEP之间的网络设备,只需要根据OuterMAC Header和OuterIP Header进行转发,利用UDPSource Port进行负载分担,这一过程,与转发普通的IP报文完全相同。这样,除了VTEP设备,现网的大量设备无需更换或升级即可支持VXLAN网络。
不过,新增加的VXLAN报文封装也引入了一个问题,即MTU值的设置。
一般来说,虚拟机的默认MTU为1500 Bytes,也就是说原始以太网报文最大为1500字节。这个报文在经过VTEP时,会封装上50字节的新报文头(VXLAN头8字节+UDP头8字节+外部IP头20字节+外部MAC头14字节),这样一来,整个报文长度达到了1550字节。而现有的VTEP设备,一般在解封装VXLAN报文时,要求VXLAN报文不能被分片,否则无法正确解封装。这就要求VTEP之间的所有网络设备的MTU最小为 1550字节。
BUM(Broadcast, Unknown-unicast, Multicast)即广播、未知单播、组播流量。根据对泛洪流量的复制方式不同可分为单播路由方式和组播路由方式两种。
1、单播路由方式泛洪
图4 单播路由方式泛洪
在单播路由方式下,VTEP负责复制报文,采用单播方式将复制后的报文通过本地接口发送给本地站点,并通过VXLAN隧道发送给VXLAN内的所有远端VTEP。
如图4所示,当VTEP 1上的VM 1发出BUM报文后,VTEP 1判断数据所属的VXLAN,通过该VXLAN内所有本地接口和VXLAN Tunnel转发报文。通过VXLAN Tunnel转发报文时,封装VXLAN头、UDP头和IP头,将泛洪报文封装于单播报文中,发送到VXLAN内的所有远端VTEP。
远端VTEP收到VXLAN报文后,解封装报文,将原始数据在本地站点的VXLAN内泛洪。为避免环路,远端VTEP从VXLAN隧道上接收到报文后,不会再将其泛洪到其他的VXLAN隧道。
2、组播路由方式泛洪
图5 组播路由方式泛洪
组播路由方式的组网中同一个VXLAN内的所有VTEP都加入同一个组播组,利用组播路由协议在IP网络上为该组播建立组播转发表项,VTEP上相应生成一个组播隧道。
如图5所示,当VTEP 1上的VM 1发出BUM报文后,VTEP 1不仅在本地站点内泛洪,还会为其封装组播目的IP地址,封装后的报文根据已建立的组播转发表项转发到IP网络。
在组播报文到达IP网络中的中间设备时,该设备根据已建立的组播表项对报文进行复制并转发。
远端VTEP(VTEP 2和VTEP 3)接收到报文后,解封装报文,将原始的数据帧在本地站点的指定VXLAN泛洪。为了避免环路,远端VTEP从VXLAN隧道上接收到报文后,不会再将其泛洪到其他的VXLAN隧道。
由于泛洪流量使用了组播技术,所以整个组网中的网络设备需要支持组播路由协议来建立组播路径以便组播报文转发。
下面,我们用实际的例子帮助大家理解VXLAN是如何完成报文转发的,其中,BUM报文采用头端复制的方法进行泛洪。
1、同VNI单播报文转发流程
图6 ARP请求报文转发流程
• ARP请求报文转发流程
1. VM 1与VM3的IP地址在同一网段。VM 1想要与VM 3进行通信,但发现没有VM 3的MAC地址,于是发起VM 3的ARP请求报文。ARP请求报文的源IP是VM 1的IP,目的IP是VM 3的IP,源MAC是VM 1的MAC,目的MAC则是全0字段,表示希望获得VM 3的MAC信息。外层封装以太网头,其中目的MAC为全F,表示这是一个广播报文。
2. Leaf A收到了VM 1发来的ARP请求报文,根据其入端口和VLAN信息,判断出这个报文应该匹配VXLAN 10。将VXLAN、MAC、入端口和VLAN信息写入相应的VSI MAC表中。
3. Leaf A发现ARP请求报文是一个广播报文,于是将这个报文在本地和远端所有VXLAN 10的端口进行广播。由于本流程广播采用头端复制的方法,Leaf A将给Leaf B和Spine C各发送一份VXLAN报文。Leaf A发送给Leaf B的报文,最外层是以太网头,接着是IP头,其中源IP是Leaf A的IP,目的IP是Leaf B的IP。再往内是UDP头和VXLAN头,其中VNI为10。最内层是VM 1的ARP请求报文。Leaf A发给Spine C的报文封装相同,不同之处在于外层目的IP是Spine C的IP,外层目的MAC根据下一跳不同而不同。
4. Spine C收到Leaf A发来的报文,发现外层目的IP是自己,于是将其解封装。发现UDP的目的端口是4789,于是将UDP的上层报文进行VXLAN解封装处理。根据VXLAN报文的信息,将VXLAN、内部MAC、入端口等信息写入相应的VSI MAC表中。再发现内部原始二层报文是一个广播报文,根据水平分割的要求,不再往其他VTEP设备转发,只在本地的VXLAN10端口内进行广播。由于Spine C上没有连接服务器,所以Spine C对这个报文不再进行后续处理,予以丢弃。
5. 同样的,Leaf B也收到Leaf A发来的报文,解封装后,将VXLAN、内部MAC、入端口等信息写入相应的VSI MAC表中。由于报文是从Tunnel 1中收到的,所以端口信息为Tunnel 1。根据VXLAN 10的映射关系表,将原始二层报文在本地所有VXLAN 10端口进行广播。
6. 最终VM 3收到了VM 1的ARP请求报文,将VM 1的IP和MAC对应关系写入自己的ARP表项,准备进行ARP应答。
图7 ARP应答报文转发流程
• ARP应答报文转发流程
1. VM 3给VM 1发送ARP应答报文。ARP应答报文的源IP是VM 3的IP,目的IP是VM 1的IP,源MAC是VM 3的MAC,目的MAC是VM 1的MAC。外层封装以太网头,源MAC是VM 3的MAC,目的MAC是VM 1的MAC,表示这是一个单播报文。
2. Leaf B收到VM3发来的ARP应答报文,根据其入端口和VLAN信息,判断出这个报文应该匹配VXLAN 10。将VXLAN、MAC、入端口和VLAN信息写入相应的VSI MAC表中。
3. Leaf B发现ARP应答报文是一个单播报文,其目的MAC是MAC 1,于是在VXLAN 10中查找。发现MAC 1的条目存在,其对应的端口为VXLAN Tunnel 1,于是把原始报文进行VXLAN封装。最外层是以太网头,接着是IP头,其中源IP是Leaf B的IP,目的IP是Leaf A的IP。再往内是UDP头和VXLAN头,其中VNI为10。最内层是VM 3的ARP应答报文。
4. Leaf A收到Leaf B发来的报文,发现外层目的IP是自己,于是将其解封装。发现UDP的目的IP是4789,于是将UDP的上层报文进行VXLAN解封装处理。根据VXLAN报文的信息,将VXLAN、内部MAC、入端口等信息写入相应的VSI MAC表中。发现原始二层报文的目的MAC为MAC 1,于是在VXLAN 10中查找,找到MAC 1的对应表项,将报文从对应端口发送出去。
5. VM 1收到了VM 3的ARP应答报文,将VM 3的IP和MAC写入ARP表项中,完成了此次ARP的学习。
图8 同VNI单播报文转发流程
• 同VNI单播报文转发流程
1. 在进行ARP报文的交互后,VM 1上已经存在VM 3的ARP表项,VM 3上也有VM 1的ARP表项。之后,VM 1和VM 3的通信就走单播报文转发流程了。
2. VM 1将发给VM 3的单播报文发送出去。Leaf A收到VM 1发来的报文,发现其目的MAC为MAC 3,在VXLAN 10中查找到MAC 3后,进行VXLAN封装后通过Tunnel 1发送出去。
3. Leaf B收到Leaf A发来的报文,解封装后在VXLAN 10中找到MAC 3表项,将其在对应的本地端口和VLAN中发出去。
4. VM 3收到报文后,往VM 1发送单播报文的流程相同,在此不再赘述。
图9 跨VNI单播报文转发
跨VNI的流量需要经过VXLAN L3 Gateway(VXLAN L3 Gateway用于转发跨VXLAN的流量,后文有详细介绍)来转发,这里采用集中式网关的模式进行说明。
由于是首次进行通信,且VM 1和VM 4处于不同网段。VM 1的网关VSI-Interface 10的IP为IP G10,MAC为MAC G10;VM4的网关VSI-Interface 20的IP为IP G20,MAC为MACG20;VSI-interface 10 和VSI-interface 20均在Spine C上。VM 1需要先发送ARP广播报文请求网关(VSI-Interface 10)的MAC,获得网关的MAC后,VM 1先将数据报文发送给网关;之后网关也将发送ARP广播报文请求VM 4的MAC,获得VM 4的MAC后,网关再将数据报文发送给VM 4。以上MAC地址学习的过程与同子网互通中MAC地址学习的流程一致,不再赘述。现在假设VM 1和VM 4均已学到网关的MAC、网关也已经学到VM 1和VM 4的MAC,下面就让我们来看下数据报文是如何从VM 1发送到VM 4的。
1. VM 1先将报文发送给网关。报文的源MAC是VM 1的MAC,目的MAC是网关VSI-Interface 10的MAC,源IP是VM 1的IP,目的IP是VM 4的IP。
2. Leaf A收到VM 1发来的报文,识别此报文属于VXLAN 10,查找目的MAC G10的表项,就报文进行VXLAN封装后从Tunnel 2发送出去。其中,VXLAN头中的VNI为10;外层源IP地址为Leaf A的IP,外层目的IP地址为Spine C的IP;外层源MAC地址为Leaf A的MAC,而外层目的MAC地址为去往目的IP的网络中下一跳设备的MAC地址。封装后的报文,根据外层MAC和IP信息,在IP网络中进行传输,直至到达对端VTEP。
3. Spine C收到Leaf A发来的报文,发现外层目的IP是自己,于是对报文进行解封装。解完封装后,Spine C发现原始二层报文的目的MAC为本机VSI-interface 10的MAC,目的IP是IP4,于是根据路由表查找IP 4的下一跳。发现一下跳为Leaf B,出接口为VSI-Interface 20。再查询ARP表项,并将原始二层报文的源MAC修改为VSI-interface 20的MAC,将目的MAC修改为VM 4的MAC。报文到达VSI-interface 20接口时,识别到需要进入VXLAN20隧道,所以根据MAC表对报文进行封装。这里封装的VXLAN头中的VNI为20,外层源IP地址为Spine C的IP地址,外层目的IP地址为Leaf B的IP地址;外层源MAC地址为Spine C的MAC地址,而外层目的MAC地址为去往目的IP的网络中下一跳设备的MAC地址。封装后的报文,根据外层MAC和IP信息,在IP网络中进行传输,直至到达对端VTEP。
4. Leaf B收到Spine C发来的报文后,解封装,得到原始二层报文。在VXLAN 20内找到目的MAC为MAC 4的表项,并将报文从对应的接口和VLAN中发送出去。最终VM 4收到了来自VM 1的报文。
5. VM 4发送给VM 1的过程与此类似,在此不再赘述。
我的公众号「码农之屋」(id: Spider1818) ,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。