Keepalived服务

一、高可用

  • 概念:多台业务系统提供相同的服务,如果其中一套业务系统故障,其他业务系统会自动接管业务;我们将其称为高可用;

  • 目的:通常使用keepalived软件实现高可用,keepalived是借助VRRP(虚拟路由冗余协议)实现高可用功能;

  • 应用场景:主要用于业务系统,保证业务系统的7x24小时运行;

二、VRRP

1.工作原理

2.角色

  • Master
  • Slave
通过结点设置的vrrp优先级选举主从关系;

3.模式

  • 抢占式:高优先级结点恢复正常后,自动接管冗余结点业务

  • 非抢占式:高优先级结点恢复正常后,不接管冗余结点业务,直到冗余结点发生故障;

三、Keepalived

1.配置文件

  • /etc/sysyconfig/keepalived keepalived服务启动参数配置文件
  • /etc/keepalived/keepalived.conf keepalived服务配置文件

2.工作原理

四、部署流程

step1 安装

yum install -y keepalived
[root@lb01 ~]# yum install -y keepalived
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
......
Dependencies Resolved

========================================================================================================
 Package                       Arch             Version                         Repository         Size
========================================================================================================
......
Installed:
  keepalived.x86_64 0:1.3.5-8.el7_6.5                                                                   

Dependency Installed:
  net-snmp-agent-libs.x86_64 1:5.7.2-38.el7_6.2         net-snmp-libs.x86_64 1:5.7.2-38.el7_6.2        

Complete!

step2 配置

vim/etc/keepalived/keepalived.conf

[抢占式]

  • Master(MASTER)配置
[root@lb01 /etc/keepalived]# vim keepalived.conf
global_defs {
   router_id LB01
}
vrrp_instance VI_1 {
    state MASTER                   #定义设备角色
    interface eth0                 #定义绑定接口
    virtual_router_id 51           #定义实例组ID
    priority 150                   #定义设备优先级
    advert_int 3                   #定义vrrp组播包宣告时间(3s)
    authentication {               #定义vrrp验证
        auth_type PASS
        auth_pass 1111
    }   
    virtual_ipaddress {            #定义vrrp虚拟IP地址
        10.0.0.13
    }   
  • Slave(BACKUP)配置
[root@lb02 /etc/keepalived]# vim keepalived.conf
global_defs {
   router_id LB02
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.13
    }
}

[非抢占式]

官方建议:Keepalived设置为非抢占模式;避免业务频繁切换至不同的主机;
1、两个结点state都必须配置为BACKUP
2、两个结点都在vrrp instance中添加nopreempt参数
3、其中一个结点优先级必须高于另外一个结点

两台服务器都启用nopreempt后,必须修改角色状态统一为BACKUP,唯一的区分就是优先级

  • Master(BACKUP)配置
[root@lb01 /etc/keepalived]# vim /etc/keepalived/keepalived.conf
global_defs {
   router_id LB01
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    nopreempt             #开启非抢占模式
    priority 150
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.13
    }
}
  • Slave(BACKUP)配置
[root@lb02 /etc/keepalived]# vim keepalived.conf
global_defs {
   router_id LB02
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.13
    }
}

step3 启动

systemctl restart keepalived
[root@lb01 /etc/keepalived]# systemctl restart keepalived.service

step4 测试(非抢占式)

[root@lb01 /etc/keepalived]# systemctl restart keepalived.service

四、Keepalived与Nginx服务结合

Nginx负载均衡实现高可用,需要借助Keepalived地址漂移功能;

有Nginx负载均衡,并不一定必须要装Keepalived保证高可用;

1、判断Keepalived故障

故障原理

  • 主备设备无法检测对端心跳,导致双方都判定自己是Master而互相抢占资源;

故障原因

  • 服务器网线松动
  • 服务器硬件故障或发生损坏现象 崩溃
  • 主备主机开启防火墙

解决思路

  • 停止其中一台主机的Keepalived服务;

示例脚本

适用于抢占式-备机使用
[root@lb02 /etc/keepalived]# vim /server/scripts/keepalived_status.sh
#!/bin/bash
vip=10.0.0.13
master_ip=10.0.0.15
while true; do
    ping -c 2 -W 3 $master_ip &>/dev/null
    if [ $? -eq 0 -a `ip add|grep "$vip"|wc -l` -eq 1];then
        echo "keepalived is Breakdown;"
    else
        echo "keepalived is OK!"
    fi
