Keepalived,即存活检测机制,是 Linux 下一个轻量级别的高可用解决方案;起初针对 LVS 进行研发,通过心跳检测检查系统中各个服务节点的健康状态,支持故障自动切换。

原理

虚拟路由冗余协议(VRRP)是一种容错协议,它通过把几台路由设备联合组成一台虚拟的路由设备,并通过一定的机制来保证当主机的下一跳设备出现故障时,可以及时将业务切换到其它设备,从而保持通讯的连续性和可靠性。
VRRP 将局域网内的一组路由器划分在一起,称为一个备份组。备份组由一个 Master 路由器和多个 Backup 路由器组成,功能上相当于一台虚拟路由器。局域网内的主机只需要知道这个虚拟路由器的 IP 地址,并不需知道具体某台设备的 IP 地址,将网络内主机的缺省网关设置为该虚拟路由器的 IP 地址,主机就可以利用该虚拟网关与外部网络进行通信。
VRRP 将该虚拟路由器动态关联到承担传输业务的物理路由器上,当该物理路由器出现故障时,再次选择新路由器来接替业务传输工作,整个过程对用户完全透明,实现了内部网络和外部网络不间断通信。

部署

  1. yum install -y keepalive

修改配置文件vim /etc/keepalived/keepalived.conf,state 可以设置为:MASTER或BACKUP

  1. global_defs {
  2. router_id ka01 #标识信息
  3. }
  4. vrrp_instance VI_1 {
  5. state MASTER
  6. priority 150 #优先级
  7. interface eth0 #绑定的网卡
  8. virtual_router_id 50 #同一个虚拟的路由
  9. advert_int 1 #心跳的间隔时间
  10. authentication {
  11. auth_type PASS #两个主机之间的密语
  12. auth_pass 1111 #心跳密码
  13. }
  14. virtual_ipaddress {
  15. 10.0.0.3 #虚拟IP地址(可以绑定多个虚拟IP地址)
  16. }
  17. }
  1. systemctl enable keepalive
  2. systemctl start keepalive
  3. systemctl stop keepalive

方式

Keepalive 高可用分为:抢占式和非抢占式

抢占式(默认)

BACKUP挂掉,BACKUP上台,MASTER重新启动则将 IP 抢占过去。

非抢占式

两台均为BACKUP,在优先级上做区分,如MASTER挂掉,BACKUP上台,则BACKUP变成MASTER,MASTER变为BACKUP。

  • 两个节点的state均为BACKUP(官方建议)
  • 两个节点都在vrrp_instance中添加nopreempt
  • 其中一个节点的优先级要高于另外一个节点

PS.两台服务器角色都启用了nopreempt后,必须修改角色状态统一为BACKUP,唯一的区别就是优先级不同。

  1. #Master
  2. vrrp_instance VI_1 {
  3. state BACKUP
  4. priority 150
  5. nopreempt
  6. }
  7. #Backup
  8. vrrp_instance VI_1 {
  9. state BACKUP
  10. priority 100
  11. nopreempt
  12. }

故障

脑裂

当两台高可用服务器在指定的时间内,无法互相检测到对方心跳而各自启动故障转移功能,取得了资源以及服务的所有权,而此时的两台高可用服务器对都还活着并作正常运行,这样就会导致同一个服务在两端同时启动而发生冲突的严重问题,最严重的就是两台主机同时占用一个VIP的地址(类似双端导入概念),当用户写入数据的时候可能会分别写入到两端,这样可能会导致服务器两端的数据不一致或造成数据的丢失,这种情况就称为裂脑,也有的人称之为分区集群或者大脑垂直分隔。

  • 服务器网线松动等网络故障
  • 服务器硬件故障发生损坏现象而奔溃
  • 主备服务器都开启了firewalld防火墙

    解决方法

    如果 Nginx 宕机,会导致用户请求失败,但 Keepalived 并不会进行地址漂移;所以需要编写一个脚本检测 Nginx 的存活状态,如果不存活则 kill nginx 和 keepalived
    1. vim check_nginx.sh
    2. #!/bin/sh
    3. nginxpid=$(ps -C nginx --no-header|wc -l)
    4. #1.判断 Nginx 是否存活,如果不存活则尝试启动 Nginx
    5. if [ $nginxpid -eq 0 ];then
    6. systemctl start nginx
    7. sleep 3
    8. #2.等待 3 秒后再次获取一次 Nginx 状态
    9. nginxpid=$(ps -C nginx --no-header|wc -l)
    10. #3.再次进行判断,如 Nginx 还不存活则停止 Keepalived,让地址进行漂移,并退出脚本
    11. if [ $nginxpid -eq 0 ];then
    12. systemctl stop keepalived
    13. fi
    14. fi
    15. #添加执行权限
    16. chmod +x check_ nginx.sh
    配置 Keepalived 使用 ```bash vim /etc/keepalived/keepalived.conf global_defs { router_id 01 }

定义脚本所在的位置,以及执行时间

vrrp_script check_nginx { script “/root/check_nginx.sh” interval 5 }

vrrp_instance VI_1 { state BACKUP priority 150 nopreempt interface eth0 virtual_router_id 50 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.3 }

  1. #调用脚本
  2. track_script {
  3. check_nginx
  4. }

} ```