vrrp
在一个网络中,通常会使用vrrp技术来实现网关的高可用。
vrrp,即Virtual Router Redundancy Protocol,虚拟路由冗余协议。
应用场景
典型的如下面这个例子:
当Router故障后,将会导致HostA-C都无法连接外部的Internet。
而引入VRRP技术后则可以解决Router单点故障问题,引入VRRP技术后的拓扑如下:
当某一路由器再次出现故障时,其对应的Backup路由器将承担起原网关的功能。
主机和网关进行通信时使用虚拟路由器的vip(虚拟ip)和vmac(虚拟mac)进行通信。
在VRRP中需要关注的点有:
- VRRP使用虚拟ip和虚拟mac实现
- VRRP报文只有一种报文且使用组播发送,为advertisement报文
- VRRP节点间使用定时机制选举出Master节点
- VRRP中有两个定时器,分别为:
- ADVER_INTERVAL定时器,由Master节点定时发送,默认周期为1秒
- MASTER_DOWN定时器,运行在Backup节点负责监听Master节点是否超时,其周期为计算公式为:
- MASTER_DOWN = (3*ADVER_INTERVAL)+Skew_time(偏移时间),
- Skew_time=(256-Priority)/256
- 节点成为Master节点后会主动发送免费ARP广播通告到它所连的设备和主机,以更新设备和主机的ARP表
bfd
通过上面的介绍我们了解到:在vrrp中故障监测周期为秒级,如要达到更快速的监测周期可以使用bfd机制一起实现。
BFD(Bidirectional Forwarding Detection,双向转发检测),可实现毫秒级监测,数据包使用UDP实现。
BFD包协议如下:
BFD的会话建立机制分为静态建立与动态建立。
bfd检测模式
BFD检测模式分为两种:
- 异步模式
- 查询模式
一般使用异步模式,如需要监测的设备较多担心且不怎么要求时效性,就也可以考虑使用查询模式。
bfd单臂回声
bfd单臂回声也就是bfd中的echo功能。主要应用场景为:两个直连的设备中,仅一台支持bfd功能。
这种情况下要实现两台设备间的故障监测,由支持BFD的设备发起回声请求,不支持BFD的设备收到该报文后直接进行回包。
bfd的应用场景有很多,在ospf节点、静态路由、VRRP等场景中得到了广泛的应用。
BFD包占用字节量较小,一般为几十个字节,通信时使用udp包进行传输。RFC规定,单跳检测时,目的端口为3784。多跳检测时,目的端口为4784。
keepalived
通过前文的了解,我们知道了vrrp可以实现节点的冗余备份,再配合bfd可实现毫秒级的故障检测。
总结来说vrrp+bfd是一个实用性很强的技术方案,其使用虚拟ip和虚拟mac这种思想来实现高可用(HA)是十分有用的。
凭借vrrp+bfd强大的特点,许多大牛也将其运用到软件上,其中最具代表的非keepalived莫属。
如keepalived官网所述那样,keepalived是一款实现了vrrp和bfd的路由软件,在负载均衡(loadbalancing )和高可用(high-availability)场景得到了广泛的应用,而且还开源,github上的星星和活跃度也挺不错的。
应用场景
keepalived实现HA的核心之一仍是VRRP,实现了虚拟ip在主备节点中的漂移。以keepalived实现软件高可用的场景非常多,比较经典的有keepalived+nginx、keepalived+mysql、keepalived+redis。
keepalived+mysql
在mysql的高可用场景中,mysql客户端直接使用keepalived的VIP地址连接mysqlServer。mysql节点间使用mysql自带的副本机制实现数据的同步,当某个节点出现故障后,mysql客户端便可实现mysql的连接自动转移。
这里需要注意的是:在mysql的连接中,client与server使用的是tcp长连接,一个连接由4元组(4-tuple)构成,即源IP地址、目的IP地址、源端口、目的端口。client端与server端断连后tcp连接也需要进行重连,使用keepalived实现mysql长连上则需要确保配置了mysql的自动重连,即url参数中的:
autoReconnect=true
或者使用mysql的数据库连接池间接与数据库进行连接。
keepalived+nginx
keepalived的另一个应用非常多的场景非keepalived+nginx莫属。
如上图所示,在两个nginx间配置keepalived,用户流量最终通过vip访问到nginx(一般会配置一个LVS,流量让LVS转发到vip),vip在两个nginx间漂移且始终位于nginx的master节点。详细配置方式这里不做展开,此方案也非常成熟网上的资料也很多。
openflow交换机
通过上文我们了解到了在路由设备和软件设备间可以使用vrrp、bfd、keepalived实现HA。接下来再来了解下openflow交换机和控制器实现HA的一些知识。
openflow交换机——即实现了openflow协议的交换机,如实现了openflow协议的ovs交换机。
openflow1.5.1协议文档:http://sdn.ifmo.ru/Members/shkrebets/sdn_4115/sdn-library/openflow-switch-v1.5.1.pdf/view
会话建立过程
直接看一下openflow交换机与控制器建立连接的过程。
我们知道,openflow交换机与控制器的通信好比是一个client/server通信,这个过程免不了会话(session)的建立。
这个过程在openflow协议中可找到对应的描述,描述片段如下:
When an OpenFlow connection is first established, each side of the connection must immediately send
an OFPT_HELLO message with the version field set to the highest OpenFlow switch protocol version
supported by the sender
After the switch and the controller have exchanged OFPT_HELLO messages and successfully negotiated
a common version number, the connection setup is done and standard OpenFlow messages can be
exchanged over the connection. One of the first things that the controller should do is to send a
OFPT_FEATURES_REQUEST message to get the Datapath ID of the switch
上述内容转换为下图:
主要为在tcp(6653或6633端口)建连后相互发送OFPT_HELLO包,之后再由控制器向交换机发送OFPT_FEATURES_REQUEST包以获得交换机ID等信息。
Multiple Controllers
在协议文档中的OpenFlow Channel and Control Channel部分可以找到如下描述:
The OpenFlow channel is the interface that connects each OpenFlow Logical Switch to an OpenFlow
controller. Through this interface, the controller configures and manages the switch, receives events
from the switch, and sends packets out the switch. The Control Channel of the switch may support
a single OpenFlow channel with a single controller, or multiple OpenFlow channels enabling multiple
controllers to share management of the switch.
openflow channel是openflow交换机与控制器的通信接口,交换机的控制通道(control channel)支持只和一个交换机的一个通道连接,也支持多个通道实现交换机的多控制器多交换机连接。
协议文档中描述的Multiple Controllers即为openflow交换机连接多个控制器的场景。使用这种方式可以实现交换机和控制器间的高可用,如某台控制器down掉后其他存活的控制器仍然可以操作openflow交换机。
为了避免脑裂问题,一台交换机与控制器的关系有一个角色的概念,即ROLE。
根据openflow协议的描述,交换机与控制器的角色有以下几种类型:
- Equal,对等关系,意味着控制器可以完全访问交换机,并和其他拥有Equal角色的控制器为平等关系;可接收来自交换机的所有异步消息,如pktIn、flow-removed消息;
- Master,主节点关系,在访问控制权限部分和Equal一样都具有完全访问权限,不同在于:一个交换机仅有一个Master角色。
- Slave,副节点关系,仅具有对交换机的可读权限,不能向交换机下发消息,如flowMod、packetOut。此种模式下的控制器仅接收交换机的Port-status消息,其他诸如pkt-in、flow-removed之类的异步消息都不会被接收到。
此部分更为详尽的说明也可查看openflow协议的官方文档。部分内容截图片段如下:
Auxiliary Connections
在openflow协议的1.3版本以后新增了Auxiliary Connections的功能。
协议描述信息如下:
In previous versions of the specification, the channel between the switch and the controller is exclusively
made of a single TCP connection, which did not allow the exploitation of the parallelism available in most
switch implementations. OpenFlow 1.3 enables a switch to create auxiliary connections to supplement
the main connection between the switch and the controller (EXT-114). Auxiliary connections are mostly
useful to carry packet-in and packet-out messages.
- Enable switch to create auxiliary connections to the controller.
- Enable switch to create auxiliary connections to the controller.
- Mandate that auxiliary connection can not exist when main connection is not alive.
- Add auxiliary-id to the protocol to disambiguate the type of connection.
- Enable auxiliary connection over UDP and DTLS.
openflow交换机除了和控制器保持单连接外,还可与多个控制器连接实现辅助控制。使用多控制器控制同一个交换机在一定条件下可以提高处理性能,也让多控制器的并性执行得到最大限度的发挥。
关于openflow交换机连接辅助控制器的示例可参考此链接:
https://github.com/mininet/mininet/blob/master/examples/controllers.py
参考:
http://sdn.ifmo.ru/Members/shkrebets/sdn_4115/sdn-library/openflow-switch-v1.5.1.pdf/view
https://github.com/opennetworkinglab/onos/blob/master/tools/dev/mininet/examples/multicluster.py
https://mp.weixin.qq.com/s/c6deR_QKIZmZbXj17q2sMA