sleep5
done

2、判断Nginx故障

必要性

  • 如果Nginx宕机,会导致用户请求失败,但是Keepalived并不会进行地址漂移

解决思路

  • 编写一个脚本监测Nginx存活状态;如果不存活则kill nginx和keepalived

[示例脚本]

[root@lb01 /]# vim /server/scripts/Check_Nginx.sh
#!/bin/bash
#定义变量
nginxpid=$(ps -C nginx --no-header|wc -l)
#判断nginx服务存活状态,如果nginx状态处于非存活,尝试启动nginx
if [ $nginxpid -eq 0 ]; then
   systemctl start nginx
   sleep 2
#等待2秒,重新获取nginx服务状态
   nginxpid=$(ps -C nginx --no-header|wc -l)
#再次判断nginx服务存活状态,若nginx仍处于非存活状态则停止keepalived
服务,让地址进行漂移,并退出脚本
   if [ $nginxpid -eq 0 ]; then
      systemctl stop keepalived
      echo "$(date +%F_%T) Nginx Service is down, Keepalived servic
e stopped" >>/var/log/message
   fi
fi
[root@lb01 /]# chmod +x /server/scripts/Check_Nginx.sh
[root@lb01 /]# ll /server/scripts/Check_Nginx.sh
-rwxr-xr-x 1 root root 611 Aug  8 16:05 /server/scripts/Check_Nginx.sh

[keepalived调用脚本]

[root@lb01 /]# vim /etc/keepalived/keepalived.conf
global_defs {
   router_id LB01
}
vrrp_script Check_Nginx {                          #定义调用脚本函数
   script "/server/scripts/Check_Nginx.sh"         #调用脚本(脚本要有执行权限)
   interval 10                                     #调用脚本执行间隔时间(脚本执行间隔时间一定要大于脚本本身的执行时间)
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    nopreempt
    priority 150
    advert_int 3
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.13
    }
    track_script {                                 #调用并运行该脚本
       Check_Nginx
    }
}
[root@lb01 /]# systemctl restart keepalived.service

[脚本调用验证]

[root@lb01 /]# systemctl stop nginx.service 
[root@lb01 /]# systemctl status nginx
● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: http://nginx.org/en/docs/

Aug 08 16:13:17 lb01 systemd[1]: Starting nginx - high performance web server...
Aug 08 16:13:17 lb01 systemd[1]: PID file /var/run/nginx.pid not readable (yet?) after start.
Aug 08 16:13:17 lb01 systemd[1]: Started nginx - high performance web server.
Aug 08 16:13:23 lb01 systemd[1]: Stopping nginx - high performance web server...
Aug 08 16:13:23 lb01 systemd[1]: Stopped nginx - high performance web server.
Aug 08 16:13:27 lb01 systemd[1]: Starting nginx - high performance web server...
Aug 08 16:13:27 lb01 systemd[1]: PID file /var/run/nginx.pid not readable (yet?) after start.
Aug 08 16:13:27 lb01 systemd[1]: Started nginx - high performance web server.
Aug 08 16:13:35 lb01 systemd[1]: Stopping nginx - high performance web server...
Aug 08 16:13:35 lb01 systemd[1]: Stopped nginx - high performance web server.
[root@lb01 /]# sleep 10
[root@lb01 /]# systemctl status nginx
● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2019-08-08 16:13:37 CST; 16s ago
     Docs: http://nginx.org/en/docs/
  Process: 17378 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
 Main PID: 17379 (nginx)
   CGroup: /system.slice/nginx.service
           ├─17379 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
           └─17380 nginx: worker process

Aug 08 16:13:37 lb01 systemd[1]: Starting nginx - high performance web server...
Aug 08 16:13:37 lb01 systemd[1]: PID file /var/run/nginx.pid not readable (yet?) after start.
Aug 08 16:13:37 lb01 systemd[1]: Started nginx - high performance web server.

[结果验证]

[root@lb02 /etc/keepalived]# vim /etc/nginx/nginx.conf 
user  www;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
#http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$
request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}
[root@lb02 /etc/keepalived]# nginx -t
nginx: [emerg] "types" directive is not allowed here in /etc/nginx/mime.types:2
nginx: configuration file /etc/nginx/nginx.conf test failed
[root@lb02 /etc/keepalived]# systemctl stop nginx.service 

附:思维导图