Nginx配合keepalived实现高可用

高可用性是Web服务的一项重要指标。Nginx和Keepalived的完美结合,能够有效提高服务的稳定性,避免单点故障。

环境

 1服务器:CentOS7
 2
 3Server1 : 10.211.55.3
 4
 5Server2 : 10.211.55.14
 6
 7Docker:23.0.5
 8
 9Nginx:1.23.4
10
11keepalived:1.3.5

部署

本次测试使用两台测试虚拟机,IP 分别为 10.211.55.3 和 10.211.55.14 ,Nginx 使用 Docker 进行部署,keepalived 直接在服务器部署。架构图如下:

images202401222131858.png

使用 yum 安装的 keepalived,配置文件在 /etc/keepalived/ 目录下,将 10.211.55.3 服务器的 keepalived.conf 文件内容替换为下面内容:

 1global_defs {
 2   script_user root
 3   enable_script_security
 4}
 5
 6vrrp_script check_nginx {
 7    script /etc/keepalived/check-nginx.sh
 8    interval 2
 9}
10
11vrrp_instance Vs_1 {
12    state BACKUP # 定义节点主/备,主MASTER,备BACKUP,这里2个节点均为BACKUP
13    interface eth0 # 虚拟IP绑定的网卡
14    virtual_router_id 32 # 集群号,所有节点需要相同
15    priority 100 # 权重,2个节点权重一致,降低权重后会发生切换
16    advert_int 1 # 检测间隔
17
18    # 抢占模式,(nopreempt非抢占模式),配置为抢占模式时,当节点权重降低时,另外一个高权重节点会抢占服务,发生切换;
19    # 如果为非抢占模式,上面配置的检查脚本在检查到服务失败后,降低权重,但是不会发生切换。
20    !nopreempt
21
22    authentication {
23        auth_type PASS
24        auth_pass 1111 # 各节点密码一致
25    }
26
27    unicast_src_ip 10.211.55.3 # 本端,源地址
28    unicast_peer {
29      10.211.55.14 # 对端,目标地址
30    }
31    virtual_ipaddress {
32        10.211.55.4  # 虚拟IP
33    }
34    track_interface {
35        eth0 # 检查网卡健康
36    }
37    track_script {
38        check_nginx
39    }
40}
  • virtual_ipaddress :定义了虚拟 IP 10.211.55.4 ,后续访问将会使用虚拟 IP 进行访问
  • unicast_peer:设置另一台服务器的 IP :10.211.55.14
  • unicast_src_ip:设置当前服务器的 IP:10.211.55.3
  • check_nginx:设置心跳检测的脚本

10.211.55.14 服务器的配置文件和上面一样,将 unicast_peer 和 unicast_src_ip 设置的 IP 互换即可。

check_nginx 设置的心跳检测脚本路径为:/etc/keepalived/check-nginx.sh ,在 /etc/keepalived 目录下创建 check-nginx.sh 文件,内容如下:

1#!/bin/bash
2count=`netstat -ntpl | grep 10000 | wc -l`
3if [ $count -gt 0 ]; then
4    exit 0
5else
6    exit 1
7fi
  • 要执行 netstat 命令,需要使用 yum -y isntall net-tools 命令安装相关依赖
  • 这段脚本的意思就是使用 netstat 命令查看当前系统中所有 TCP 连接的状态,然后使用 grep 命令筛选出其中监听端口为 10000 的连接,最后使用 wc -l 命令统计筛选出的行数
  • 使用 if 语句对命令输出结果进行判断。如果监听在 TCP 端口 10000 上的进程数量大于 0,则表示有进程正在监听该端口,那么脚本就会执行 exit 0 命令来退出,并返回一个成功的退出码(0)。反之,如果监听在 TCP 端口 10000 上的进程数量等于 0,则表示没有进程在监听该端口,那么脚本就会执行 exit 1 命令来退出,并返回一个失败的退出码(1)

使用下面命令给 check-nginx.sh 文件设置权限:

1chmod +x check-nginx.sh

配置文件修改好后,执行 systemctl start keepalived 启动 keepalived 服务,使用命令 systemctl status keepalived 可以查看状态,如下图为正常:

验证

1、两台服务器都正常运行时,使用虚拟 IP + 负载 Nginx 端口(http://10.211.55.4:10000)进行访问,正常情况下页面中的 IP 应该在 10.211.55.3 和 10.211.55.14 之间来回切换。

2、关闭 10.211.55.14 服务器的 9000 端口的 docker 容器,访问站点页面应该只会出现 IP 10.211.55.3。

3、继续关闭 10.211.55.14 服务器的 10000 端口的 docker 容器,站点应该可以继续访问。

4、关闭 10.211.55.14 服务器,站点应该可以继续访问。

5、启动 10.211.55.14 服务器和 9000、10000 端口的容器,访问页面,检查是否恢复了负载切换。

6、同样的操作可以将 10.211.55.3 再来一遍,检查网页访问是否正常。