好的,Keepalived的虚拟IP(VIP)有时不显示是一个常见问题。这通常不是脚本判断方法的问题,而是Keepalived本身的工作机制或配置导致的。
以下是可能的原因和解决方案,以及如何在docheck
脚本中更可靠地判断主节点状态:
VIP有时不显示的常见原因及解决
网络接口问题
# 检查接口状态 ip link show eth0 # 重启网络(谨慎操作) systemctl restart networking
ARP协议冲突/延迟
# 清除ARP缓存 ip neigh flush all
防火墙阻止VRRP协议
# 允许VRRP协议(协议号112) iptables -A INPUT -p vrrp -j ACCEPT iptables -A OUTPUT -p vrrp -j ACCEPT
多播通信问题
# 检查多播路由 route -n | grep 224.0.0.0
更可靠的docheck脚本判断方法
既然VIP显示不稳定,建议采用以下更可靠的方法:
方法一:通过Keepalived状态文件判断(推荐)
#!/bin/bash
# Keepalived状态文件路径(默认位置)
STATE_FILE="/var/run/keepalived.state"
# 读取状态文件获取当前角色
if [ -f "$STATE_FILE" ]; then
CURRENT_STATE=$(cat "$STATE_FILE" | awk '/State/ {print $2}')
if [ "$CURRENT_STATE" = "MASTER" ]; then
echo "[$(date)] 当前节点是主节点 (MASTER)"
# 这里添加主节点的健康检查逻辑
# 示例:检查Nginx是否运行
if systemctl is-active --quiet nginx; then
exit 0 # 健康
else
exit 1 # 不健康,触发故障转移
fi
elif [ "$CURRENT_STATE" = "BACKUP" ]; then
echo "[$(date)] 当前节点是备份节点 (BACKUP)"
exit 0
else
echo "[$(date)] 未知状态: $CURRENT_STATE"
exit 1
fi
else
echo "[$(date)] 状态文件不存在: $STATE_FILE"
exit 1
fi
# DEBUG:记录执行日志(可选)
echo "[$(date)] docheck executed with state: $CURRENT_STATE" >> /var/log/keepalived-docheck.log
exit $?
方法二:结合VIP检查和进程状态的双重验证
#!/bin/bash
VIP="192.168.1.100"
INTERFACE="eth0"
# 检查1:通过ip命令查看VIP是否存在
if ip addr show dev $INTERFACE | grep -q "$VIP"; then
HAS_VIP=true
else
HAS_VIP=false
fi
# DEBUG输出到日志便于排查问题
echo "HAS_VIP=$HAS_VIP, INTERFACE=$INTERFACE, VIP=$VIP, TIME=$(date)" >> /tmp/vip_debug.log
if [ "$HAS_VIP" = true ]; then
echo "当前节点为主节点(持有VIP)"
# TODO:在此处添加主节点的服务健康检查逻辑
else
echo "当前节点为备节点(未持有VIP)"
fi
exit $?
Keepalived配置优化建议
在keepalived.conf
中添加以下配置来提高稳定性:
vrrp_instance VI_1 {
state MASTER #初始角色设为MASTER
interface eth0 #指定正确的网卡名称
# ⚠️重要:添加以下参数避免脑裂和状态抖动⚠️
#设置抢占模式为“延迟抢占”,避免频繁切换导致VIP丢失。
preempt_delay 300 #抢占延迟时间(秒)
nopreempt #非抢占模式(可选)
#调整通告间隔和超时判定阈值
advert_int 1 #通告间隔(秒)
authentication { #认证配置
auth_type PASS #认证类型
auth_pass your_password #密码至少8位且复杂一些
}
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:1
}
track_script {
chk_service #关联健康检查脚本名
}
# ⭐新增:启用状态通知并指定状态文件⭐
notify "/usr/bin/bash -c 'echo \"State \$STATE\" > /var/run/keepalived.state'"
}
VIP丢失时的排查命令
当VIP不显示时,可以使用以下命令排查:
#查看系统日志中Keepalived的相关信息:
journalctl -u keepalived --since "5 minutes ago"
#手动查看网卡上的IP地址:
ip addr show eth0
#抓包分析VRRP通告是否正常(在主备节点上分别执行):
tcpdump -i eth0 proto vrrp -n
#强制重新通知Keepalived(谨慎使用):
systemctl reload keepalived
总结建议:优先采用方法一(状态文件判断),因为它不依赖于网络层面的VIP可见性,而是直接读取Keepalived的内部状态,更加稳定可靠。同时优化Keepalived配置参数可以减少VIP丢失的发生概率。
内容由零声教学AI助手提供,问题来源于学员提问