Keepalive:http://www.keepalived.org/
《老男孩Linux运维》
Keepalived
Keepalived介绍
Keepalived软件最初是专为LVS设计的,用来管理并监控LVS集群系统中的各个服务节点状态,后来又加入了实现高可用的 VRRP功能。因此,Keepalived除了能管理LVS外,还可以作为Nginx、Haproxy等的高可用解决软件。
Keepalived主要是通过VRRP协议实现高可用功能。
VRRP(Virtual Router Redundancy Protocol),虚拟路由冗余协议。
VRRP目的是为了解决静态路由单点故障问题,它能保证当个别节点宕机时,整个网络可以不间断地运行。
所以,Keepalived一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。
Keepalived的三个重要功能
管理LVS负载均衡软件
可以说,Keepalived起初是专为解决LVS的问题而诞生的。因此,Keepalived和LVS的关系如夫妻一样,可紧密结合。
实现对LVS集群节点健康检查
当LVS集群中某个节点服务器发生故障时,Keepalived服务会自动将失效的节点从正常队列中剔除,并将请求调度到别的正常的节点服务器上,从而保证用户访问不受影响。当故障节点被修复后,Keepalived服务又会自动把它切换回来。
系统网络服务的高可用功能
Keepalived可以实现任意两台主机之间,如Master和Backup间的故障转移和自动切换。这个主机是不能停机的业务服务器,如LVS负载均衡、Nginx反向代理服务器等。
Keepalived高可用功能的简单原理。Mater获得所有资源并对用户提供服务,Backup主机为Master的热备。当Master失效或出现故障时,Backup将自动接管Master主机的所有工作,包括VIP资源;当Master恢复后,自会自动接管回它原来的工作,Backup则同时释放它接管的工作。
此时,两台主机将恢复到最初启动时各自的原始角色及工作状态。
Keepalived高可用故障切换转移原理
Keepalived高可用服务的故障切换转移,是通过VRRP来实现的。
在Keepalived服务正常运行时,主Master节点会不断向备用结点发送(多播方式)心跳信息,用以告诉Backup节点自己还活着。
当Master节点发生故障时,就无法发送心跳信息,Backup节点也就无法检测到来自Master的心跳信息,于是调用自身的接管程序,接管Master的IP资源和服务;
当Master恢复时,Backup又会释放Master故障时自身接管的IP资源和服务,恢复到原来的备用角色。
VRRP(Virtual Router Redundancy Protocol)虚拟路由协议,为了解决静态路由的单点故障问题,VRRP通过一种竞选机制来将路由的任务交给某台VRRP路由器。
VRRP早期是用来解决交换机、路由器等设备单点故障。交互、路由的Master和Backup的切换原理同样适用于Keepalived的工作原理。
在一组VRRP路由器集群中,有多台物理VRRP路由器,但并不是同时工作,而是由一台Master的机器负责路由工作,其他机器都是Backup。Master并不是一成不变,VRRP会让每个VRRP路由参与竞选,最终获胜的就是Master。获胜的Master有一些特权,比如拥有虚拟路由器的IP地址等。
拥有系统资源的Master负责转发发送给网关地址的包和响应ARP请求。
VRRP通过竞选机制来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(Multicast)包形式来发送,默认多播地址224.0.0.18
。在一组虚拟路由器中,不管谁是 Master,对外都是相同的MAC和IP,称之为VIP。客户端主机并不需要因Master的改变而修改自己的路由配置。对他们来说,这种切换时透明的。
在一组虚拟路由器中,只有作为Master的VRRP路由器会一直发送VRRP广播包,此时Backup不会抢占Master。当Master不可用时,Backup就收不到来自Master的广播包了,此时多台Backup中优先级最高的路由器会抢占为Master。
这种抢占非常快速,以保证服务的连续性。处于安全性考虑,VRRP数据报使用了加密协议进行加密。
Keepalived高可用服务
安装Keepalived软件
可以通过官方下载源码来编译安装,也可以使用yum来安装。
yum search keepalived
yum install -y keepalived
rpm -q keepalived
Keepalived配置文件
利用yum安装,Keepalived的配置文件默认为:/etc/keepalived/keepalived.conf
全局定义(Global Definitions)部分:
! Configuration File for keepalived
#号 和 !号 都是注释
global_defs { #全局定义
notification_email { #定义报警邮件地址,当服务切换或RS节点有故障时,发送报警邮件
[email protected] #收件人1
[email protected] #收件人2
[email protected] #收件人3
}
notification_email_from [email protected] #发件人
smtp_server 192.168.200.1 #发送邮件的smtp服务器
smtp_connect_timeout 30 #连接smtp的超时时间
#所有邮件报警相关参数均可以不配,可以交由监控软件(如Nagios、Zabbix)实现
router_id LVS_DEVEL #Keepalived服务器的路由标识。在一个局域网内,此标识应该唯一
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
VRRP实例定义区块(VRRP instance)部分:
这部分主要用来定义具体服务的实例配置,包括Keepalived主备状态、接口、优先级、认证方式和IP信息等。
vrrp_instance VI_1 {
#定义一个vrrp实例,名字是 VI_1
#每个vrrp实例可以认为是Keepalived服务的一个实例或作为一个业务服务,在Keepalived服务配置中,vrrp实例可以有多个
#注意,存在于主节点中的vrrp实例在备节点中也要存在,这样才能实现故障切换转移
state MASTER
#当前vrrp实例状态,MASTER|BACKUP,大写
interface eth0
#网络通信接口,注意服务器的接口名称
virtual_router_id 51
#虚拟路由ID标识,这个标识最好是一个数字,并在keepalived.conf配置中唯一
#MASTER和BACKUP配置中相同vrrp实例的virtual_router_id必须一致,否则将出现脑裂问题
priority 100
#优先级,数字越大,表示实例优先级越高
#在同一个vrrp实例里,MASTER的优先级要高于BACKUP才行
advert_int 1
#同步通知间隔,MASTER和BACKUP之间通信检查的时间间隔,单位是秒
authentication {
#权限认证配置
auth_type PASS
#认证类型,有PASS(Simple Passwd)和 AH(IPSEC),官方推荐PASS
#验证密码为明文方式,最好长度不要超过8个字符,建议使用4位的数字。同一个vrrp实例的MASTER和BACKUP使用相同的密码才能正常通信
auth_pass 1111 #通信密码
}
virtual_ipaddress {
#虚拟ip,可以配置多个虚拟ip,配置是最好指定子网掩码和虚拟IP绑定的网络接口。否则子网掩码默认是32位,绑定的接口和前面的interface参数配置一致
#虚拟IP就是工作中需要和域名绑定的IP,和配置高可用服务监听的IP要保持一致
192.168.200.16
192.168.200.17
192.168.200.18
}
}
配置Keepalived高可用
Keepalived高可用服务器节点,MASTER 和 BACKUP 。两台的配置如下:
Ip:
MASTER:192.168.1.9
BACKUP:192.168.1.7
Virtual_ip:192.168.3.88
upstream.conf:
upstream zhang {
server 192.168.0.99:5678;
}
Nginx.conf:
http {
xxx;
include /xxx/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
proxy_pass http://zhang;
}
访问效果:
MASTER端Keepalived.conf:
! Configuration File for keepalived
global_defs {
router_id zhang #路由器ID主备可同可不同
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.3.88/22 dev ens33 label ens33:1
}
}
BACKUP端Keepalived.conf:
BACKUP在MASTER没有挂的情况下是没有VIP的哦!VIP同一时刻只能出现在同一台机器上。
! Configuration File for keepalived
global_defs {
router_id zhang #路由器ID主备可同可不同
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.3.88/22 dev eth0 label eth0:1
}
}
注意:
state 不一样;
priority 不一样;
修改hosts:
192.168.3.88 www.zhang.com
实际效果:
切换MASTER:
192.168.1.9上
service keepalived stop
这里1.9主机的Keepalived挂掉后,VIP实现了自动漂移切换。因此,仅适合两台服务器提供的服务均开启的应用场景,这也是工作中常用的高可用解决方案。
关于脑裂问题:
如果MASTER 和 BACKUP都出现了VIP,那说明两者高可用裂脑了,裂脑是两台服务器争抢同一资源导致的。
如出现两节点抢夺同一IP资源问题,可考虑排查:
主备服务器间通信是否正常,是否有防火墙阻挡;
主备对应的keepalived.conf配置文件是否有错?
Keepalived高可用服务的裂脑问题
什么是裂脑
由于某些原因,导致两台高可用服务器在指定时间内,无法检测到对方的心跳消息,各自取得资源及服务的所有权,而此时的两台高可用服务器对都还活着并正常运行,这样就会导致同一个ip或服务在两端同时存在而发生冲突。
最严重的是两台主机占用同一个VIP地址,当用户写入数据时可能会分别写入到两端,这可能会导致服务器两端的数据不一致或造成数据丢失,这种情况被称为裂脑。
裂脑发生的原因
一般来说,有以下几种原因:
- 高可用服务器对之间心跳线路发生故障,导致无法正常通信;
- 高可用服务器上开启了防火墙阻挡了心跳信息传输;
- 高可用服务器网卡等信息配置不正确,导致心跳信息发送失败;
- 其他服务配置不当,如vrrp实例的virtual_router_id不一致;
解决裂脑常见方案
- 保证通信线路完整;
- 当检测到裂脑时强行关闭一个心跳节点;
- 做好多裂脑的监控报警,发生问题时及时解决;
- 如果有防火墙,要让心跳信息通过;
Keepalived双实例双主模式
前面的Keepalived栗子是单实例主备模式,但Keepalived还支持双实例多业务双向主备模式。需要创建新实例。
双实例主备环境:
192.168.1.7 instance VI_1-BACKUP, instance VI_2-MASTER;
192.168.1.9 instance VI_1-MASTER, instance VI_2-BACKUP;
instance 1-VIP:192.168.3.88-www.zhang.com;
instance 2-VIP:192.168.3.99-www.zhang.cn;
#记得添加hosts
192.168.1.9-keepalived.conf:
! Configuration File for keepalived
global_defs {
router_id zhang
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.3.88/22 dev ens33 label ens33:1
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
192.168.3.99/22 dev ens 33 label ens33:2
}
}
192.168.1.7-keepalived.conf:
! Configuration File for keepalived
global_defs {
router_id zhang
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.3.88/22 dev eth0 label eth0:1
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
192.168.3.99/22 dev eth0 label eth0:2
}
}
效果:
VIP漂移:
192.168.1.9
service keepalived stop
访问图:
解决高可用服务只针对物理服务器的问题
默认情况下,Keepalived软件仅仅在另外一台机器宕机或Keepalived停掉的时候才会接管业务。
但在实际工作中,有业务服务停止而Keepalived服务还存在的情况,这就会导致用户访问的VIP无法找到对应的服务。那么,如果让ip漂移到对端节点呢?
第一个方法:可以写守护进程脚本来处理
当Nginx业务有问题时,就停掉本地的Keepalived服务,实现IP漂移到对端继续提供服务。
举个栗子:
vim check_nginx.sh
#!/bin/bash
while true
do
if [ `netstat -nltup | grep nginx | wc -l` -ne 1 ];then
/sbin/service keepalived stop
fi
sleep 2
done
第二个方法:使用Keepalived配置文件触发写好的监测脚本
监测脚本:
vim chk_nginx.sh
#!/bin/bash
while true
do
if [ `netstat -nltup | grep nginx | wc -l` -ne 1 ];then
/sbin/service keepalived stop
fi
sleep 3
done
修改keepalived.conf:
! Configuration File for keepalived
global_defs {
xxx
}
vrrp_script chk_nginx { #定义vrrp脚本
script "/etc/keepalived/chk_nginx.sh"
interval 2 #间隔2s
weight 2
}
vrrp_instancd xxx {
xxx
virtual_ipaddress {
xxx
}
track_script { #触发检查
chk_nginx
}
}
解决多组Keepalived服务器在同一个局域网的冲突问题
当在同一个局域网内部部署了多组Keepalived服务器对,而又未使用专门的心跳线通信时,可能会发生高可用接管的严重故障问题。
Keepalived高可用是通过VRRP协议来实现的,VRRP协议默认通过IP多播的形式实现高可用对之间的通信。多组Keepalived服务器对会造成IP多播地址冲突问题,导致接管错乱,不同组的Keepalived都是使用默认的 224.0.0.18
作为多播地址。
此时解决办法是,在同组的Keepalived服务器所有的配置文件里指定独一无二的多播地址。
global_defs {
router_id zhang
vrrp_mcast_group4 224.0.0.19 #指定多播地址
不同实例的通信认证密码也最好不同,以确保接管正确。
指定Keepalived日志
默认情况下,Keepalived服务的日志会输出到 /var/log/messages
,和其他日志混杂在一起,很不方便。
操作如下:
vim /etc/sysconfig/keepalived
将 KEEPALIVED_OPTIONS="-D"
修改为 KEEPALIVED_OPTIONS="-D -d -S 0"
vim /etc/rsyslog.conf
#在末尾加入
#keepalived
local0.* /var/log/keepalived.log
#然后找到 *.info;mail.none;authpriv.none;cron.none /var/log/messages
#加上local0
*.info;mail.none;authpriv.none;cron.none;local0.none /var/log/messages
#重启rsyslog服务
service rsyslog restart
开发检查Keepalived脑裂的脚本
思路:在备节点上执行脚本,如果可以ping通主节点,并且备节点有VIP就报警,让人员介入检查。