跳转到内容

使用keepalived实现nginx高可用部署

nginx-HA-poster
服务器1 服务器2
系统 Red Hat Enterprise Linux release 8.6 (Ootpa) Red Hat Enterprise Linux release 8.6 (Ootpa)
IP 192.168.12.11 192.168.12.12
nginx版本 nginx-1.14.1-9.module+el8.0.0+4108+af250afe.x86_64 nginx-1.14.1-9.module+el8.0.0+4108+af250afe.x86_64
keepalived版本 keepalived-2.1.5-8.el8.x86_64 keepalived-2.1.5-8.el8.x86_64
虚拟IP 192.168.12.10(需要保证该IP未被路由)
  1. 双机主从模式: 即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态; 当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。

  2. 双机主主模式: 即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务; 当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)。

两台测试机都需要安装nginx:

Terminal window
yum install nginx -y

修改nginx配置增加server:

Terminal window
server {
listen 80;
server_name 192.168.12.10;
location /nginx-test {
return 200 "Hello from Nginx@XX"; # 为了区分两个服务器在这里可以加上IP
}
}

为了更直观地看到高可用方案生效,将两台服务器nginx默认返回html做修改以区分。安装完成后启动nginx:

Terminal window
systemctl start nginx.service
#查看nginx运行状态,确保nginx已经正常启动
systemctl status nginx
#设置nginx服务开机自启动
systemctl enable nginx.service

两台测试机都需要安装keepalived:

Terminal window
yum install keepalived -y

安装完成后修改/etc/keepalived/keepalived.conf文件,配置内容如下:

Terminal window
! Configuration File for keepalived
global_defs {
router_id master # 集群中该主机的id,需要唯一
}
# 定时检查nginx状态
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" # 检查脚本位置
interval 2 # 检查时间间隔2s
weight -5 # 失败后权重减少5
fall 3 # 三次失败后切换主备
rise 2
}
vrrp_instance VI_1 {
state MASTER # 标识主服务器
interface ens192 # 这个网卡名称可以通过lshw -class net -businfo来查看
virtual_router_id 51 # 同一个集群需要相同
priority 100 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
# 源地址(只在组播不同的情况下配置)
unicast_src_ip 192.168.12.11
# 目标地址(只在组播不同的情况下配置)
unicast_peer {
192.168.12.12
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.12.10 #虚拟ip,随便写一个没有被用到的ip
}
}

另外一台备份服务器也需要配置如下:

Terminal window
! Configuration File for keepalived
global_defs {
router_id slave # 集群中该主机的id,需要唯一
}
# 定时检查nginx状态
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" # 检查脚本位置
interval 2 # 检查时间间隔2s
weight -5 # 失败后权重减少5
fall 3 # 三次失败后切换主备
rise 2
}
vrrp_instance VI_1 {
state BACKUP # 标识主服务器
interface ens192 # 这个网卡名称可以通过lshw -class net -businfo来查看
virtual_router_id 51 # 同一个集群需要相同
priority 90 # 权重,master要大于slave
advert_int 1 # 主备通讯时间间隔
# 源地址(只在组播不同的情况下配置)
unicast_src_ip 192.168.12.12
# 目标地址(只在组播不同的情况下配置)
unicast_peer {
192.168.12.11
}
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.12.10 #虚拟ip,随便写一个没有被用到的ip
}
}

其中检查nginx状态的脚本/etc/keepalived/check_nginx.sh如下:

#!/bin/bash
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then
systemctl restart nginx.service
sleep 2
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then
systemctl stop keepalived.service
fi
fi

启动keepalived:

Terminal window
systemctl start keepalived.service
#查看keepalived服务状态,确保已经正常启动
systemctl status keepalived
#设置keepalived服务开机自启动
systemctl enable keepalived.service

由于防火墙会导致主服务器异常时虚拟IP无法漂移到备份服务器,需要针对keepalived做出防火墙规则的调整。Keepalived使用vrrp组播,默认地址是224.0.0.18,因此要配置防火墙放过:

Terminal window
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT

需要放过nginx端口:

Terminal window
firewall-cmd --zone=public --add-port=80/tcp --permanent

重载防火墙配置:

Terminal window
firewall-cmd --reload

如果SELinux处于开启状态并且未放开http上游连接会导致nginx无法将请求转发到上游服务,所以需要关闭或配置SELinux。

  1. 关闭SELinux
Terminal window
setenforce 0
  1. 配置SELinux 如果不能关闭selinux,则需要配置一下相关规则:
Terminal window
semanage permissive -a httpd_t

在域中的用户电脑上打开命令行请求虚拟IP:

Terminal window
curl http://192.168.12.10/nginx-test # 输出“Hello from Nginx@88”,该消息来自主服务器

在主服务器中停止keepalived服务模拟主服务器异常:

Terminal window
systemctl stop keepalived

再次在用户电脑中请求虚拟IP:

Terminal window
curl http://192.168.12.10/nginx-test # 输出“Hello from Nginx@114”,该消息来自备份服务器

说明已经实现了nginx的高可用。此时可以重新启动主服务器上的keepalived服务:

Terminal window
systemctl restart keepalived

再次在用户电脑上请求虚拟IP:

Terminal window
curl http://192.168.12.10/nginx-test # 输出“Hello from Nginx@88”,该消息来自主服务器

说明主服务器重新加入到集群中。