Linux keepalived工作原理
一、keepalived简介与工作原理
Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
keepalived工作在IP/TCP协议栈的IP层,TCP层,及应用层,工作原理基于VRRP协议。
网络层(layer 3):Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包,(既我们平时用的Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除。
传输层(layer 4):Keepalived以TCP端口的状态来决定服务器工作正常与否,如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。
应用层(layer 5):只要针对应用上的一些探测方式,如URL的get请求,或者对nginx脚本检测等;可以根据用户自定义添加脚本针对特定的服务进行状态检测,当检测结果与用户设定不一致,则把这台服务器从服务器群中剔除。
二、VRRP协议与工作原理

VRRP(Virtual Router Redundancy Protocol)虚拟路由冗余协议是一种容错的主备模式的协议,当网络设备发生故障时,可以不影响主机之间通信情况下进行设备切换,并且相对用户时切换过程时透明的。
路由器开启VRRP功能后,会根据优先级确定自己在备份组中的角色。优先级高的路由器成为主用路由器,优先级低的成为备用路由器。主用路由器拥有虚拟IP与虚拟MAC,实现各种网络功能,并发送VRRP通告报文,通知备用路由器组内的其他路由器自己工作正常;备用路由器则启动定时器等待通告报文。抢占模式下,当备用路由器收到VRRP通告报文后,会将自己的优先级与通告报文中的优先级进行比较。如果大于通告报文中的优先级,则成为主用路由器;否则将保持备用状态。非抢占模式下,只要主用路由器不发生故障,就算备用路由器的优先级再高,也始终保持备用状态。如果备用路由器的定时器超时后仍未收到主用路由器发送来的VRRP通告报文,则认为主用路由器已经无法正常工作,备份组内的路由器根据优先级选举出主用路由器。
一个VRRP路由器有唯一的标识:VRID,范围为0—255。该路由器对外表现为唯一的虚拟MAC地址,地址的格式为00-00-5E-00-01-[VRID]。
同一台路由器可以加入多个备份组,在不同备份组中有不同的优先级,使得该路由器可以在一个备份组中作为主用路由器,在其他的备份组中作为备用路由器。
提供了两种安全认证措施:明文认证和IP头认证。
三、VRRP选举机制
虚拟IP拥有者,如果某台路由器的IP地址与虚拟路由器的VIP地址一致,那么这台就会被选为主用路由器。
优先级较高者,如果没有虚拟IP拥有者,优先级数值大的路由器会被选举出,优先级范围0~255。
IP地址较大者,如果优先级一样高,IP地址数值大的路由器会被选举出。
VRRP的工作工程:
(1) 虚拟路由器中的路由器根据优先级选举出 Master。 Master 路由器通过发送免费 ARP 报文,将自己的虚拟 MAC 地址通知给与它连接的设备或者主机,从而承担报文转发任务;
(2) Master 路由器周期性发送 VRRP 报文,以公布其配置信息(优先级等)和工作状况;
(3) 如果 Master 路由器出现故障,虚拟路由器中的 Backup 路由器将根据优先级重新选举新的 Master;
(4) 虚拟路由器状态切换时, Master 路由器由一台设备切换为另外一台设备,新的 Master 路由器只是简单地发送一个携带虚拟路由器的 MAC 地址和虚拟 IP地址信息的ARP 报文,这样就可以更新与它连接的主机或设备中的ARP 相关信息。网络中的主机感知不到 Master 路由器已经切换为另外一台设备。
(5) Backup 路由器的优先级高于 Master 路由器时,由 Backup 路由器的工作方式(抢占方式和非抢占方式)决定是否重新选举 Master。
VRRP优先级的取值范围为0到255(数值越大表明优先级越高)
keepalived的工作原理就是基于VRRP实现的,keepalived的体系结构图如下:

在这个机构图中,处于内核的IPVS和NETLINK,其中NETLINK是提供高级路由及其他相关的网络功能,如果在负载均衡器上启用iptables/netfilter,将会直接影响它的性能。对于图中不同模块功能的介绍如下:
- VRRP Stack 负责负载均衡器之间的失败切换FailOver;//LVS中负责DR调度器组的
- Checkers 负责检查调度器后端的Real server 或者 Upstream Server的健康状况; // 检查RS的状态,决定是否将其剔除
- WatchDog 负责监控checkers和VRRP进程的状况;
- IPVS wrapper 用来发送设定的规则到内核IPVS;
- Netlink Reflector 用来设定VRRP的vip地址。// VIP也有‘人’管
keepalived运行时,会启动3个进程,分别为:core(核心进程),check和vrrp
- core:负责主进程的启动,维护和全局配置文件的加载;
- check:负责健康检查
- vrrp:用来实现vrrp协议
四、keepalived配置组成
global_defs是对全局一些参数做出设置。
global_defs {
notification_email {
接受邮件地址
sysadmin@firewall.loc
}
notification_email_from master@keepalived.com
邮件头地址
smtp_server 192.168.200.1
邮件服务smtp地址
smtp_connect_timeout 30
smtp连接超时时间
router_id LVS_DEVEL
本地机器的id,可以为本地主机名
vrrp_skip_check_adv_addr
检查收到的通告中的所有地址会非常耗时,设置此参数就不会检查收到过的主路由器的通告
vrrp_strict
严格遵守VRRP协议,开启这个功能会在iptables中添加下面一条规则,导致VIP ping不通
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all – 0.0.0.0/0 172.30.100.200
vrrp_garp_interval 0
一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0
vrrp_gna_interval 0
一个网卡上每组na消息之间的延迟时间,默认为0
vrrp_iptables
设置此项则不会开启任何iptables规则
vrrp_mcast_group4 224.0.0.18
主备间通告状态信息的组播地址,通常为224网段
}
vrrp_script只是定义一个对集群服务的健康状态检测脚本,并根据监控的结果状态能实现优先动态调整;这种方式在做高可用nginx或者haproxy时需要用到。
vrrp_script chk_nginx {
script
# 添加要定期执行的检测脚本,它的退出代码将被记录在监视它的所有VRRP实例中
interval 2
# 两次脚本调用的间隔,默认为1秒
weight -20
# 如果检测条件成立,权重-20
}
vrrp_instance是虚拟路由实例的配置段,用来定义当前keepalived节点的运行角色为主或是备,定义当前节点的优先级,设置虚拟IP等信息。
vrrp_instance VI_1 {
定义虚拟路由器,实例名称VI_1主备必须相同
state MASTER
# 定义此节点为MASTER
interface eth0
# 绑定为当前虚拟路由器使用的物理接口
virtual_router_id 51
# 设置虚拟路由id,范围0~255,主备必须相同
priority 100
# 设置此节点优先级
advert_int 1
# 设置主备节点间vrrp通告状态的时间间隔
authentication {
# 设置主备间验证方式
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
# 设置虚拟路由VIP
172.30.200.1
}
track_script {
# 添加监控脚本,脚本名为vrrp_script中定义的脚本
chk_nginx
}
}
virtual_server中定义了LVS工作模式及调度算法等信息,real_server则是定义后端的真实服务器。
virtual_server 172.30.200.1 80 {
定义虚拟主机IP与端口
delay_loop 6
# 健康状态检测时间间隔
lb_algo rr
# lvs调度算法
lb_kind NAT
# lvs工作类型
persistence_timeout 50
# lvs持久连接超时时间
protocol TCP
# 定义服务协议
sorry_server 172.30.10.14 80
# 当后端所有主机不可达时,就会被定义这台主机,只是为了展示sorry页面
real_server 172.30.10.12 80 {
# 配置后端主机
weight 1
# 调度权重
HTTP_GET {
# 应用层检测
url {
path /testurl/test.jsp
# 定义被检测的URL
status_code 200
# 判断上述URL健康状态的响应码
digest 640205b7b0fc66c1ea91c463fac6334d
# 判断上述URL健康状态的内容的hash码
}
connect_timeout 3
# 检测连接的超时时间
nb_get_retry 3
# 重试次数
delay_before_retry 3
# 重试前等待时间
}
TCP_CHECK {
connect_ip 172.30.10.12
# 选择要连接的IP地址。默认值为realserver IP
connect_port 80
# 选择要连接的端口。默认值为realserver PORT
bindto 172.30.10.11
# 用于发起连接的可选源地址
bind_port 10000
# 用于发起连接的可选源端口
connect_timeout 3
# 连接超时时间
}
}
real_server 172.30.10.12 80 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
全局定义段、VRRP实例定义段、虚拟服务器定义段。
global_defs {
notification_email { 指定keepalived在发生切换时需要发送email到的对象。
acassen@firewall.loc
}
notification_email_from huangxin202823@163.com #指定发件人
smtp_server smtp.163.com #指定smtp服务器地址
smtp_connect_timeout 3 #指定smtp连接超时时间
router_id LVS_DEVEL #运行keepalived的一个标识
}
vrrp_sync_group VG_1{ #监控多个网段的实例
group{
inside_network #实例名
outside_network }
notify_master /path/xx.sh #指定当切换到master时,执行的脚本
netify_backup /path/xx.sh #指定当切换到backup时,执行的脚本
notify_fault “path/xx.shVG_1” #故障时执行的脚本
notify /path/xx.sh #脚本所在目录
smtp_alert #使用global_defs中提供的邮件地址和smtp服务器发送邮件通知}
#VRRP实例定义段
vrrp_instance VI_1 {
state MASTER #指定哪个为master,哪个为backup
interface eth0 #设置实例绑定的网卡
virtual_router_id 51 #VRID标记
priority 100 #优先级,高优先级的DR会抢占为master (默认为抢占模式)
advert_int 1 #检查间隔,1秒
authentication { #设置认证
auth_type PASS #认证方式
auth_pass 1111 #认证字符串(使用 openssl rand -hex 6生成随机字符串)
}
virtual_ipaddress { #设置VIP




