一、前言
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 keepalived
global_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/BACKUP
state MASTER
# 当前实例绑定的网卡 可通过ip addr查询
interface ens18
# 保证主备节点一致
virtual_router_id 100
# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTER
priority 100
# 主备之间同步检查的时间间隔,默认1s
advert_int 1
# 认证授权的密码,防止非法节点的进入
authentication {
auth_type PASS
auth_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 keepalived
global_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/BACKUP
state BACKUP
# 当前实例绑定的网卡 可通过ip addr查询
interface ens18
# 保证主备节点一致
virtual_router_id 100
# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTER
priority 99
# 主备之间同步检查的时间间隔,默认1s
advert_int 1
# 认证授权的密码,防止非法节点的进入
authentication {
auth_type PASS
auth_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/nginx
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ]
then
systemctl stop keepalived
fi
fi
或者
#!/bin/bash
counter=$(ps -ef|grep nginx | grep -v 'grep'|wc -l)
if [ "${counter}" = "0" ]; then
/home/chnsys/ecms/nginx/sbin/nginx || true
sleep 3
counter=$(ps -ef|grep nginx | grep -v 'grep'|wc -l)
if [ "${counter}" = "0" ]; then
systemctl stop keepalived
fi
fi
上述脚本需要按实际修改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 keepalived
global_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/BACKUP
state MASTER
# 当前实例绑定的网卡 可通过ip addr查询
interface ens18
# 保证主备节点一致
virtual_router_id 100
# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTER
priority 100
# 主备之间同步检查的时间间隔,默认1s
advert_int 1
# 认证授权的密码,防止非法节点的进入
authentication {
auth_type PASS
auth_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/BACKUP
state BACKUP
# 当前实例绑定的网卡 可通过ip addr查询
interface ens18
# 保证主备节点一致
virtual_router_id 101
# 优先级/权重,谁的优先级高,在MASTER挂掉以后,就能成为MASTER
priority 99
# 主备之间同步检查的时间间隔,默认1s
advert_int 1
# 认证授权的密码,防止非法节点的进入
authentication {
auth_type PASS
auth_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 keepalived
global_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 BACKUP
interface ens18
virtual_router_id 100
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.50.7.100
}
#执行nginx检测脚本。注意这个设置不能紧挨着写在vrrp_script配置块的后面(实验中碰过的坑),否则nginx监控失效!!
track_script {
#引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。
chk_nginx
}
}
vrrp_instance VI_2 {
state MASTER
interface ens18
virtual_router_id 101
priority 100
advert_int 1
authentication {
auth_type PASS
auth_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会轮询访问两个网关服务的地址,当其中一个服务挂掉之后,就会自动切换到正常的服务,从而实现网关服务集群。