KeepAlived+Nginx实践Nginx高可用方案
目录
1、什么是高可用?
高可用性 HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性。HA 系统是目前企业防止核心计算机系统因故障停机的最有效手段。
实现 HA 的方式,一般采用两台或者多台机器同时完成一项功能,比如数据库服务器,平常只有一台机器对外提供服务,另一台机器作为热备,当这台机器出现故障时,自动动态切换到另一台热备的机器。
2、什么是Keepalived
Keepalived软件起初是专为LVS(Linux Virtual Server)负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件
3、Keepalived如何实现故障转移
Keepalived对高可用服务之间的故障切换转移,是通过 VRRP 来实现的。在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。
Keepalived的作用是检测服务器的状态,当服务器宕机或工作出现故障,Keepalived将检测到并将服务器集群中剔除,选择其他服务器代替该服务器的工作;当服务器恢复工作正常,Keepalived检测到自动将服务器加入服务器集群。
总结来说:Keepalived软件是一个监控+自愈的软件。
运行协议是VRRP,主分发器的keepalived会向网络广播。
4、Keepalived安装
4.1 下载安装
#两种方式:
#方法一:
yum -y install keepalived(如果你本地安装了mysql,可能会有冲突)
#方法二:
cd /usr/local
wget http://www.keepalived.org/software/keepalived-2.0.19.tar.gz
#解压文件
tar -zxvf keepalived-2.0.19.tar.gz
#编译
cd keepalived-2.0.19/
#--prefix 指定安装地址
#/usr/local/keepalived/ 安装的目录,不要和解压文件一个目录,不然可能报错
./configure --prefix=/usr/local/keepalived/
#编译并安装
make && make install
4.2 运行前配置
cp /usr/local/keepalived-2.0.19/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.0.19/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
4.3 启动服务
service keepalived start
# 配置开机自启动
systemctl enable keepalived
#查看服务启动情况
ps -aux |grep keepalived
5、 Keepalive+Nginx高可用集群
双机高可用方法目前分为两种:
1)Nginx+keepalived 双机主从模式:
即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠,但是对于主从服务器配置差异很大的机器可以作为一种选择(从服务器就临时用一下嘛)
2)Nginx+keepalived 双机主主模式:
即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)。这种方案,经济实惠,非常适合于当前架构环境。一般来说,两个机器的性能都要相差无几,能够提供正常的业务访问量
5.1 双机主从模式
实验环境配置如下:
192.168.223.128: nginx + keepalived master 主
192.168.223.129: nginx + keepalived backup 从
5.1.1 主从节点服务器配置
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
}
}
5.1.2 nginx监听脚本
#与上面配置的脚本路径、名称要保持一致
cd /etc/keepalived
#创建nginx检测脚本
vim nginx_check.sh
# 添加如下内容
#!/bin/bash
nginxpid=`ps -C nginx --no-header | wc -l`
if [ $nginxpid -eq 0 ];then
systemctl restart nginx
sleep 2
nginxpid=`ps -C nginx --no-header | wc -l`
if [ $nginxpid -eq 0 ];then
killall keepalived
fi
fi
------------------------------
#给脚本增加可执行权限
chmod +x nginx_check.sh
PS:让keepalived监控NginX的状态:
由于keepalived只检测本机和他机keepalived是否正常并实现VIP的漂移,而如果本机nginx出现故障则不会漂移VIP,所以编写脚本来判断本机nginx是否正常,如果发现NginX不正常,重启之。等待3秒再次校验,仍然失败则不再尝试,关闭keepalived,其他主机此时会接管VIP;
1)经过前面的配置,如果master主服务器的keepalived停止服务,slave从服务器会自动接管VIP对外服务; 一旦主服务器的keepalived恢复,会重新接管VIP。 但这并不是我们需要的,我们需要的是当NginX停止服务的时候能够自动切换。 2)keepalived支持配置监控脚本,我们可以通过脚本监控NginX的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复NginX则杀掉keepalived,使得从服务器能够接管服务。
5.1.3 防止出现脑裂现象
脑裂(split-brain):指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致资源瓜分甚至“各自为政”,系统混乱,数据损坏。
对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(比如MySQL)的HA,必须要严格防止脑裂:
1)或者共享资源被瓜分、两边"服务"都起不来了;
2)或者两边"服务"都起来了,但同时读写"共享存储",导致数据损坏(常见如数据库轮询着的联机日志出错)。
防火墙模拟脑裂:
#在192.168.223.129上drop掉组播数据包,让备节点接收不到master上的报文,备节点就会启动接管程序接管主节点的资源, 对外提供服务, 表现形式就是备节点上出现了虚拟IP, 此时主节点也是持有虚拟IP的
iptables -A INPUT -m pkttype --pkt-type multicast -j DROP
#或者禁掉128的访问:
iptables -I INPUT -s 192.168.223.128 -j DROP
iptables -I OUTPUT -s 192.168.223.128 -j DROP
#解封:
iptables -L INPUT #查看状态
iptables -L OUTPUT #查看状态
iptables -L --line-numbers #带序号查看状态
#然后
iptables -D INPUT 序号
iptables -D OUTPUT 序号
#---------------------------------封禁----------------------------------------
[root@ydt2 ~]# iptables -A INPUT -m pkttype --pkt-type multicast -j DROP
#---------------------------------解封----------------------------------------
[root@ydt2 ~]# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT udp -- anywhere anywhere udp dpt:domain
2 ACCEPT tcp -- anywhere anywhere tcp dpt:domain
3 ACCEPT udp -- anywhere anywhere udp dpt:bootps
4 ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
5 DROP all -- anywhere anywhere PKTTYPE = multicast
[root@ydt2 ~]# iptables -D INPUT 1
[root@ydt2 ~]# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
#禁掉组播后会发现128,129两台机器都有一个相同的虚拟IP
解决办法:
1)、使用VRRP广播地址:
# 指定keepalived配置的网卡:eth0,固定的VRRP广播地址:224.0.0.18 由IANA标准指定的多点广播地址224.0.0.18
#将防火墙的vvrp开启,并使用VRRP固定的广播地址
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
#再看从节点VIP不见了
# 查看配置的规则
firewall-cmd --direct --get-rules ipv4 filter INPUT
firewall-cmd --direct --get-rules ipv4 filter OUTPUT
2)、使用脚本检测警告
检测思路:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就设置报警信息。脚本(在从节点上)
vim check_split_brain.sh
-------------------------------------------
#!/bin/bash
# 检查脑裂的脚本,在备节点上进行部署
LB01_VIP=192.168.223.130
while true
do
if [ `ip a show eth0 |grep "$LB01_VIP"|wc -l` -ne 0 ];then
if [ `ping -c 1 www.yuandengta.com|grep 100%|wc -l` -ne 0 ];
then
echo "ha is brain"
else
echo "ha is ok"
fi
fi
sleep 1
done
----------------------------------
chmod 777 check_split_brain.sh
#执行结果如下:
[root@ydt2 keepalived]# ./check_split_brain.sh
ha is ok
ha is ok
ha is ok
ha is ok
ha is ok
ha is ok
#当发现异常时候的执行结果:
[root@ydt2 keepalived]# ./check_split_brain.sh
ha is ok
ha is ok
ha is ok
ha is ok
ha is ok
ha is ok
ha is brain.
ha is brain.
5.1.4 启动查看
启动keepalived之前先将nginx启动,如果nginx报如下错误:
请执行系统配置设置:
mkdir -p /etc/systemd/system/nginx.service.d
printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" >/etc/systemd/system/nginx.service.d/override.conf
systemctl daemon-reload
systemctl restart nginx.service
接下来启动keepalived:
**启动服务:**
service keepalived start
# 配置开机自启动
systemctl enable keepalived
**查看服务启动情况:**
ps -aux |grep keepalived
**查看启动日志:**
journalctl -xe
**查看keepalived日志**
tail -f /var/log/messages
配置成功后的效果。eth0是网卡名字;192.168.223.130是虚拟ip,已经成功绑定到网卡上。
当前192.128.223.128是主节点,关闭之,查看192.128.223.129的日志信息:
再次启动192.168.223.128,查看192.128.223.129的日志信息:
5.1.5 Nginx测试
外部访问虚拟IP时,先在各节点执行如下命令,让iptables对虚拟服务ip彻底放行:
# 192.168.223.130虚拟IP #80 nginx端口
iptables -t nat -A PREROUTING -p tcp -d 192.168.223.130 --dport 80 -j REDIRECT
我们人为造些异常出来,反正就一个目标,让VIP漂移到从节点,然后我们再访问192.168.223.130/111.png
5.2 双机双主模式
5.2.1 互为主从虚拟实例配置
192.168.223.128
! 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
}
}
192.168.223.129
! 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
}
}
5.2.2 测试
关闭128节点的keepalived的,继续访问130虚拟IP,仍可访问,只不过是129节点支持的而已(nginx配置的代理地址不一样,只是为了显示讲解而已)
关闭前:
关闭后:
6、注意
1)、 在MASTER节点的 vrrp_instance 中 配置 nopreempt ,当它异常恢复后,即使它 priority 更高也不会抢占,这样可以避免正常情况下做无谓的切换
2)、 不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况
更多推荐
所有评论(0)