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 #查看服务状态