问题导读:
1.虚拟路由冗余协议是什么?
2.什么是Keepalived?
3.如何创建 HA Router?
1. 基础知识
1.1 虚拟路由冗余协议 - VRRP
1.1.1 概念
路由器是整个网络的核心。一个网络内的所有主机往往都设置一条缺省路由,这样,主机发出的目的地址不在本网段的报文将被通过缺省路由发往路由器,从而实现了主机与外部网络的通信。在通常只使用单路由器来承担缺省路由的情况下,当该路由器坏掉后,本网段内所有以它为缺省路由下一跳的主机将断掉与外部的通信。可见,在使用单路由器的情况下,如果路由器发生致命性的故障,将导致本地网络的瘫痪,如果是骨干路由器,影响的范围将更大,所造成的损失也是难以估计的。因此,对路由器采用热备份是提高网络可靠性的必然选择。
VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)是一种可以解决这种问题的容错协议,其协议文本在这里。 它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。一组实现了该协议的路由器向局域网内的主句提供具有高可用性(HA)的虚拟路由器。
1.1.2 VRRP 怎么解决问题 VRRP 将一组物理路由器组织成一个虚拟路由器,称之为一个备份组。 这个虚拟的路由器拥有自己的 IP 地址,局域网内的机器使用该 IP 地址作为其缺省路由器的地址。
<ignore_js_op>
以上图为例,
- Device A 和 B 组成一个 VRRP 组,它的虚拟 IP(VIP) 为 10.1.1.10/24。其中,通过选举机制,A 是 Master Router,B 是 Backup Router。一个 VRRP 组内可以由多个设备,但是只有一个是 Master 设备。
- Device A 和 B 可以由自己的 IP 地址,VIP 可以和其中的某 IP 相同,也可以不同。
- 当前,Router A 作为 Master router 向局域网内的机器提供路由服务。
- 当前,Router B 作为 Backup router。它的任务是周期性地接受 A 发出的心跳。在规定的时间段内,如果都没有收到 A 发出的心跳,则启动一个选举过程,重新选出 Master。
- 局域网内的机器将虚拟路由器当作默认网关,它们仅仅知道这个虚拟路由器的IP 地址 10.1.1.10,而并不知道具体的 Master 路由器的 IP 地址以及 Backup 路由器的IP 地址。它们将自己的缺省路由下一跳地址设置为10.1.1.10。于是,网络内的主机就通过这个虚拟的路由器来与其它网络进行通信。如果 Master 路由器坏掉,Backup 路由器将会通过选举策略选出一个新的 Master 路由器,继续向网络内的主机提供路由服务。从而实现网络内的主机不间断地与外部网络进行通信。
可以看出:
- VRRP 是一种路由器选择协议,它可以把一个虚拟路由器的责任动态分配到 VRRP 组内的多个路由器中的一台。控制虚拟路由器 IP 地址的 VRRP 路由器称为主路由器,它负责转发数据包到这些虚拟 IP 地址。一旦主路由器不可用,这种选择过程就提供了动态的故障转移机制,这就虚拟允许路由器的 IP 地址可以作为终端主机的默认第一跳路由器。使用 VRRP 的好处是有更高的默认路径的可用性而无需在每个终端主机上配置动态路由或路由发现协议。
- VRRP 包封装在 IP 包中发送,用于 VRRP 组内设备的互相通信比如保持心跳等。它只定义了一种报文即 VRRP 报文,这是一种组播报文,由 Master 路由器定时发出来通告组内的路由器它的存在。
- VRRP 中定义了三种状态模型,初始状态 Initialize,活动状态 Master 和备份状态 Backup,其中只有活动状态的交换机可以为到虚拟IP地址的的转发请求提供服务。
几个概念:
- VIP:VRRP 使用两种类型的 VIP:一种 VIP 参与 VRRP 通告,使用配置项 virtual_ipaddress 指定;另一种 VIP 不参与 VRRP 通告,使用配置项 virtual_ipaddress_excluded 指定。
- 优先级(Priority):虚拟路由器中VRRP设备的优先级。虚拟路由器根据优先级选举出Master设备和Backup设备。
- 抢占模式:在抢占模式下,如果 Backup 设备的优先级比当前 Master 设备的优先级高,则主动将自己切换成 Master。
- 非抢占模式:在非抢占模式下,只要 Master 设备没有出现故障,Backup 设备即使随后被配置了更高的优先级也不会成为Master设备。
-
VRRP协议报文:封装在IP报文中,发送到分配给 VRRP 的 IP 组播地址。在IP报文头中,源地址为发送报文接口的主 IP 地址(不是虚拟IP地址),目的地址是224.0.0.18,TTL是255,协议号是112。目前,VRRP协议包括两个版本:VRRPv2和VRRPv3,VRRPv2仅适用于IPv4网路,VRRPv3适用于IPv4和IPv6两种网络。
- VRRP 节点三种状态:初始状态(Initialize)、活动状态(Master)、备份状态(Backup)。其中,只有处于Master状态的设备才可以转发那些发送到虚拟IP地址的报文。
Master 路由器的选举过程:
VRRP根据优先级来确定虚拟路由器中每台路由器的角色(Master 路由器或 Backup 路由器)。优先级越高,则越有可能成为 Master 路由器。
初始创建的 VRRP 交换机工作在 Initialize 状态,收到接口 Up 的消息后,若此路由器的优先级小于255,则会先切换至 Backup 状态,待 Master_Down_Interval 定时器超时后再切换至 Master 状态。首先切换至 Master 状态的 VRRP 路由器通过 VRRP 通告报文的交互获知虚拟交换机中其他成员的优先级,进行Master的选举:
- 如果 VRRP 报文中 Master 路由器的优先级高于或等于自己的优先级,则 Backup 路由器保持 Backup 状态;
- 如果 VRRP 报文中 Master 路由器的优先级低于自己的优先级,采用抢占方式的 Backup 交换机将切换至 Master 状态,采用非抢占方式的Backup 路由器仍保持Backup状态。
- 如果多个 VRRP 路由器同时切换到 Master 状态,通过 VRRP 通告报文的交互进行协商后,优先级较低的 VRRP 路由器将切换成 Backup 状态,优先级最高的 VRRP 路由器成为最终的 Master设备;优先级相同时,VRRP 路由器上 VRRP 备份组所在接口主 IP 地址较大的成为 Master 设备。
- 如果创建的VRRP 路由器为IP地址拥有者,收到接口 Up 的消息后,将会直接切换至Master状态。
Master交换机状态的通告:
- Master 路由器周期性地发送 VRRP 通告报文,在 VRRP 备份组中公布其配置信息(优先级等)和工作状况。Backup 路由器通过接收到 VRRP 报文的情况来判断Master 路由器是否工作正常。
- 当 Master 路由器主动放弃 Master 地位(如 Master 路由器退出备份组)时,会发送优先级为0的通告报文,用来使 Backup 路由器快速切换成 Master 路由器,而不用等到 Master_Down_Interval 定时器超时。
- 当 Master 路由器发生网络故障而不能发送通告报文的时候,Backup 路由器并不能立即知道其工作状况。等到 Master_Down_Interval 定时器超时后,才会认为 Master 路由器无法正常工作,从而将状态切换为 Master。
目前,主流的硬件路由器设备都实现了该协议: 这篇文章 介绍了 Broadcom 路由器上 VRRP 的配置,这篇文章 介绍了一个 Cisco 路由器 VRRP 的配置例子,这篇文章 是华为的 VRRP 白皮书。
它的优势:
- 操作简单:它不需要改变组网情况,也不需要在主机上做任何配置,只需要在相关路由器上配置极少的几条命令,就能实现下一跳网关的备份,并且不会给主机带来任何负担。和其他方法比较起来,VRRP更加能够满足用户的需求。
- 简化网络管理:在具有多播或广播能力的局域网(如以太网)中,借助 VRRP 能在某台设备出现故障时仍然提供高可靠的缺省链路,有效避免单一链路发生故障后网络中断的问题,而无需修改动态路由协议、路由发现协议等配置信息,也无需修改主机的默认网关配置。
- 适应性强:VRRP报文封装在IP报文中,支持各种上层协议。
- 网络开销小:VRRP只定义了一种报文——VRRP通告报文,并且只有处于Master状态的路由器可以发送VRRP报文。
1.2 Keepalived
1.2.2 概念
Keepalived是一个用 C 语言编写的路由软件,其主要目的是向 Linux 系统和基础设施提供简单可靠的工具来实现负载均衡(Load balancing)和高可用(HA)。其中,
- 负载均衡框架基于 Linux Virtual Server (IPVS) 内核模块来提供网络四层的负载均衡,它实现了一组检查器(Checkers)来根据它们的健康状态动态地和自适应地维护和管理被均衡的服务器池。
- 高可用(HA)是使用 VRRP 来实现的,Keepalived 是 VRRP 的一个非常好的开源实现。它是一个基于 VRRP 协议来实现的 WEB 服务高可用方案,可以利用其来避免单点故障。一个 WEB 服务至少会由两台台物理服务器运行 Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟 IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候,备份服务器就会接管虚拟 IP,继续提供服务,从而保证了高可用性。
1.2.2 软件架构和功能
(本部分内容来自 Keepalived 官网)
<ignore_js_op>
Keepalived 使用三个进程,其中 Watchdog 是控制进程,VRRP Stack and Checkers 是它的两个子进程。
- Watchdog 通过心跳机制来确保子进程处于运行状态。
- Checkers:负责真实服务器的健康检测,用于负载均衡。
- VRRP Stack:实现 VRRP 协议,提供 HA。
主要模块:
- System call : 用于启动用户添加的脚本。它可以被 Checkers 和 VRRP Stack 使用。它向 VRRP 框架提供了一种能力,即在 VRRP 协议状态变化时可以运行用户指定的脚本。
- SMTP : 使得 Keepalive 能够使用邮件来通知管理员。
- NETLINK Interface: 用于 VRRP。Keepalive 通过它来设置或者删除 VIP。
VRRP Stack 模块:
<ignore_js_op>
VRRP Stack 是独立于 LVS的,它可以被单独使用。它主要提供以下功能:
- Failover:实现 VRRP协议的核心功能,提供故障切换能力。
- VRRP Instance synchronization:VRRP Group (组)之间的同步,比如保证两个 VRRP 组直接保持同样状态。
- VRRP 广播:Master 实例通知 Backup 实例。
- System call: 在 VRRP 状态变换时调用外部的脚本或者程序。
它包括以下组件:
- Netlink:提供 VIP 操作。
- Multicast:用于发送 VRRP 协议广播。
- SYSLOG:所有 daemon 的通知消息都会通过该组件写入日志。
用户可以使用配置文件 /etc/keepalived/keepalived.conf 来配置 Keepalived。本部分主要讲讲 keepalived 的概念,使用会在下文谈到。更多内容,参见官网。
2. Neutron Juno 版本中 VRRP 的实现
在 OpenStack HA (1)概述 一文中谈到,Neutron L3 Agent 在 Juno 版本中添加了两种 HA 机制的实现:VRRP 机制(blueprint, Spec,Wiki)和 DVR 机制。VRRP 机制就是借助实现 VRRP 协议的软件,来保证 Neutron L3 Agent 的高可用性。这需要多方面的实现:
- 创建 HA Router 时,创建多个 router 实例部署到不同物理服务器上的 L3 Agent 中。这个实现需要修改 Neutron schedulers。
- 借助实现 VRRP 的软件,保证多个 L3 Agent 的 HA,即其中一个是 Master,其他是 Backup。由 Master 向虚机提供路由服务。在 Master 故障时,某个 Standby 被选举为新的 Master,接替之前的 Master。目前的 Neutron VRRP 实现使用的是 Keepalived。
- 路由器故障切换时保持已建立的连接。Neutron 会使用 conntrack 来实现该功能。
2.1 创建 HA Router
neutron server 上:
(1)类似普通的 router,首先执行 DB 操作在 DB 中创建一个 router。
(2)检查 router 所在的 tenant 中是否存在 HA Network,如果不存在的话,则创建名称为 “HA network tenant”+ tenant_id 的 network,以及该 network 中的名字为 “HA subnet tenant” + tenant_id, cidr 为 cfg.CONF.l3_ha_net_cidr 的 subnet。其余的参数皆为默认或者null。
[AppleScript]
纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
s
1
@controller
:
~$ neutron net
-
show
bc
5501
ed
-56
ee
-4
d
32
-974
b
-02279
fb
35
c
32
+
---------------------------+----------------------------------------------------+
| Field | Value |
+
---------------------------+----------------------------------------------------+
| admin_state_up | True |
|
id
| bc
5501
ed
-56
ee
-4
d
32
-974
b
-02279
fb
35
c
32
|
|
name
| HA network tenant
74
c
8
ada
23
a
3449
f
888
d
9
e
19
b
76
d
13
aab |
| provider
:
network_type | gre |
| provider
:
physical_network | |
| provider
:
segmentation_id |
1
|
| router
:
external | False |
| shared | False |
| status | ACTIVE |
| subnets |
2
ce
1
ff
9
d
-6889
-41
cb
-8
d
6
b
-18
e
7
ccd
67
a
7
b |
| tenant_id | |
+
---------------------------+----------------------------------------------------+
s
1
@controller
:
~$ neutron subnet
-
show
2
ce
1
ff
9
d
-6889
-41
cb
-8
d
6
b
-18
e
7
ccd
67
a
7
b
+
-------------------+------------------------------------------------------+
| Field | Value |
+
-------------------+------------------------------------------------------+
| allocation_pools |
{
"start"
:
"169.254.192.1"
,
"end"
:
"169.254.255.254"
}
|
| cidr |
169.2
54.1
92.0
/
18
|
| dns_nameservers | |
| enable_dhcp | False |
| gateway_ip | |
| host_routes | |
|
id
|
2
ce
1
ff
9
d
-6889
-41
cb
-8
d
6
b
-18
e
7
ccd
67
a
7
b |
| ip_version |
4
|
| ipv
6
_address_mode | |
| ipv
6
_ra_mode | |
|
name
| HA subnet tenant
74
c
8
ada
23
a
3449
f
888
d
9
e
19
b
76
d
13
aab |
| network_id | bc
5501
ed
-56
ee
-4
d
32
-974
b
-02279
fb
35
c
32
|
| tenant_id | |
+
-------------------+------------------------------------------------------+
|
注意,当 tenant 最后一个 HA Router 被删除的时候,该 HA network/subnet 不会被自动删除,这里有个 bug。看起来还没有被 fixed,目前只能手动删除。
(3)分配一个可用的 VRRP ID,该 ID 为 1 - 255 之间。
(4)创建与部署的 router 实例相同数量的 port 作为 HA Interfaces,每个 L3 Agent 上使用一个。
[AppleScript]
纯文本查看 复制代码
1
2
3
4
5
6
7
8
|
{
'tenant_id'
:
''
,
'network_id'
:
network_id
,
'fixed_ips'
:
attributes.ATTR_NOT_SPECIFIED
,
'mac_address'
:
attributes.ATTR_NOT_SPECIFIED
,
'admin_state_up'
:
True
,
'device_id'
:
router_id
,
'device_owner'
:
constants.DEVICE_OWNER_ROUTER_HA_INTF
,
'
name
'
:
constants.HA_PORT_NAME % tenant_id
}
}
)
|
比如需要部署的 router 的实例数目为2 的情况下,会分配 2 个port,分别用于各 router network namespace 中 keepalived 之间的通信:
[AppleScript]
纯文本查看 复制代码
1
2
3
|
s
1
@controller
:
~$ neutron port
-
list
| grep
169.2
54.1
92
|
20894
a
79
-
b
668
-44
d
9
-
bf
42
-
ef
6
bc
2981960
| HA port tenant
74
c
8
ada
23
a
3449
f
888
d
9
e
19
b
76
d
13
aab | fa
:
16
:
3
e
:
09
:
29
:
d
4
|
{
"subnet_id"
:
"2ce1ff9d-6889-41cb-8d6b-18e7ccd67a7b"
,
"ip_address"
:
"169.254.192.2"
}
|
| a
8
a
3
a
49
f
-
c
175
-4
ea
6
-9342
-240
ef
646
e
99
c | HA port tenant
74
c
8
ada
23
a
3449
f
888
d
9
e
19
b
76
d
13
aab | fa
:
16
:
3
e
:
84
:
24
:
7
f |
{
"subnet_id"
:
"2ce1ff9d-6889-41cb-8d6b-18e7ccd67a7b"
,
"ip_address"
:
"169.254.192.1"
}
|
|
(5)schedule router。具体参见 2.1.2 章节.
(6)向待部署 router 实例的每个 L3 Agent 发送 RPC Cast “routers_updated” 消息
<ignore_js_op>
每个 L3 Agent 上:
(1)循环运行的 routers_updated 方法将待处理的每个 router 加入到内部 queue 中,等待被 L3 Agent 启动的循环线程处理
(2)处理过程可以参考我这篇文章 的 3.1 部分
(3)在完成常规的 router 添加操作后,调用 process_ha_router_added 执行 HA 配置部分
(3.1)将 HA Port plug 到 OVS 的 br-int 上,并设置 interface 的三层属性,比如 IP, gateway, route 等。
[AppleScript]
纯文本查看 复制代码
1
2
3
4
5
|
Bridge br
-
int
Port
"ha-20894a79-b6"
tag
:
7
Interface
"ha-20894a79-b6"
type
:
internal
|
(3.2)准备 keepalived
(3.2.1)生成一个 keepalived 实例。该实例的初始状态为 Backup,非抢占式,VRRP 通告间隔2秒,优先级为 50。
[AppleScript]
纯文本查看 复制代码
1
|
instance
=
keepalived.KeepalivedInstance
(
'BACKUP'
,
interface_name
,
ri.ha_vr_id
,
ha_port_cidr
,
nopreempt
=
True
,
advert_int
=
self.conf.ha_vrrp_advert_int
,
priority
=
ri.ha_priority
)
|
(3.2.2)通过上面第三步分配的 VRRP ID,定位到 VRRP Group;然后将 3.2.1 中的 keepalived instance 加入到 该 group 。
(3.2.3)将 group 和 instance 保存到 keepalived config 中。
(4)调用 _add_keepalived_notifiers 方法来添加 neutron 需要的 keepalived notifiers。具体见 2.1.3 章节。
(5)调用 process_router 方法继续处理该 route。对于HA Router,会首次启动新的或者重启已有的 keepalived 进程。
(5.1)生成 keepalived 配置。配置文件的位置可以由配置项 vrrp_confs 指定,其默认值为 “$state_path/vrrp”。还可以使用配置项 ha_vrrp_auth_type (默认 'PASS') 和 ha_vrrp_auth_password (默认 none)指定 VRRP 组播的认证方法,以及 使用配置项 ha_vrrp_advert_int (默认值 2) 指定 VRRP 广播发送的时间间隔。
[AppleScript]
纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
vrrp_sync_group VG_
1
{
# VRRP ID 为 1
group
{
VR_
1
}
notify_master
"/var/lib/neutron/ha_confs/04f6e792-3b79-4b8f-a577-2ad38d33a2bb/notify_master.sh"
notify_backup
"/var/lib/neutron/ha_confs/04f6e792-3b79-4b8f-a577-2ad38d33a2bb/notify_backup.sh"
notify_fault
"/var/lib/neutron/ha_confs/04f6e792-3b79-4b8f-a577-2ad38d33a2bb/notify_fault.sh"
}
vrrp_instance VR_
1
{
state
BACKUP
interface ha
-20894
a
79
-
b
6
# 实例绑定的网卡,因为在配置虚拟 IP 的时候必须是在已有的网卡上添加的
virtual_router_id
1
# VRRP ID,每个 tenant HA Router 一个 ID
priority
50
# 该 HA Router instance 的 优先级,根据这个选举 Master
nopreempt
# 使用非抢占模式
advert_int
2
# VRRP 广播发送间隔,单位秒
track_interface
{
# 跟踪接口,设置额外的监控
ha
-20894
a
79
-
b
6
}
virtual_ipaddress
{
# 该 VRRP 的 VIP,格式为 HA Network CIDR 最后一位被 VID 替换,该例子中,CIDR 为 “169.254.0.1/24”, VID 为 1
169.2
54.0
.
1
/
24
dev ha
-20894
a
79
-
b
6
}
|
keepalived 各种配置说明:
配置 | 说明 | neutron 用法 |
notify master/backup/fault | 表示当该 VRRP 节点切换到 master/backup/fault 状态时,要执行的脚本 | 见本文 2.1.3 章节 |
state | state 指定 instance(Initial) 的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定,里如果这里设置为master,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为master | neutron 将所有 keeplived 实例的初始状态都设置为 BACKUP,而且都使用默认优先级 50。这样实际上,一般来说,哪个 L3 Agent 先起来,它的 keepalived 实例就是 Master 了。 |
interface | VRRP 实例绑定的网卡,在此网卡上添加 VIP 作为 secondary IP | HA Interface |
dont track primary | 忽略 VRRP 的 interface 错误 | 不使用 |
track interface | 跟踪接口,设置额外的监控,里面任意一块网卡出现问题,都会进入故障(FAULT)状态,例如,用nginx做均衡器的时候,内网必须正常工作,如果内网出问题了,这个均衡器也就无法运作了,所以必须对内外网同时做健康检查 | neutron 只跟踪 HA Interface,其实它还是可以跟踪 network namespace 的其他 interface,比如 qr,qg 等,是吧? |
mcast src ip | 发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址 | 不设置,默认使用 HA Interface IP |
garp master delay | 在切换到master状态后,延迟进行免费的ARP(gratuitous ARP)请求 | 未指定 |
virtual router id | 这里设置VRID,这里非常重要,相同的 VRID 为一个组,他将决定多播的MAC地址 | 创建 HA Router时从 neutron DB 分配,从 1 开始 |
priority 100 | 设置本节点的优先级,优先级高的为master | 默认为 50 |
advert int | 检查间隔,默认为1秒 | 配置项 ha_vrrp_advert_int (默认值 2) |
virtual ipaddress | 这里设置的就是VIP,也就是虚拟 IP 地址,他随着 state 的变化而增加或者删除,当 state 为master的时候就添加,当 state 为 backup 的时候删除,这里主要是有优先级来决定的,和 state 设置的值没有多大关系,这里可以设置多个 IP 地址。这篇文章 谈到其数目限制为 20,超过该数目的 IP 可以放到 virtual_ipaddress_excluded。 | VIP。格式为 HA Network CIDR 最后一位被 VID 替换, 该例子中,CIDR 为 “169.254.0.1/24”, VID 为 1。 因此,每个 HA Router 的 VIP 是固定的。 |
virtual routes | 原理和 virtual ipaddress 一样,只不过这里是增加和删除路由 | 不使用 |
authentication
auth type
auth pass
|
认证方式,类型,密码 | 配置项 ha_vrrp_auth_type (默认 'PASS') 和 ha_vrrp_auth_password (默认 none) |
nopreempt | 设置不抢占,这里只能设置在state为backup的节点上,而且这个节点的优先级必须别另外的高 | 设置,使用非抢占模式。这样,只要 Master 没坏,即使 Backup 的优先级更高,也不会触发选举 |
preempt delay | 抢占延迟 | 不使用 |
virtual_ipaddress_excluded | 需要 keepalived 维护但是不会放在VRRP包中传输的IP。也就是说当某个router被选举为master的时候其会的将qg口设置对应的IP。而在变为 backup 时,会将相应的 IP 删除。 | VIP。Neutron 将 浮动 IP,internal/external port IP 等保存在这里。这样,当一个 node 变为 master 的时候,这些 IP 地址会生效;当一个 node 变为 backup 的时候,这些 IP 地址会被删除。 |
virtual_routes | 在某个router设置为 master 的时候其会的设置对应的 route。相反的,如果一个router变成了backup,那么上面这些操作会反过来做一遍。 | 每个 external port 对应一条路由,在 VRRP 状态变化时增加或者删除 |
(5.2)在 route network namespace 运行命令 'keepalived -P -f config_path -p pid_file -r pid_file-vrrp' 启动 keepalived 进程。
[AppleScript]
纯文本查看 复制代码
1
2
|
root
31510
1
0
10
:
42
?
00
:
00
:
00
keepalived
-
P
-
f
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb
/
keepalived.conf
-
p
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb.pid
-
r
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb.pid
-
vrrp
root
31512
31510
0
10
:
42
?
00
:
00
:
00
keepalived
-
P
-
f
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb
/
keepalived.conf
-
p
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb.pid
-
r
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb.pid
-
vrrp
|
根据上面基础知识部分的介绍,第一个进程(进程号 31510)是 Watchdog 进程,第二个进程(进程号 31512)是 VRRP Stack 进程。
(6) Neutron 中,keepalived 进程启动后,初始状态都是 BACKUP。在它指定时间没收到 Master 的广播后,它自己切换至 Master 状态,然后通过 VRRP 通告报文的交互获知虚拟路由器组中其他成员的优先级,进行 Master 的选举:
- 如果 VRRP 报文中 Master 路由器的优先级高于或等于自己的优先级,则 Backup 交换机保持 Backup 状态。显然,Neutron 中的 keepalived 都是同样的优先级,它们会各自保持自己的 BACKUP 状态。
- 如果 VRRP 报文中 Master 路由器的优先级低于自己的优先级,因为 neutron 中 keepalived 采用非抢占模式,Backup交换机仍保持 Backup 状态。
可见,neutron 中,哪个 L3 Agent namespace 中的 keepalived 进程先启动并先发出 VRRP 通告,则它会成为 Master,直到它 down 掉才会由别的节点接替。在状态变化时,会调用指定的脚本。详细见 2.1.3 部分。状态变化完成后,会达到下面这种效果(Juno 中还没有实现 conntrack):
<ignore_js_op>
(7)启动后状态转换过程
[AppleScript]
纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
Aug
1
18
:
42
:
32
network Keepalived[
31509
]
:
Starting Keepalived v
1.2
.
7
(
08
/
14
,
2013
)
#进程启动
Aug
1
18
:
42
:
32
network Keepalived[
31510
]
:
Starting VRRP child process
,
pid
=
31512
# VRRP Stack 进程启动
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Interface queue
is
empty
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Registering Kernel netlink reflector
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Registering Kernel netlink command channel
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Registering gratuitous ARP shared channel
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Initializing ipvs
2.6
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Opening
file
'
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb
/
keepalived.conf'.
#导入配置文件
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Configuration
is
using
:
64796
Bytes
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Using LinkWatch kernel netlink reflector...
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
VRRP_Instance
(
VR_
1
)
Entering BACKUP STATE
#根据初始配置,首先进入 BACKUP 状态
Aug
1
18
:
42
:
32
network Keepalived_vrrp[
31512
]
:
Opening
script
file
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb
/
notify_backup.sh
#脚本调用
Aug
1
18
:
42
:
39
network Keepalived_vrrp[
31512
]
:
VRRP_Instance
(
VR_
1
)
Transition
to
MASTER STATE
#第一次选举后进入 Master 状态
Aug
1
18
:
42
:
39
network Keepalived_vrrp[
31512
]
:
VRRP_Group
(
VG_
1
)
Syncing instances
to
MASTER
state
Aug
1
18
:
42
:
39
network Keepalived_vrrp[
31512
]
:
Opening
script
file
/
var
/
lib
/
neutron
/
ha_confs
/
04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb
/
notify_master.sh
#脚本调用
Aug
1
18
:
42
:
41
network Keepalived_vrrp[
31512
]
:
VRRP_Instance
(
VR_
1
)
Entering MASTER STATE
|
(8)VRRP 心跳
下面的 log 能看出来,Master 每隔两秒钟,向 组播地址 224.0.0.18/01:00:5e:00:00:12 发出长度为 54 bytes 的一个心跳:
[AppleScript]
纯文本查看 复制代码
1
2
3
4
5
6
|
ip netns exec qrouter
-04
f
6
e
792
-3
b
79
-4
b
8
f
-
a
577
-2
ad
38
d
33
a
2
bb tcpdump
-
envi ha
-20894
a
79
-
b
6
-
vvv
11
:
18
:
10.9
69378
fa
:
16
:
3
e
:
09
:
29
:
d
4
>
01
:
00
:
5
e
:
00
:
00
:
12
,
ethertype IPv
4
(
0
x
0800
)
,
length
54
:
(
tos
0
xc
0
,
ttl
255
,
id
1066
,
offset
0
,
flags [none]
,
proto VRRP
(
112
)
,
length
40
)
169.2
54.1
92.2
>
224.0
.
0.1
8
:
vrrp
169.2
54.1
92.2
>
224.0
.
0.1
8
:
VRRPv
2
,
Advertisement
,
vrid
1
,
prio
50
,
authtype none
,
intvl
2
s
,
length
20
,
addrs
:
169.2
54.0
.
1
11
:
18
:
12.9
71101
fa
:
16
:
3
e
:
09
:
29
:
d
4
>
01
:
00
:
5
e
:
00
:
00
:
12
,
ethertype IPv
4
(
0
x
0800
)
,
length
54
:
(
tos
0
xc
0
,
ttl
255
,
id
1067
,
offset
0
,
flags [none]
,
proto VRRP
(
112
)
,
length
40
)
169.2
54.1
92.2
>
224.0
.
0.1
8
:
vrrp
169.2
54.1
92.2
>
224.0
.
0.1
8
:
VRRPv
2
,
Advertisement
,
vrid
1
,
prio
50
,
authtype none
,
intvl
2
s
,
length
20
,
addrs
:
169.2
54.0
.
1
|