Linux下Nginx+keepalived实现高可用

前言

一般情况下,如果是小型项目,客户端使用一个Nginx做反向代理或者负载均衡即可。但是如果想做到高可用,Nginx也必须得有多个,一个Nginx服务挂掉,能自动切换到另一个Nginx服务上。使用Nginx + keepalived,对外提供一个虚拟ip,虚拟ip对应多台Nginx服务。出现故障时,ip自动漂移。如下所示:

 

 

准备

虚拟机两台,安装Nginx,安装 keepalived 可直接使用命令 yum -y install keepalived 。

keepalived 默认配置文件路径:/etc/keepalived/keepalived.conf

keepalived 默认日志存放路径:/var/log/messages

网格划分如下:

名称 操作系统 IP 虚拟IP keepalived
虚拟机1 Centos7.6 192.168.20.12 192.168.20.100 MASTER
虚拟机2 Centos7.6 192.168.20.16 192.168.20.100 BACKUP

 

 

 

 

1、启动Nginx

简单起见,也为了后面测试,只用Nginx自带的静态页进行测试。

静态页面路径:nginx/html/index.html,分别在index.html中增加一行"<span>ip:192.168.20.12</span>"和"<span>ip:192.168.20.16</span>"

切到 usr/local/nginx/sbin目录下,执行启动Nginx命令:

./nginx

 

2、keepalived抢占式配置

MASTER配置如下(默认配置文件:/etc/keepalived/keepalived.conf):

global_defs {               
   router_id keep12             ##路由id,通常为 hostname
}

vrrp_script chk_nginx {
        script "/etc/keepalived/nginx_check.sh" ## 检测 nginx 状态的脚本路径
        interval 2              ## 检测时间间隔
        weight -20              ## 如果条件成立,权重-20
}

vrrp_instance VI_1 {
    state MASTER                ##主节点为 MASTER,备份节点为 BACKUP
    interface ens32             ##绑定 VIP 的网络接口,与本机IP地址所在网络接口相同
    virtual_router_id 100       ##虚拟路由id,主从节点必须保持一致
    priority 100                ##节点优先级,直范围0-254,MASTER 要比 BACKUP 高
    advert_int 1
    authentication {            ##设置验证信息,两个节点必须一致
        auth_type PASS
        auth_pass 123456
    }
    track_script {
        chk_nginx               ##执行 Nginx 监控
    }
    virtual_ipaddress {
        192.168.20.100          ##VIP,两个节点必须设置一样(可设置多个)
    }
}

BACKUP配置如下(默认配置文件:/etc/keepalived/keepalived.conf):

global_defs {               
   router_id keep16             ##路由id,通常为 hostname
}

vrrp_script chk_nginx {
        script "/etc/keepalived/nginx_check.sh" ## 检测 nginx 状态的脚本路径
        interval 2              ## 检测时间间隔
        weight -20              ## 如果条件成立,权重-20
}

vrrp_instance VI_1 {
    state BACKUP                ##主节点为 MASTER,备份节点为 BACKUP
    interface ens32             ##绑定 VIP 的网络接口,与本机IP地址所在网络接口相同
    virtual_router_id 100       ##虚拟路由id,主从节点必须保持一致
    priority 90                 ##节点优先级,直范围0-254,MASTER 要比 BACKUP 高
    advert_int 1
    authentication {            ##设置验证信息,两个节点必须一致
        auth_type PASS
        auth_pass 123456
    }
    track_script {
        chk_nginx               ##执行 Nginx 监控
    }
    virtual_ipaddress {
        192.168.20.100          ##VIP,两个节点必须设置一样(可设置多个)
    }
}

其中有几个配置需要注意:

a、router_id,最好配置成hostname(需要在 /etc/hosts 文件中,增加一行,比如:127.0.0.1  keep12)

b、interface,本机IP地址所在网络接口(可以通过 ifconfig 命令查看具体ip所对应的那个接口名称)

 

3、增加检测心跳脚本

由于某些原因(比如主备都开启了防火墙),导致两台高可用服务器(Nginx + keepalived)在指定时间内,无法检测到对方存活心跳信号,从而导致互相抢占对方的服务所有权,然而两台高可用服务器可能都还存活着。所以需要增加一个检测Nginx是否存活的脚本,如果Nginx挂掉了,则停掉该服务器上的keepalived(所有的keepalived都要配置)。

在 /etc/keepalived 目录下,新增文件 nginx_check.sh (和上面对应script中对应),然后添加内容:

#!/bin/bash
#1、判断Nginx是否存活
counter=`ps -C nginx --no-header | wc -l`
if [ $counter -eq 0 ]; then
    #2、如果不存活则尝试启动Nginx
    ./usr/local/nginx/sbin/nginx
    sleep 2
    #3、等待2秒后再次获取一次Nginx状态
    counter=`ps -C nginx --no-header | wc -l`
    #4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
    if [ $counter -eq 0 ]; then
        killall keepalived
    fi
fi

 

4、测试

为了方便测试,最好先将上面心跳脚本文件中的重启nginx注释掉,不然手动停止Nginx后,又会被keepalived复活。

a、分别启动两台机器上的 Nginx 和 keepalived,然后访问虚拟ip:http://192.168.20.100

b、停掉192.168.20.12上的Nginx服务,在 keepalived的日志文件中可以看到心跳脚本被执行了,最后杀掉了keepalived:

然后访问虚拟ip:http://192.168.20.100

c、重新启动192.168.20.12上的Nginx和keepalived服务,发现又回到了"ip:192.168.20.12"

 

踩过的坑

keepalived日志文件:/var/log/messages

1、心跳脚本没有被执行

     原因:脚本文件写错了,多了一些字符

     解决:重新编辑心跳脚本文件,可以通过sh nginx_check.sh 命令执行一下,看编写的脚本是否正确

2、心跳脚本执行报错,日志提示:WARNING - script '/etc/keepalived/nginx_check.sh' is not executable for uid:gid 0:0 - disabling.

     原因:心跳脚本文件没有执行权限

     解决:chmod +x /etc/keepalived/nginx_check.sh

3、心跳脚本执行报错,日志提示:/etc/keepalived/nginx_check.sh exited due to signal 15

     原因:心跳检查间隔时间太短了

     解决:interval设置大一点(一定要大于sleep时间)

 

其它

1、如果要配置keepalived非抢占式,可以参考:https://www.cnblogs.com/t-bar/p/9940085.html

2、keepalived命令:

systemctl start keepalived      #启动服务
systemctl restart keepalived    #重启服务
systemctl stop keepalived       #停止服务
systemctl status keepalived     #查看服务状态

 

posted @ 2021-02-05 12:26  仅此而已-远方  阅读(1187)  评论(0编辑  收藏  举报