• Long Live Kubernetes!
  • 可关注微信公众第一时间知晓网站动态。 微信公众号
  • Long Live Linux!
  • 您觉得本站非常有看点,可以收藏本站,本站将持续推出高质量文章!
  • This site has been created and is maintained by and is the sole property of Yok8s.com. No part of this site may be copied or reproduced without express written consent from the authors of this site.

KeepAlived+Nginx实践Nginx高可用方案

中间件 Rocloong 来源:CSDN 3个月前 (09-26) 93次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

什么是高可用?

高可用性 HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性。HA 系统是目前企业防止核心计算机系统因故障停机的最有效手段。

实现 HA 的方式,一般采用两台或者多台机器同时完成一项功能,比如数据库服务器,平常只有一台机器对外提供服务,另一台机器作为热备,当这台机器出现故障时,自动动态切换到另一台热备的机器。

什么是Keepalived

Keepalived软件起初是专为LVS(Linux Virtual Server)负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件

Keepalived如何实现故障转移

Keepalived对高可用服务之间的故障切换转移,是通过 VRRP 来实现的。在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。

Keepalived的作用是检测服务器的状态,当服务器宕机或工作出现故障,Keepalived将检测到并将服务器集群中剔除,选择其他服务器代替该服务器的工作;当服务器恢复工作正常,Keepalived检测到自动将服务器加入服务器集群。

总结来说:Keepalived软件是一个监控+自愈的软件。

运行协议是VRRP,主分发器的keepalived会向网络广播。

Keepalived安装

Keepalived安装

##两种方式:
##方法一:
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

运行前配置

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/

启动服务

service keepalived start
# 配置开机自启动
systemctl enable keepalived
#查看服务启动情况
ps -aux |grep keepalived

Keepalive+Nginx高可用集群

双机高可用方法目前分为两种:

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
}
}

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,使得从服务器能够接管服务。

防止出现脑裂现象

脑裂(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.

启动查看

请执行系统配置设置:

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,已经成功绑定到网卡上。

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

双机双主模式

互为主从虚拟实例配置

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
}
}

测试

关闭128节点的keepalived的,继续访问130虚拟IP,仍可访问,只不过是129节点支持的而已(nginx配置的代理地址不一样,只是为了显示讲解而已)

特别注意

1、在MASTER节点的 vrrp_instance 中 配置 nopreempt ,当它异常恢复后,即使它 priority 更高也不会抢占,这样可以避免正常情况下做无谓的切换

2、不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况


《KeepAlived+Nginx实践Nginx高可用方案》版权归作者所有,如需转载请注明出处,并附带文章链接地址,侵权必究!!!
喜欢 (1)
[]
分享 (0)
Rocloong
关于作者:
善战者无赫赫战功!
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到