KeepAlived+Nginx实践Nginx高可用方案
高可用性 HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性。HA 系统是目前企业防止核心计算机系统因故障停机的最有效手段。
实现 HA 的方式,一般采用两台或者多台机器同时完成一项功能,比如数据库服务器,平常只有一台机器对外提供服务,另一台机器作为热备,当这台机器出现故障时,自动动态切换到另一台热备的机器。
Keepalived软件起初是专为LVS(Linux Virtual Server)负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
Keepalived对高可用服务之间的故障切换转移,是通过 VRRP 来实现的。在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。
Keepalived的作用是检测服务器的状态,当服务器宕机或工作出现故障,Keepalived将检测到并将服务器集群中剔除,选择其他服务器代替该服务器的工作;当服务器恢复工作正常,Keepalived检测到自动将服务器加入服务器集群。
核心原理:使用两台Nginx做反向代理服务器,当其中一台Nginx宕机之后,仍能用另一台来工作,两台Nginx之间用keeplived来监测心跳。
配置要求:两台服务器,三个同网段的IP地址。
关闭系统防火墙
必须关闭,否则会导致无法访问。
systemctl stop firewalld
systemctl disable firewalld
检测系统模块加载
ip_vs模块系统默认没有自动加载,可以通过。
lsmod | grep ip_vs
命令查看一下,如果没有任何输出则表示ip_vs模块并没有被内核加载,那必须手动加载一下:
modprobe ip_vs
modprobe ip_vs_wrr
写到/etc/rc.local文件中实现开机加载此模块。
安装NGINX
两台服务器安装nginx
配置启动脚本
脚本路径:/lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动并设置开启自启
systemctl start nginx
systemctl enable nginx
安装keepalived
两台都需要安装
yum install -y keepalived
#方法二:
cd /usr/local
wget https://www.keepalived.org/software/keepalived-2.2.8.tar.gz
#解压文件
tar -zxvf keepalived-2.2.8.tar.gz
#编译
cd keepalived-2.2.8/
#--prefix 指定安装地址
#/usr/local/keepalived/ 安装的目录,不要和解压文件一个目录,不然可能报错
./configure --prefix=/usr/local/keepalived/
#编译并安装
make && make install
运行前配置
cp /usr/local/keepalived-2.2.8/keepalived/etc/init.d/keepalived /etc/init.d/
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalived-2.2.8/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
配置文件修改
检测脚本路径:/usr/local/sbin/check_ng.sh
设置权限:744
#!/bin/bash
#时间变量,用于记录日志
d=`date --date today +%Y-%m-%d_%H:%M:%S`
echo "$d nginx status check" >> /var/log/check_ng.log
#计算nginx进程数量
n=`ps -C nginx --no-heading|wc -l`
#如果进程为0,则启动nginx,并且再次检测nginx进程数量,
#如果还为0,说明nginx无法启动,此时需要关闭keepalived
if [ $n -eq "0" ]; then
echo "$d nginx stop retry again" >> /var/log/check_ng.log
systemctl start nginx
sleep 2
n2=`ps -C nginx --no-heading|wc -l`
if [ $n2 -eq "0" ]; then
echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log
systemctl stop keepalived
fi
fi
双机高可用方法目前分为两种:
1)Nginx+keepalived 双机主从模式:即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠,但是对于主从服务器配置差异很大的机器可以作为一种选择(从服务器就临时用一下嘛)
2)Nginx+keepalived 双机主主模式:即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)。这种方案,经济实惠,非常适合于当前架构环境。一般来说,两个机器的性能都要相差无几,能够提供正常的业务访问量。
双机主从模式
实验环境配置如下:
192.168.223.128: nginx + keepalived master 主
192.168.223.129: nginx + keepalived backup 从
192.168.223.128(主节点配置)
vim /etc/keepalived/keepalived.conf
-------------------------------------------------------
! Configuration File for keepalived
global_defs {
#不与其他节点重名即可
router_id nginx_router
}
# 检测nginx是否运行
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #心跳执行的脚本
interval 2 #(检测脚本执行的间隔,单位是秒)
weight -20 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -20
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance nginx {
state BACKUP #此处不设置为MASTER,通过priority来竞争master
interface eth0 #网卡名称
virtual_router_id 51 #同一个keepalived集群的virtual_router_id相同
priority 100 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
authentication { #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
# 虚拟ip地址(VIP,一个尚未占用的内网ip即可,可以多个)
virtual_ipaddress {
192.168.223.130
192.168.223.131
}
}
192.168.223.129(从),就改个priority
vim /etc/keepalived/keepalived.conf
global_defs {
#不与其他节点重名即可
router_id nginx_router
}
# 检测nginx是否运行
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #心跳执行的脚本
interval 2 #(检测脚本执行的间隔,单位是秒)
weight -20 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -20
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance nginx {
state BACKUP #此处不设置为MASTER,通过priority来竞争master
interface eth0 #网卡名称
virtual_router_id 51 #同一个keepalived集群的virtual_router_id相同
priority 90 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
authentication { #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
# 虚拟ip地址(VIP,一个尚未占用的内网ip即可,可以多个)
virtual_ipaddress {
192.168.223.130
192.168.223.131
}
}
由于keepalived只检测本机和他机keepalived是否正常并实现VIP的漂移,而如果本机nginx出现故障则不会漂移VIP,所以编写脚本来判断本机nginx是否正常,如果发现NginX不正常,重启之。等待3秒再次校验,仍然失败则不再尝试,关闭keepalived,其他主机此时会接管VIP;
1)经过前面的配置,如果master主服务器的keepalived停止服务,slave从服务器会自动接管VIP对外服务; 一旦主服务器的keepalived恢复,会重新接管VIP。 但这并不是我们需要的,我们需要的是当NginX停止服务的时候能够自动切换。
2)keepalived支持配置监控脚本,我们可以通过脚本监控NginX的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复NginX则杀掉keepalived,使得从服务器能够接管服务。
防止出现脑裂现象
脑裂(split-brain):指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致资源瓜分甚至“各自为政”,系统混乱,数据损坏。
对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(比如MySQL)的HA,必须要严格防止脑裂:
1)或者共享资源被瓜分、两边"服务"都起不来了;
2)或者两边"服务"都起来了,但同时读写"共享存储",导致数据损坏(常见如数据库轮询着的联机日志出错)。
双机双主模式
主机
注意修改:脚本地址、网卡名称、虚拟IP地址
! Configuration File for keepalived
global_defs {
router_id nginx_router
}
# 检测nginx是否运行
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #心跳执行的脚本
interval 2 #(检测脚本执行的间隔,单位是秒)
weight -20 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -20
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance nginx {
state BACKUP #此处不设置为MASTER,通过priority来竞争master
interface eth0 #网卡名称
virtual_router_id 51 #virtual_router_id相同漂移相同的VIP
priority 100 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
authentication { #设置验证类型和密码,同一个VIP实例,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
# 虚拟ip地址(VIP,一个尚未占用的内网ip即可,可以多个)
virtual_ipaddress {
192.168.223.130
}
}
#增加的备虚拟节点
vrrp_instance nginx2 {
state BACKUP
interface eth0
virtual_router_id 52 #注意不要与上方virtual_router_id相同
priority 90 #一定要比上方的优先级低
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.223.131
}
}
备机
注意修改:脚本地址、网卡名称、虚拟IP地址
! Configuration File for keepalived
global_defs {
router_id nginx_router
}
# 检测nginx是否运行
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #心跳执行的脚本
interval 2 #(检测脚本执行的间隔,单位是秒)
weight -20 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -20
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance nginx {
state BACKUP #此处不设置为MASTER,通过priority来竞争master
interface eth0 #网卡名称
virtual_router_id 51 #同一个keepalived集群的virtual_router_id相同
priority 90 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
authentication { #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
# 虚拟ip地址(VIP,一个尚未占用的内网ip即可,可以多个)
virtual_ipaddress {
192.168.223.130
}
}
#增加的主虚拟节点
vrrp_instance nginx2 {
state BACKUP
interface eth0
virtual_router_id 52 #注意不要与上方virtual_router_id相同
priority 100 #一定要比上方的优先级高
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
#与上方nginx运行状况检测呼应
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.223.131
}
}
启动并设置开启自启
systemctl start keepalived
systemctl enable keepalived