keepalived使用
一、keepalived简介
Keepalived 是基于 VRRP(虚拟路由冗余协议)实现的高可用解决方案,主要用于实现服务器(如 Nginx、MySQL)的故障自动切换,核心是通过虚拟 IP(VIP)在主备节点间漂移来保证服务不中断。
1.1 Keepalived 核心配置结构
Keepalived 的主配置文件默认路径是 /etc/keepalived/keepalived.conf,核心分为 3 个区块:
- global_defs:全局配置(日志、标识等);
- vrrp_instance:VRRP 实例配置(核心,定义 VIP、主备角色、切换规则);
- virtual_server(可选):虚拟服务器配置(结合 LVS 时使用,纯高可用可省略)。
2.1 环境介绍
四台服务器,规划如下:
- 负载均衡器主
lsb-23(MASTER):IP = 192.168.106.23 - 负载均衡器备
lsb-24(BACKUP):IP = 192.168.106.24 - 虚拟 IP(VIP):192.168.106.100(确保无机器使用)
- nginx服务器
web-34:IP=192.168.106.34 - nginx服务器
web-36:IP=192.168.106.36
2.2 实现效果
在正常使用过程中,负载均衡器主lsb-23,负责将web请求分发到web-34,web-36这两台web服务器中,当lsb-23服务出现故障时可以切换负载均衡器备lsb-24来顶替,确保业务不中断。当lsb-23恢复时可直接切换为主负载均衡器
(单节点负载均衡查看上篇)
2.3 配置步骤
2.3.1 主节点(MASTER)配置
/etc/keepalived/keepalived.conf
# 全局配置global_defs { # 标识本节点的字符串(自定义,建议唯一) router_id lsb-23 # 禁止 SNMP 陷阱(新手可忽略) vrrp_skip_check_adv_addr # 严格遵守 VRRP 协议 #vrrp_strict # 日志级别:0(调试)~7(紧急) vrrp_garp_interval 0 vrrp_gna_interval 0}
# VRRP 实例配置(实例名自定义,如 VI_1)vrrp_instance VIP_1 { # 角色:MASTER(主)/BACKUP(备) state MASTER # 绑定的网卡(需替换为你的网卡名,如 eth0、ens33) interface ens32 # VRRP 实例 ID(主备节点必须相同,范围 0-255) virtual_router_id 50 # 优先级(主节点要高于备节点,范围 0-254) priority 150 # 心跳检测间隔(秒) advert_int 1 # 认证配置(主备节点必须一致,防止非法节点接入) authentication { auth_type PASS auth_pass 1111 } # 虚拟 IP(VIP,可配置多个,每行一个) virtual_ipaddress { 192.168.106.100/24 dev ens32 # dev 指定网卡,/24 是子网掩码 }}2.3.2 备节点(BACKUP)配置
仅需修改 state 和 priority,其余与主节点一致:
global_defs { router_id lsb-23 vrrp_skip_check_adv_addr # vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}
vrrp_instance VIP_1 { state BACKUP interface ens32 virtual_router_id 50 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.106.100/24 dev ens32 }}2.3.3 关键参数解释
| 参数 | 作用 |
|---|---|
router_id | 节点标识,仅用于日志区分,无实际功能,建议主备节点不同(如 MASTER_100)。 |
vrrp_strict | 严格模式,禁止无效的 VRRP 数据包,防止攻击,新手必开。 |
state | 主备角色,但优先级才是决定主备的核心(优先级高的为实际主节点)。 |
interface | 绑定的网卡,必须是服务器上存在的网卡(可通过 ip addr 查看)。 |
virtual_router_id | VRRP 实例 ID,主备节点必须相同,不同实例用不同 ID(避免冲突)。 |
priority | 优先级(0-254),数值越高越优先成为主节点,主节点建议设 100,备节点 90。 |
advert_int | 心跳间隔,主节点每隔该时间发送广播包,备节点未收到则判定主节点故障。 |
authentication | 认证配置,auth_type PASS 为密码认证,auth_pass 主备必须一致(仅用于内网)。 |
virtual_ipaddress | 虚拟 IP,服务对外提供的 IP,故障时会从主节点漂移到备节点。 |
2.4 配置后验证步骤
2.4.1 启动 Keepalived
# 启动systemctl start keepalived# 设置开机自启systemctl enable keepalived# 查看状态systemctl status keepalived2.4.2 检查 VIP
主节点执行
ip addr show dev ens32
[root@lsb-23 /etc/keepalived]#ip addr show dev ens322: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:b4:f6:cd brd ff:ff:ff:ff:ff:ff inet 192.168.106.23/24 brd 192.168.106.255 scope global ens32 valid_lft forever preferred_lft forever inet 192.168.106.100/24 scope global secondary ens32 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:feb4:f6cd/64 scope link valid_lft forever preferred_lft forever,能看到 VIP(192.168.106.100)绑定在网卡上;备节点无 VIP。
2.4.3 故障切换测试
停止主节点 Keepalived,备节点会自动绑定 VIP;重启主节点后,VIP 会漂移回主节点(抢占模式,默认开启)。
# 关闭主节点systemctl stop keepalived
# 查看备用节点[root@lsb-24 /etc/keepalived]#ip addr show dev ens322: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:1a:ec:dd brd ff:ff:ff:ff:ff:ff inet 192.168.106.24/24 brd 192.168.106.255 scope global ens32 valid_lft forever preferred_lft forever inet 192.168.106.100/24 scope global secondary ens32 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe1a:ecdd/64 scope link valid_lft forever preferred_lft forever
# 恢复主节点systemctl start keepalived
# 再次查看,可以看到又切换回了主节点[root@lsb-23 /etc/keepalived]#ip addr show dev ens322: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:b4:f6:cd brd ff:ff:ff:ff:ff:ff inet 192.168.106.23/24 brd 192.168.106.255 scope global ens32 valid_lft forever preferred_lft forever inet 192.168.106.100/24 scope global secondary ens32 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:feb4:f6cd/64 scope link valid_lft forever preferred_lft forever二、keepalived脑裂问题
2.1 脑裂原因
-
backup收不到master的数据包,导致backup抢夺VIP,出现VIP争夺现象
-
master节点
keepalived服务正常但其他服务故障(如负责负载均衡的nginx故障),backup节点无法正确的接替VIP去工作
2.2 问题1解决方法
2.2.1 创建shell脚本
备节点lsb-24创建shell脚本,使用该脚本的前提是主节点需要支持免密登录
vim /etc/keepalived/check_vip.sh添加如下脚本
#!/bin/bash# 远程查看主节点lsb-23是否存在VIPMASTER_VIP=$(ssh 192.168.106.23 ip addr|grep 192.168.106.100 |wc -l)# 判断当前机器是否有VIPMY_VIP=$(ip addr|grep 192.168.106.100|wc -l)
# 如果远程有VIP并且自己本地也存在了VIP,就干掉自己if [ ${MASTER_VIP} == 1 -a ${MY_VIP} == 1 ]then systemctl stop keepalivedfi添加执行权限
chmod 755 /etc/keepalived/check_vip.sh2.2.2修改配置文件
使用vrrp_script块定义脚本、之后使用“vrrp_instance`块中引用脚本
global_defs { router_id lsb-24 vrrp_skip_check_adv_addr # vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}# 定义脚本vrrp_script check_vip { # 脚本路径 script "/etc/keepalived/check_vip.sh" # 脚本执行间隔 interval 5}
vrrp_instance VIP_1 { state BACKUP interface ens32 virtual_router_id 50 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.106.100/24 dev ens32 } # 引用脚本 track_script { check_vip }
}2.2.3 重启keepalived
重启keepalived后,查看效果,有条件可以加上邮箱提醒服务,当出现切换时邮箱提醒运维人员
2.2.4 模拟故障
# 主节点抓取报文转发过程[root@lsb-23 ~/.ssh]#tcpdump -nn -i any host 224.0.0.18tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes17:14:48.654619 IP 192.168.106.23 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 150, authtype simple, intvl 1s, length 2017:14:49.656096 IP 192.168.106.23 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 150, authtype simple, intvl 1s, length 20
# 开启防火墙,并创建规则,阻止本机发送组播报文systemctl restart firewalld[root@lsb-23 ~/.ssh]#iptables -A OUTPUT -d 224.0.0.18 -j DROP
# 再次查看发现无报文发送[root@lsb-23 ~/.ssh]#tcpdump -nn -i any host 224.0.0.18tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes^C0 packets captured0 packets received by filter0 packets dropped by kernel
# 此时查看备用节点lsb-24的keepalived服务状态
[root@lsb-24 /etc/keepalived]#systemctl status keepalived.service● keepalived.service - LVS and VRRP High Availability Monitor Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled) Active: inactive (dead)
Mar 09 17:14:57 lsb-24 Keepalived_vrrp[1707]: Sending gratuitous ARP o...Mar 09 17:14:57 lsb-24 Keepalived_vrrp[1707]: Sending gratuitous ARP o...Mar 09 17:15:01 lsb-24 Keepalived[1705]: StoppingMar 09 17:15:01 lsb-24 systemd[1]: Stopping LVS and VRRP High Ava可以发现,脚本已经执行,把自身的keepalived给关掉了
2.3 问题2解决方法
2.3.1 核心思路
- 编写 Shell 脚本,检测 Nginx 是否正常提供服务(不仅检测进程,还检测端口 / 访问状态);
- 在 Keepalived 配置中引用该脚本,设置检测频率;
- 当脚本检测到 Nginx 故障时,Keepalived 会自动降低当前节点优先级,触发 VIP 漂移到备节点。
2.3.2 编写健康检查脚本
主节点slb-23创建脚本文件 /etc/keepalived/check_nginx.sh,内容如下
#!/bin/bash# 检测 Nginx 是否存活NGINX_PID=$(ps -ef | grep nginx | grep -v grep | wc -l)
# 1. 先检测 Nginx 进程是否存在if [ $NGINX_PID -eq 0 ]; then # 进程不存在,尝试重启 Nginx systemctl start nginx sleep 3 # 重启后再次检测,仍不存在则停止 Keepalived(触发 VIP 漂移) NGINX_PID=$(ps -ef | grep nginx | grep -v grep | wc -l) if [ $NGINX_PID -eq 0 ]; then systemctl stop keepalived fifi
# 2. 进阶检测:检测 Nginx 是否能正常响应 HTTP 请求(可选,更精准)# 可替换为你的业务接口,比如 /index.htmlHTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" http://127.0.0.1:80/)if [ $HTTP_CODE -ne 200 ]; then systemctl stop keepalivedfi2.3.3 脚本权限配置
# 添加执行权限chmod +x /etc/keepalived/check_nginx.sh# 测试脚本是否能正常运行bash /etc/keepalived/check_nginx.sh2.3.4 修改 Keepalived 配置(主 / 备节点均需修改)
在原有配置基础上,添加 vrrp_script(脚本定义)和 track_script(脚本引用),完整配置如下:
2.3.4.1 主节点(MASTER)完整配置
global_defs { router_id lsb-23 vrrp_skip_check_adv_addr # vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}
# 1. 定义健康检查脚本vrrp_script check_nginx { script "/etc/keepalived/check_nginx.sh" # 脚本路径 interval 2 # 检测间隔(秒) weight -100 # 检测失败时,节点优先级降低 100 fall 3 # 连续 3 次检测失败,判定为故障 rise 2 # 连续 2 次检测成功,恢复优先级}
vrrp_instance VIP_1 { state MASTER interface ens32 virtual_router_id 50 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.106.100/24 dev ens32 } # 引用健康检查脚本 track_script { check_nginx } # 可选:抢占模式(默认开启,主节点恢复后抢回 VIP) # nopreempt # 如需关闭抢占(备节点不主动归还 VIP),取消注释}2.3.4.2 备节点(BACKUP)完整配置
仅 state 和 priority 不同,其余与主节点一致:
global_defs { router_id lsb-24 vrrp_skip_check_adv_addr # vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}
# 1. 定义健康检查脚本vrrp_script check_nginx { script "/etc/keepalived/check_nginx.sh" # 脚本路径 interval 2 # 检测间隔(秒) weight -100 # 检测失败时,节点优先级降低 100 fall 3 # 连续 3 次检测失败,判定为故障 rise 2 # 连续 2 次检测成功,恢复优先级}
vrrp_instance VIP_1 { state BACKUP interface ens32 virtual_router_id 50 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.106.100/24 dev ens32 } # 引用健康检查脚本 track_script { check_nginx } # 可选:抢占模式(默认开启,主节点恢复后抢回 VIP) # nopreempt # 如需关闭抢占(备节点不主动归还 VIP),取消注释}2.3.5 关键参数解释(新增部分)
| 参数 | 作用 |
|---|---|
vrrp_script | 定义健康检查脚本的区块,名称(如 check_nginx)自定义。 |
script | 脚本的绝对路径,必须确保 Keepalived 进程有权限执行(建议用 root)。 |
interval | 脚本执行间隔(秒),建议设 2-5 秒,过短会增加系统开销。 |
weight | 权重调整值(负数):检测失败时,节点优先级 = 原优先级 + weight(如 100-20=80),低于备节点的 90,触发漂移。 |
fall | 连续失败次数,达到该次数才判定故障(避免网络抖动误判)。 |
rise | 连续成功次数,达到该次数恢复原优先级(主节点恢复后抢回 VIP)。 |
track_script | 在 VRRP 实例中引用定义好的健康检查脚本,可引用多个(用逗号分隔)。 |
nopreempt | 非抢占模式:主节点故障恢复后,不会主动抢回 VIP,需手动切换(适合对服务稳定性要求高的场景)。 |
2.3.6 验证健康检查功能
-
重启 Keepalived
Terminal window systemctl restart keepalived -
模拟 Nginx 故障
Terminal window # 停止 Nginxsystemctl stop nginx# 等待 3*2=6 秒(fall=3 + interval=2)sleep 6# 查看 VIP 位置(备节点会绑定 VIP)ip addr[root@lsb-24 /etc/keepalived]#ip addr show ens322: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:1a:ec:dd brd ff:ff:ff:ff:ff:ffinet 192.168.106.24/24 brd 192.168.106.255 scope global ens32valid_lft forever preferred_lft foreverinet 192.168.106.100/24 scope global secondary ens32valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe1a:ecdd/64 scope linkvalid_lft forever preferred_lft forever -
恢复 Nginx
Terminal window # 启动 Nginx及keepalivedsystemctl start keepalived;systemctl start nginx# 等待 2*2=4 秒(rise=2 + interval=2)sleep 4# 主节点会抢回 VIP(默认抢占模式)ip addr[root@lsb-23 /etc/keepalived]#ip addr show ens322: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:b4:f6:cd brd ff:ff:ff:ff:ff:ffinet 192.168.106.23/24 brd 192.168.106.255 scope global ens32valid_lft forever preferred_lft foreverinet 192.168.106.100/24 scope global secondary ens32valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:feb4:f6cd/64 scope linkvalid_lft forever preferred_lft forever
2.3.7 适配其他服务(如 MySQL)
只需修改健康检查脚本即可,示例 MySQL 检测脚本:
#!/bin/bash# 检测 MySQL 是否存活(需配置免密登录)MYSQL_STATUS=$(mysql -uroot -p'你的密码' -e "select 1" 2>/dev/null | wc -l)if [ $MYSQL_STATUS -eq 0 ]; then systemctl stop keepalivedfi文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
赣公网安备36072602000131号