一、前言
1、简介
Nginx作为一款高性能的Web服务器和反向代理服务器,被广泛使用。且现如今很多高并发场景需要后端服务集群部署,因此nginx也需要支持集群部署从而避免单点故障的问题。
本文将详细介绍使用 Keepalived+Nginx 来实现Nginx的高可用集群和Nginx实现Gateway网关服务集群。
2、什么是Keepalived?
Keepalived是基于VRRP协议,作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
简单来讲Keepalived可以在master和slave子网卡建立一个相同的VIP(virtual IP),然后通过同一个虚拟出来的IP地址就可以访问两台服务器的Nginx。
二、实现步骤
实现 Keepalived+Nginx 高可用集群共有两种常用方案,即主从模式和双主模式。服务安装很简单所以本文不介绍如何安装Keepalived和Nginx服务,将从配置方面分别介绍如何实现。
1、主从模式
这种方案由两台服务器均部署一个Keepalived和一个Nginx服务,然后虚拟出一个VIP地址,两台服务器一台做主一台做备,但同时只有一台机器工作,主节点宕机后由从节点自动成为主节点。当主节点不出现故障的时候,从节点永远处于空闲状态。当主节点宕机重新上线后自动再次成为主节点。
1.1 服务器规划
角色 | ip | vip地址 | 部署服务 |
---|---|---|---|
主节点 | 10.50.7.51 | 10.50.7.100 | Keepalived+Nginx |
从节点 | 10.50.7.76 | 10.50.7.100 | Keepalived+Nginx |
1.2 服务配置
1.2.1 keepalived配置
1、主节点keepalived.conf 配置如下(我的目录是在 /etc/keepalived/keepalived.conf如下图):
keepalived.conf :
! Configuration File for keepalivedglobal_defs {#路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_51
}# 定义chk_nginx脚本,脚本执行间隔10秒,权重-10,检测nginx服务是否在运行。
vrrp_script chk_nginx { #这里通过脚本监测 script "/etc/keepalived/chk_nginx.sh" #脚本执行间隔,每2s检测一次interval 2 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5 weight -10 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间) fall 2 #检测1次成功就算成功。但不修改优先级 rise 1
}vrrp_instance VI_1 {# 表示的状态,当前服务器为nginx的主节点,MASTER/BACKUPstate MASTER# 当前实例绑定的网卡 可通过ip addr查询interface ens18# 保证主备节点一致virtual_router_id 100# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTERpriority 100# 主备之间同步检查的时间间隔,默认1sadvert_int 1# 认证授权的密码,防止非法节点的进入authentication {auth_type PASSauth_pass 1111}# 虚拟出来的VIP地址virtual_ipaddress {10.50.7.100}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }
}
2、从节点keepalived.conf配置:
! Configuration File for keepalivedglobal_defs {#路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_76
}# 定义chk_nginx脚本,脚本执行间隔10秒,权重-10,检测nginx服务是否在运行。
vrrp_script chk_nginx { #这里通过脚本监测 script "/etc/keepalived/chk_nginx.sh" #脚本执行间隔,每2s检测一次interval 2 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5 weight -10 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间) fall 2 #检测1次成功就算成功。但不修改优先级 rise 1
}vrrp_instance VI_1 {# 表示的状态,当前服务器为nginx的从节点,MASTER/BACKUPstate BACKUP# 当前实例绑定的网卡 可通过ip addr查询interface ens18# 保证主备节点一致virtual_router_id 100# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTERpriority 99# 主备之间同步检查的时间间隔,默认1sadvert_int 1# 认证授权的密码,防止非法节点的进入authentication {auth_type PASSauth_pass 1111}# 虚拟出来的VIP地址virtual_ipaddress {10.50.7.100}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }
}
3、chk_nginx.sh
vim /etc/keepalived/chk_nginx.sh,
编辑完内容之后需要赋权限,命令:chmod +x /etc/keepalived/chk_nginx.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then /home/chnsys/ecms/nginx/sbin/nginxsleep 3 if [ `ps -C nginx --no-header |wc -l` -eq 0 ] thensystemctl stop keepalived fi
fi
或者
#!/bin/bashcounter=$(ps -ef|grep nginx | grep -v 'grep'|wc -l)if [ "${counter}" = "0" ]; then/home/chnsys/ecms/nginx/sbin/nginx || truesleep 3counter=$(ps -ef|grep nginx | grep -v 'grep'|wc -l)if [ "${counter}" = "0" ]; thensystemctl stop keepalivedfifi
上述脚本需要按实际修改nginx的启动命令,两个脚本均可推荐第二个,这两个 Bash 脚本的主要目的是检查 Nginx 是否正在运行,并在其未运行时启动 Nginx。如果启动后 Nginx 仍然未运行,那么它将停止 keepalived 服务,keepalived 停止之后,将由从节点代替为主节点,防止主节点keepalived服务运行但是nginx服务挂掉导致后续服务无法访问的问题。
1.3 启动服务
分别启动两个服务器的nginx服务和keepalived服务,命令如下:
/home/chnsys/ecms/nginx/sbin/nginx(看具体的安装位置)
systemctl start keepalived (全局生效)
1.4 验证效果
分别访问主服务器和从服务器以及虚拟vip的nginx服务的默认页面地址:
可以看到,访问虚拟的VIP地址也可以访问到主服务器的nginx的默认页面。
1.5 主从切换
1、nginx
关闭主节点上的nginx服务,观察主节点的nginx是否会被自动重启。如果重启则说明chk_nginx脚本执行成功,如果nginx未能重启,则应当执行脚本中的命令关闭keepalived服务。
2、keepalived
关闭主节点的keepalived服务,观察vip是否会绑定到从服务器上。
重启主节点的keepalived服务,观察vip是否会绑定到主服务器上。
2、互为主从模式
这种方案,使用两个VIP地址,互为主备,轮询请求两个VIP地址,同时有两台机器工作,当其中一台机器出现故障,两台机器的请求转移到一台机器负担,非常适合于生产架构环境。
2.1 服务器规划
角色 | ip | vip地址 | 部署服务 |
---|---|---|---|
主、从节点 | 10.50.7.51 | 10.50.7.100 | Keepalived+Nginx |
从、主节点 | 10.50.7.76 | 10.50.7.101 | Keepalived+Nginx |
2.2 服务配置
2.2.1 keepalived配置
在双主模式中,大致内容与主从模式一样,需要额外添加以下内容,新增一个新的vrrp_instance配置,state 为主从配置相反的角色,如下:
注:chk_nginx.sh脚本在1.2.1 keepalived配置的第三个
1、主节点keepalived.conf 配置如下:
! Configuration File for keepalivedglobal_defs {#路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_51}# 定义chk_nginx脚本,脚本执行间隔10秒,权重-10,检测nginx服务是否在运行。vrrp_script chk_nginx { #这里通过脚本监测 script "/etc/keepalived/chk_nginx.sh" #脚本执行间隔,每2s检测一次interval 2 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5 weight -10 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间) fall 2 #检测1次成功就算成功。但不修改优先级 rise 1 }vrrp_instance VI_1 {# 表示的状态,当前服务器为nginx的主节点,MASTER/BACKUPstate MASTER# 当前实例绑定的网卡 可通过ip addr查询interface ens18# 保证主备节点一致virtual_router_id 100# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTERpriority 100# 主备之间同步检查的时间间隔,默认1sadvert_int 1# 认证授权的密码,防止非法节点的进入authentication {auth_type PASSauth_pass 1111}# 虚拟出来的VIP地址virtual_ipaddress {10.50.7.100}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }}vrrp_instance VI_2 {# 表示的状态,当前服务器为nginx的主节点,MASTER/BACKUPstate BACKUP# 当前实例绑定的网卡 可通过ip addr查询interface ens18# 保证主备节点一致virtual_router_id 101# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTERpriority 99# 主备之间同步检查的时间间隔,默认1sadvert_int 1# 认证授权的密码,防止非法节点的进入authentication {auth_type PASSauth_pass 1111}# 虚拟出来的VIP地址virtual_ipaddress {10.50.7.101}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }}
2、从节点keepalived.conf 配置如下:
! Configuration File for keepalivedglobal_defs {router_id 76
}# 定义chk_nginx脚本,脚本执行间隔10秒,权重-10,检测nginx服务是否在运行。
vrrp_script chk_nginx { #这里通过脚本监测 script "/etc/keepalived/chk_nginx.sh" #脚本执行间隔,每2s检测一次interval 2 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5 weight -10 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间) fall 2 #检测1次成功就算成功。但不修改优先级 rise 1
}vrrp_instance VI_1 {state BACKUPinterface ens18virtual_router_id 100priority 99advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {10.50.7.100}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }
}vrrp_instance VI_2 {state MASTERinterface ens18virtual_router_id 101priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {10.50.7.101}#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!track_script { #引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。 chk_nginx }
}
2.3 启动或重启服务
分别启动两个服务器的nginx服务和keepalived服务,命令如下:
/home/chnsys/ecms/nginx/sbin/nginx(看具体的安装位置)
systemctl restart keepalived (全局生效)
2.4 验证效果
分别访问主服务器和从服务器的虚拟vip的nginx服务的默认页面地址:
可以看到两个服务器互为主从的效果
2.5 主从切换
同上述1.5中效果验证即可
三、实现网关集群
本文通过两种方案实现 Keepalived+Nginx 的高可用集群。还有一些其他的特性功能,例如主备节点切换后邮件通知等也只需修改相关配置即可,本文主要实现主备切换的功能就不在此赘述。
一般来讲会再通过nginx来路由请求后台网关服务,网关服务同样需要集群来解决单点故障问题,可以利用nginx的特性来反向代理网关集群:
1、nginx.conf配置
upstream niginx-http-cluster{server 10.50.7.51:8080;server 10.50.7.76:8080;
}server {listen 8080;server_name localhost;location / {proxy_redirect off;proxy_set_header Host $host;proxy_set_header Origin '';proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://niginx-http-cluster/hello/;}
}
按照上述配置之后,nginx会轮询访问两个网关服务的地址,当其中一个服务挂掉之后,就会自动切换到正常的服务,从而实现网关服务集群。