Keepalived实现Nginx高可用
一、介绍
Keepalived 是一款开源的、基于 VRRP 协议的Linux软件,通过虚拟IP地址(VIP)的漂移和健康检查来实现服务器故障时的自动切换。
原理
检测keepalived 进程是否存活,如果检测不到,就代表对方宕机,会把虚拟IP地址(VIP)抢占过来。
如果需要检测 nginx 的话,可以写个脚本,检测 nginx 的状态。
二、环境准备
两台机器环境初始化,安装 keepalived、nginx
当然也可以从官网下载源码包,编译安装。最新版 2.3.4
规划
| 主机名 |
ip地址 |
用途 |
| nginx-01 |
192.168.10.101 |
|
| nginx-02 |
192.168.10.102 |
|
|
192.168.10.100 |
虚拟ip地址 |
安装,版本比较旧 1.3.5
1
| yum install -y keepalived nginx
|
修改默认 html
1 2 3 4 5 6 7 8 9 10 11 12
| cat > /usr/share/nginx/html/index.html <<EOF <html> <head> <title> 192.168.10.101 </title> </head> <body> This is nginx-01 192.168.10.101 </body> </html> EOF
|
1 2 3 4 5 6 7 8 9 10 11 12
| cat > /usr/share/nginx/html/index.html <<EOF <html> <head> <title> 192.168.10.102 </title> </head> <body> This is nginx-02 192.168.10.102 </body> </html> EOF
|
三、验证
默认的配置文件是 /etc/keepalived/keepalived.conf
注意事项,一定要注意配置是否正确,该一致时一致,不一样的地方不要配置成一样。
3.1 检测 keepalived 的进程
nginx-01 上修改配置文件
1
| vim /etc/keepalived/keepalived.conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ! Configuration File for keepalived global_defs { router_id LB101 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.100 } }
|
router_id 唯一标识一个节点
vrrp_instance 实例名称
state 节点的角色
interface 网卡名称
priority 优先级,0-255,越大越优先
advert_int 检测间隔
authentication 同一组应该保持一致
virtual_ipaddress 虚拟ip
nginx-02 上修改配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ! Configuration File for keepalived global_defs { router_id LB102 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.100 } }
|
- 启动后验证
1
| systemctl enable --now keepalived
|
外部机器一直ping虚拟ip
关闭 nginx-01
3.2 检测 nginx 进程
nginx-01 的配置
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 30 31
| global_defs { router_id Node1 }
vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 }
vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 192.168.10.100 }
track_script { check_nginx } }
|
killall 通常用来杀死进程
-0 询问操作系统是否存在此进程,
- 存在返回
0
- 不存在返回
1,此时就开始降权,停止发送 VRRP 报文。
nginx-02 的配置
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 30
| global_defs { router_id Node2 }
vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 }
vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 192.168.10.100 }
track_script { check_nginx } }
|
- 启动并验证
1
| systemctl restart keepalived
|
nginx-01 关闭 nginx
3.3 排错
- 查看日志,排错时用到
1
| tail -f /var/log/messages
|
- 如果出现脑裂现象(两个节点都抢占IP地址)
可能原因,
VRRP是一种三层之上、四层之下的协议,虽然不需要暴露端口,但仍需要master持续发送组播包,来证明自己存活。
解决方案,放行防火墙
1 2 3
| firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --protocol vrrp -j ACCEPT firewall-cmd --reload
|
四、抢占模式和非抢占模式
主服务器回归后,是否抢占回来虚拟IP。
默认情况会抢占回来,但有时候不希望IP一直漂移。需要设置非抢占模式。
1
| vim /etc/keepalived/keepalived.conf
|
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 30 31 32 33
| global_defs { router_id Node1 }
vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 }
vrrp_instance VI_1 { state BACKUP nopreempt interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 192.168.10.100 }
track_script { check_nginx } }
|
1
| vim /etc/keepalived/keepalived.conf
|
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 30 31
| global_defs { router_id Node2 }
vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 }
vrrp_instance VI_1 { state BACKUP nopreempt interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 }
virtual_ipaddress { 192.168.10.100 }
track_script { check_nginx } }
|