ZBLOG

keepalived的虚拟IP有时不显示

好的,Keepalived的虚拟IP(VIP)有时不显示是一个常见问题。这通常不是脚本判断方法的问题,而是Keepalived本身的工作机制或配置导致的。

以下是可能的原因和解决方案,以及如何在docheck脚本中更可靠地判断主节点状态:

VIP有时不显示的常见原因及解决

  1. 网络接口问题

    # 检查接口状态
    ip link show eth0
    # 重启网络(谨慎操作)
    systemctl restart networking
    
  2. ARP协议冲突/延迟

    # 清除ARP缓存
    ip neigh flush all
    
  3. 防火墙阻止VRRP协议

    # 允许VRRP协议(协议号112)
    iptables -A INPUT -p vrrp -j ACCEPT
    iptables -A OUTPUT -p vrrp -j ACCEPT
    
  4. 多播通信问题

    # 检查多播路由
    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助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=8446

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?