一:背景
看过了红宝书之前的之前的部分,相信大家对数据中心网络虚拟化技术有了一些基本的认识。本文所要讨论的M-LAG技术是一种跨设备的链路聚合技术,主要的应用场景是双归接入场景。
我们先简单总结一下之前的内容,在服务器跨核心层二层互访模型中,核心层与接入层设备有两个问题是必须要解决的,一是拓扑无环路,二是多路径转发。但是传统以太网通过xSTP破环无法做到多路径转发,于是产生了以下两种解决的思路:
思路一:控制平面虚拟化(堆叠/VSS/IRF&SVF/FEX/IRF3)
控制平面虚拟化的思想是将核心层虚拟成一台逻辑设备,通过链路聚合使此逻辑设备与每个接入层物理或逻辑节点设备均只通过一条逻辑链路连接,将整个网络逻辑拓扑变成一个无环的树状连接结构,从而满足无环与多路径转发的需求。
控制平面虚拟化解决了二层网络无环和多路径问题,但是其技术本身也存在一些问题:
1. 扩展性受限,受到Master设备性能限制。
2. 可靠性问题,控制平面完全耦合,控制面故障可能导致整个系统故障。
3. 维护麻烦,无法进行独立设备升级。升级时由于控制面完全耦合,业务中断时间较长。无损升级(ISSU)的方案操作起来非常麻烦。
思路二:数据平面虚拟化(TRILL/FP&Nvo3)
数据平面虚拟化即在原本的以太网络上引入一套新的寻址机制(新的寻址标识或者借助IP转发机制)来解决二层多路径问题。对接入层以下的设备来说,整个中间系统被虚拟成了一台框式交换机,原始报文进入这个中间系统,不关心在其中做了什么处理,只需要知道报文会原封不动的从另外一端出来,就如同两台服务器被连到了一台二层交换机上,而在二层交换机内部,可以通过各种方式来实现多路径转发。
这类技术解决了网络侧多路径转发和破环问题,并且大多利用了路由的机制,解决了扩展性的问题,同时故障影响范围也较小。但是其接入侧的多路径问题还是无法解决。比如上图中,无论接入交换机双归接入,还是服务器直接双归接入,还是需要借助二层破环协议(例如xSTP)进行破环,无法做到多路径转发。
于是我们想到,何不将堆叠/SVF的机制引入到TRILL/VXLAN网络中,为其接入侧多路径转发服务。
这样,一种跨设备链路聚合技术M-LAG(Multichassis Link Aggregation Group)产生了。
M-LAG技术的基本思想是,让两台接入交换机以同一个状态和被接入的设备进行链路聚合协商,在被接入的设备看来,就如同和一台设备建立了链路聚合关系。其逻辑拓扑就如同上图右侧所示。
M-LAG技术本质上还是控制平面虚拟化技术,但是和堆叠/SVF技术不同的是,由于M-LAG的目的仅仅是在链路聚合协商时,对外表现出同样的状态,所以不需要像堆叠,SVF那样同步设备上所有的信息,只需要同步接口和表项相关的一些内容。这样,控制面耦合程度相比堆叠/SVF来说,会小很多。
这样,堆叠/SVF技术的一些缺陷在M-LAG上也会缓解很多,比如上面我们说过的堆叠/SVF的三个主要的问题:
1. 扩展性问题:M-LAG技术并没有解决扩展性问题,但是其主要目的是为了解决接入侧多路径问题,在数据中心网络中一般会配合路由或者一些大二层技术。所以扩展性并非其需要考虑的问题。
2. 可靠性问题:M-LAG需要同步的仅仅是协议面的一些内容,并不需要同步所有的设备状态,理论可靠性相对堆叠/SVF更加好。
3. M-LAG两台设备可以进行独立升级。仅协议面耦合,中断时间较短。
二:基本概念
-
M-LAG:跨设备链路聚合组,是一种实现跨设备链路聚合的机制,能够实现多台设备间的链路聚合,从而把链路可靠性从单板级提高到了设备级,组成双活系统。
-
M-LAG主/备设备:和堆叠/SVF一样,M-LAG也会选取主/备设备,但是正常情况下,主/备设备转发行为没有区别,仅在故障场景下,主备设备的行为会有差别,在后面故障场景中我们会讲到。
-
Dfs-group:动态交换服务组协议,M-LAG双归设备之间的接口状态,表项等信息同步需要依赖Dfs-group协议进行同步。
-
Peer-link:部署M-LAG的两台设备之间必须存在的一条直连链路,且该链路必须为链路聚合且配置为peer-link。peer-link链路是一条二层链路,用于协商报文的交互及部分流量的传输。接口配置为peer-link接口后,该接口上不能再配置其它业务。
-
Keepalive Link:心跳链路,承载心跳数据包,主要作用是进行双主检测。需要注意的是,keepalive链路和peer-link是不同的两条链路,其作用也不一样。正常情况下,keepalive链路不会参与M-LAG的任何转发行为,只在故障场景下,用于检查是否出现双主的情况。keepalive链路可以通过外部网络承载(比如,如果M-LAG上行接入IP网络,那么两台双归设备通过IP网络可以互通,那么互通的链路就可以作为keepalive)。也可以单独配置一条三层可达的链路来作为keepalive链路(比如通过管理口)。
-
M-LAG成员口:双归接入的接口,两个M-LAG成员口的状态需要进行同步。
-
单归设备:如图,单归设备仅连接到M-LAG双归设备中的一台。如果部署M-LAG,单归设备是极为不推荐的。
三:M-LAG控制平面原理
一、M-LAG建立过程
M-LAG建立过程主要有以下几步:
1. M-LAG两端的设备配置完成后,会进行配对。两边设备会在Peer-link上定期发送Hello报文,Hello报文中携带了自己的DFS Group ID、协议版本号、系统MAC等信息。
2. 收到对端的Hello报文后,会判断DFS Group ID是否相同,如果相同,则配对成功。
3. 配对成功后,会选举主/备设备,根据优先级选举,优先级高为主。如果优先级一样则比较系统MAC,小的为主。缺省情况下,优先级为100,可以通过手动配置修改。
4. 配对成功之后,设备间会发送同步报文进行信息同步,需要同步的信息包括设备名、系统MAC、软件版本、M-LAG状态、STP BPDU信息、MAC、ARP、IGMP表项等。
5. 设备配对成功后,会通过keepalive链路发送心跳。心跳主要是用于在peer-link故障时,双主检测使用。
二、M-LAG协议报文
M-LAG协议报文如图所示,上面说过,协议报文(HELLO或者同步报文)都是在peer-link上承载的,而peer-link是一个二层链路,所以协议报文也是封装在普通的以太报文中的,最外层的以太头中,源MAC为自身设备的MAC地址,目的MAC为组播MAC地址,VLAN则是用的保留VLAN。
外层以太头部内,封装了一层自定义的消息头部。自定义消息头部中主要包含以下信息:
-
Version:协议版本号,用于标识双归设备所运行的M-LAG版本。
-
Message Type:报文类型,标识该报文为那种类型的报文,HELLO或者同步报文。
-
Node:设备节点编号。
-
Slot:槽位号,标识需要接收消息的槽位号,如果盒式设备,则为堆叠ID。
-
Serial Number:协议序列号,用于增加可靠性。
自定义消息头部里面,就是正常的报文数据,包含了需要交互或者同步的信息。比如HELLO报文的DATA中会包含Dfs-group ID、优先级、设备MAC地址等信息。而同步报文DATA中会包含一些表项和状态信息。
三、M-LAG同步原理
M-LAG作为一个逻辑的链路聚合组,双归设备两端的表项需要保持一致,所以需要在M-LAG两端同步表项,否则可能导致流量异常。需要保持一致的表项主要有:
-
MAC表
-
ARP表
-
二三层组播转发表
-
DHCP Snooping表
-
LACP System ID
-
STP全局和端口的一些配置
-
其他一些表项如ACL等
表项会封装在同步报文的DATA部分,DATA按照TLV格式封装,方便扩展。以同步ARP表项为例:
TLV的内容包含收到ARP的源M-LAG ID,以及原始的ARP报文。之所以带原始的ARP报文是因为对于原始的ARP报文,不管什么版本的设备处理模式都是相同的。更容易实现版本之间的兼容性。除ARP之外,IGMP等协议相关的表项也都是以原始报文同步,对端收到原始报文后会根据报文信息同步为自身的表项。
四、M-LAG协议兼容性原理
之前说过,M-LAG的一大优势就是支持逐台升级,为维护带来了便利。对于控制平面需要进行同步的这类协议来说,逐台升级过程中,必然会出现两端协议版本不一致的情况,那么必须保证协议的兼容性。
M-LAG保证协议兼容性主要有以下一些方法:
1. M-LAG HELLO报文中会协议协议的版本号,这个版本号并不随设备版本升级而变化,如果设备升级前后涉及M-LAG的功能(如MAC、ARP等)没有变化,版本号不会变化。如果功能有变化,M-LAG版本号才会变化。
2. M-LAG设备在获取到对面的版本号后,如果自身版本较高,则会兼容处理老版本发送过来的报文,并且会以老版本的的方式和对方设备进行交互。
3. 上面我们说过,在进行表项信息同步时,M-LAG设备会将原始报文同步给对方。这样也保证了协议兼容性。以ARP表项为例,ARP协议是一个非常稳定的协议,各个版本对于ARP报文的处理几乎没有差别,所以将原始ARP报文发给对面,几乎不会因为版本原因导致对端设备无法处理。
下面用一个例子来说明一下逐台升级过程中的协议兼容性问题。
如图所示,SwitchA和SwitchB组成一个M-LAG系统。版本均为V1R5C10,现在要将两台设备升级为V2R1C00版本。由于V2R1C00版本新增了一个同步LACP SystemID的功能,在V1R5C10版本,两端设备LACP System ID必须手动配置为一致,而在V2R1C00版本中,主设备会将自己的LACP SystemID封装在同步报文中,备设备收到后,会使用该System ID替换自己的SystemID,防止了手动配置错误的情况发生。那么升级过程如下:
1. SwtichB换包重启,M-LAG由双归变成单归,SwitchA独立承担报文转发。
2. SwitchB升级完成后,以V2R1C00版本启动,发送HELLO报文重新配对。由于新增了一个功能,SwitchB发送的HELLO报文中新增了TLV(这里以新增TLV为例,实际新增功能并不一定会在HELLO报文中新增TLV),SwtichA收到SwitchB的报文后,只处理可以识别的TLV。
3. SwitchB收到SwitchA发送的HELLO报文后,发送HELLO报文中携带的版本号比自己低,于是不会校验是否有该新增的TLV,两者可以正常协商(新增的TLV功能暂时不生效)。
4. 协商完成后,SwitchB开始发送LACP System ID的同步报文,这是一个新增的报文类型。SwtichA是仍然是老版本,不会处理,直接忽略。SwitchB接收不到SwitchA发送的同步LACP SystemID的报文,也不会有任何处理。两设备继续保持手动配置System ID状态,LACP功能也就继续保持以前的工作状态。
5. 开始升级SwtichA,同之前类似,双归切换为单归。
6. SwitchA升级完,最终两边版本一致。此时两台设备可以交互LACP System ID的同步报文,此时可以将之前手工配置的System ID删除,全部切换完自动协商形式。
四:M-LAG数据平面原理
一、正常转发流程
1:CE侧访问网络侧单播流程
CE侧单播访问网络侧时,无论单归或是双归均为正常转发流程,双归设备会正常通过链路聚合将流量哈希到两条链路上。
2:CE侧单播互访流程
CE1访问CE2时,由于SwitchA上会学习到CE2的MAC表项,可以正常转发给CE2。
CE2访问CE1时,CE2首先会进行哈希,如果流量被哈希到SwtichA一侧,由于SwitchA上会学习到CE1的MAC表项,可以正常转发给CE1。如果流量被哈希到SwitchB一侧,由于SwitchA会将表项同步给SwitchB,SwitchB会从peer-link口学习到CE1的MAC表项(也就是SwitchB上CE1的MAC表项出接口为peer-link口),于是SwitchB会将流量通过peer-link口发给SwitchA,同理,SwitchA将流量转发给CE1。
3:组播/广播/未知单播流程
这里以CE2发送广播流量为例,广播流量会在M-LAG两条链路上进行广播,到达SwitchA和SwitchB后,会继续向其他CE和网络侧进行广播。需要注意的是,由于peer-link是加入所有VLAN的的,所以广播流量必然也会在peer-link上广播。这里,SwitchB将广播流量通过peer-link发送给SwitchA后(SwitchA也会广播给SwitchB,原理一致,这里不赘述了),广播流量不会从SwitchA的MLAG成员口再发送给CE2,这样就防止了环路的发生。peer-link自身有一个端口隔离的机制:所有从peer-link口接到的:流量不会从M-LAG双归成员口再发送出去。
4:网络侧流量模型
网络侧协议根据协议不同,原理会略有不同,这里我们简单说一下,后面典型应用场景中会详细说明:
l xSTP:M-LAG双归设备会协商成同一个STP的根桥,也就是说在STP看来,SwitchA和SwitchB是一个STP根桥。
l TRILL/VXLAN:M-LAG会通过同一个标识(虚拟nickname/虚拟VETP)对外协商,网络侧设备会将双归设备作为一台设备进行协商。流量会通过TRILL/VXLAN协议的机制进行,实现负载分担。
l IP网络:正常路由协商,如果链路状态一致,则为ECMP。
网络侧无论将流量发给双归设备中的哪一台设备,流量是单播或者广播,其原理和CE侧的原理是一致的,仍然是单播正常转发,广播做端口隔离。
二、故障场景
1:M-LAG成员口故障
如果M-LAG某成员口故障,网络侧流量会通过peer-link发送给另外一台设备,所有流量均由另外一台设备转发,具体过程如下:
1. SwitchB的M-LAG成员口故障,网络侧不感知,流量依然会发送给双归设备。
2. 由于M-LAG成员口故障,SwtichB将CE对应的MAC表项清除。此时,M-LAG系统会触发一次MAC表项同步的过程,SwitchA将CE的MAC表项同步给SwitchB,出接口为peer-link口。
3. 由于成员口故障,双归变成单归,端口隔离机制会放开。
4. SwitchB收到网络侧访问CE的流量后,查找MAC表项,会通过peer-link将流量交给SwitchA转发给CE。
5. 故障恢复后,M-LAG成员口UP也会触发一次M-LAG系统的MAC表项同步过程,SwtichB上CE的MAC表项恢复正常情况下的出接口。流量正常转发。
2:peer-link故障
如果一旦peer-link故障,则两台设备不能同时转发流量,如果同时转发流量会导致广播风暴,MAC漂移等一系列问题,所以必须只让一台设备转发,具体方法如下:
1. 双归设备一旦感知peer-link口down,即立刻发起一次双主检测过程,通过Keepalive链路进行双主检测。如果在一定时间内未收到对端发来的Keepalive报文,则认为对端设备故障。如果收到对端发来的Keepalive报文,则判定peer-link故障。
2. 判定peer-link故障后,M-LAG备设备会将自己除了peer-link接口、堆叠口、和管理网口之外的所有物理接口Error-dwon。此时,所有流量都只会通过M-LAG主设备进行转发。
3. peer-link故障恢复后,peer-link接口UP,M-LAG系统重新协商。协商完成后,为了保证M-LAG的端口隔离机制生效,网络侧协议收敛完毕,并不立即将备设备上Error-down的端口恢复,而是会有一个延时时间(一般为2分钟,如果是M-LAG双归接入到SVF系统则为5分钟)。
这里大家可以看到,如果peer-link故障,由于备设备接口被Error-down,单归到备设备的CE设备(如图中CE3)将无法访问网络侧,也无法收到网络侧的流量。这就是为什么我们在一开始说,单归的组网是非常不推荐的。
这里还需要说明的是:如果使用框式设备组成M-LAG系统,最好是将peer-link接口和M-LAG成员口部署在不同单板上。因为如果部署在同一块单板上,则如果单板故障,则peer-link和M-LAG成员口同时故障,这时,如果故障的为主设备,则备设备自动Error-down物理端口,此时,发送到双归设备的流量会被丢弃。
3:设备故障场景
设备故障处理流程和peer-link故障基本一致,首先设备感知peer-link接口down,进行双主检测,检测肯定检测不到,于是判定设备故障。既然设备都故障了,自然也转发不了,如果我是M-LAG主设备,那我啥也不用做,继续转发。如果我是M-LAG备设备,那我自然就升主了,然后依然继续转发。等故障恢复了,感知peer-link口up,就再进行M-LAG协商。同理,为了给网络侧协议收敛的时间,以及M-LAG本身的一些机制准备,还是会有一个延时的时间,在延时时间内,依然还是只有一台设备进行转发。
4:上行链路故障
一般情况下,上行链路故障并不会影响M-LAG系统的转发,如图SwitchA上行链路虽然故障,但是网络侧的转发相关表项会通过SwitchB通过peer-link同步给SwitchA,SwitchA可以将访问网络侧的流量发送给SwitchB进行转发。而网络侧发送给CE侧的流量由于接口故障,自然也不会发送给SwitchA处理。
但是如果故障的接口正好是Keepalive链路接口,就有问题了。此时,由于Keepalive链路故障,设备双主检测后均认为对方设备故障。此时出现双主情况,CE发送给SwitchA的流量会因为没有上行出接口而被丢弃。
针对这个问题,我们主要有两种方法解决:
1. 用管理口作为Keepalive链路。
2. 配置Monitor-link功能,将M-LAG成员口和上行口关联起来,一旦上行链路故障了,会联动M-LAG成员口故障,这样就防止了流量丢失。
五:M-LAG典型应用场景
二:服务器通过M-LAG双归接入
Server双归接入M-LAG的场景下,Server只需要支持负载分担模式的双网卡即可。将双网卡绑定为Eth-Trunk,建议通过LACP协议和M-LAG进行对接。
如果服务器的网卡只能支持主备模式,通过M-LAG接入的时候必须要通过LACP进行协商。这样服务器发出的流量只从主链路进行转发,这里假设左侧链路为主链路。那么所有的流量都会通过SwitchA进行转发,而SwitchA会将Server对应的MAC表项通过peer-link同步给SwitchB,出接口为peer-link口。这样,当SwitchB收到发往Server的流量后,会通过peer-link发送给SwitchA,这时Server相当于是单归接入。
网卡主备模式服务器能否通过M-LAG接入还取决于服务器的能力,这里还是推荐网卡负载分担模式进行接入。
二:M-LAG双归接入隧道类协议
前面我们说过,数据平面虚拟化协议大多数是采用了隧道封装,M-LAG双归接入此类网络的原理基本是一致的。目前CE系列交换机支持M-LAG接入TRILL和VXLAN。
这类场景的实现方式都是将双归设备虚拟成一台设备和网络侧交互。对于TRILL网络,两台设备会通过peer-link协商或者手工配置一个虚拟nickname,在向外发送Hello报文时,封装这个虚拟的nickname,这样网络侧设备会认为和同一台设备建立了TRILL邻居,这样所有到Server的路由都会指向这个虚拟nickname。
对于VXLAN网络,设备会虚拟出一个VTEP,无论是手工建立隧道还是通过MPBGP自动建立的方式,SwitchA和SwitchB均用这个虚拟的VTEP的IP和外界建立VXLAN隧道。
这样在接入侧看来,通过一个Eth-Trunk和一台设备建立了连接,在网络侧看来,是和一台设备建立了TRILL邻居/VXLAN隧道。下面以TRILL网络为例,描述一下报文转发过程。
1. SwitchA和SwitchB正常和TRILL网络侧设备建立邻居关系,注意,TRILL建立邻居是通过ISIS的机制,HELLO报文中并不发布nickname信息,所以不会出现nickname冲突的情况。
2. SwitchA和SwitchB通过LSP报文像TRILL网络侧发布携带虚拟nickname的路由信息。注意,这里如果TRILL网络侧里也有一台设备的nickname和虚拟nickname一致,会出现nickname冲突的情况。
3. 用户侧报文到达双归设备后,查询双归设备的MAC表项,发现MAC表项出接口为TRILL的Egress节点,于是对报文进行TRILL封装,封装的ingress nickname为虚拟nickname。
4. TRILL网络侧报文在发往用户侧时,由于双归设备同时发布了虚拟nickname的路由信息,所以在TRILL网络侧设备看来,双归RB是ECMP的等价下一跳,于是封装的Egress nickname为虚拟nickname。
三:M-LAG双归接入IP网络
M-LAG双归接入到IP网络时,双归设备就成了二层网络和三层网络的分界点。也就是承担了网关的作用。由于是两台设备做网关,那么他们对用户侧展示的必须是相同的网关IP和MAC。这里就要借用VRRP的机制,在SwitchA和SwitchB上配置虚拟的IP和MAC。但是要注意的是,这里VRRP并不是主备,如果是主备,那就不能负载分担了。所以我们通过一些机制,屏蔽了VRRP的协议报文,让VRRP组工作在双主的状态下,仅仅借用VRRP的虚拟IP和MAC的机制。
这里L1和L2接口可以配置成VLANIF或者三层路由接口均可以,SwitchA和SwitchB正常和网络侧建立路由邻居关系,发布路由时,由于L1和L2网段相同,SwitchA和SwitchB会发布相同网段的路由,这样在网络侧看来,SwitchA和SwitchB是ECMP的两个等价下一跳。
四:M-LAG和STP网络对接
M-LAG双归接入STP网络的场景不太常见,一般可能某些STP网络不太方便进行调整时,需要和M-LAG进行对接。
M-LAG和STP对接的原理和双归接入隧道类协议类似,也是将双归设备模拟成STP的一个逻辑节点。这样网络侧在进行STP协商时,会将双归设备看做STP的一个节点。有两种方法可以将双归设备模拟成一个STP节点:
1. 手动配置双归设备为STP网络的根桥。
2. 通过配置VSTP协议,VSTP协议的作用是在双归设备之间同步STP的协议状态,让两台设备以同一个状态对外进行STP协商。
五:多级M-LAG互联
在网络规模较大的情况下,可以在核心层,汇聚层和接入层部署多个M-LAG来保证各层网络之间的链路都可以形成负载分担,保证了链路的可靠性。
多级M-LAG其实本质上并没有什么区别,因为所有M-LAG之间都可以看做是通过一个Eth-Trunk连接。比如对于SwitchA和SwitchB来说,往上运行了一个M-LAG连接了一个Eth-Trunk接口,往下也同理。
但是这里要提一下的是,这种情况下,就不能通过手动配置根桥的方式来进行STP破环了,因为有多级M-LAG,如果配置某M-LAG的双归设备为根桥,那其他设备必然就不能运行了。所以多级M-LAG互联方式必须要部署VSTP协议来同步M-LAG双归设备之间STP状态信息。
|