Nginx+Keepalived 实现简单的高可用

在单台 Nginx 负载能力冗余的情况,没必要申请更多资源做负载均衡,只需要保障高可用即可。 此配置为了应对 nginx单台机器 崩溃,或者重启 导致服务不可用的时候,能自动切换到备用的 nginx。两台 nginx 理应部署在不同的物理机,避免物理机重启的时候彻底不可用。

根据目前医院情况,Nginx 有两台,分别是 100.100.100.245 和 100.100.100.247,那寻找一个还未被使用的同网段 ip,这里假设是 100.100.100.246 还未被使用。 未禁止 ping 的时候 ping 100.100.100.246 是没有回应的。

那目前我们掌握的IP信息大概如下:

- Nginx master: 100.100.100.245

- Nginx slave: 100.100.100.247

- Virtual IP(VIP): 100.100.100.246

配置Keepalived

在Nginx master: 100.100.100.245 配置

执行以下命令安装 keepalived

1
yum install -y keepalived

配置 nginx 健康检查脚本。该脚本主要实现以下功能

  1. 如果不存在 nginx 进程,则尝试启动 nginx 进程。这里我们是用 systemd 管理的 nginx,所以用 systemctl start nginx ,如果是别的方式启动,请写具体的启动命令。
  2. 如果依然启动失败 则杀死 keepalived 进程 使得 VIP 立马飘走。不用等待权重慢慢减少再飘走。
1
2
3
4
5
6
7
8
9
10
11
cat <<EOF> /usr/local/src/nginx_check.sh
#! /bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
systemctl start nginx
sleep 2
if [ `ps -C nginx --no-header| wc -l` -eq 0 ];then
killall keepalived
fi
fi
EOF

配置 keepalived

以下脚本注意修改以下几个点

  • 网卡设备名 我这里是 eth0 ,可以使用 ip a 这个命令查看,如果不是 eth0,则修改 interface 后面的 eth0 为你正确的设备名。
  • VIP 我们前面选定的 VIP 是 100.100.100.246
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat <<EOF> /etc/keepalived/keepalived.conf 
global_defs {
router_id LVS_Main
}

vrrp_script chk_nginx {
script "/usr/local/src/nginx_check.sh"
interval 2
weight 2
}

vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 160
priority 100
advert_int 1
authentication {
auth type PASS
auth pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
100.100.100.246/24
}
}
EOF

启动 keepalived 并设置开机启动

1
systemctl enable --now keepalived

在 Nginx slave: 100.100.100.247 配置

执行以下命令安装 keepalived

1
yum install -y keepalived

配置 nginx 健康检查脚本

1
2
3
4
5
6
7
8
9
10
11
cat <<EOF> /usr/local/src/nginx_check.sh
#! /bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
systemctl start nginx
sleep 2
if [ `ps -C nginx --no-header| wc -l` -eq 0 ];then
killall keepalived
fi
fi
EOF

配置 keepalived

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat <<EOF> /etc/keepalived/keepalived.conf 
global_defs {
router_id LVS_Slave
}

vrrp_script chk_nginx {
script "/usr/local/src/nginx_check.sh"
interval 2
weight 2
}

vrrp_instance VI_1 {
state SLAVE
interface eth0
virtual_router_id 160
priority 10
advert_int 1
authentication {
auth type PASS
auth pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
100.100.100.246/24
}
}
EOF

启动 keepalived 并设置开机启动

1
systemctl enable --now keepalived

检查配置效果

确认两台机的 nginx 和 keepalived 都启动

1
2
systemctl status nginx
systemctl status keepalived

检查当前 VIP 是否绑定

目前 master (100.100.100.245)的priority 比较高,所以用命令 ip a 查看的时候,能看到VIP(100.100.100.246) 被绑在对应的网卡

1
ip a

nginx 停止的时候能被 keepalived 再度拉起

1
2
3
systemctl stop nginx
# 过几秒再查看 nginx 是否有启动
systemctl status nginx

测试 VIP 是否能飘走

1
2
3
4
5
6
7
# 在master
systemctl stop keepalived
# 停止后 看VIP是否没有了
ip a

# 在slave上查看 VIP 是否绑定
ip a

注意事项

  • 修改配置后一定要 ·nginx -t· 测试没问题后再 reload
  • 理应注意两台机器的配置保持同步。

简单点的话,在配置了 ssh master 上免密登录 slave 后。可以采用 rsync 命令同步配置

1
2
3
rsync -avz --delete /etc/nginx/ user@100.100.100.247:/etc/nginx/
# 重载 slave nginx 配置
ssh root@100.100.100.247 'systemctl reload nginx'

关注公众号 尹安灿