因此,我在两台服务器上运行 keepalived,但无法让它故障转移到另一台服务器。
下面是我对其中一台服务器的配置。两者之间唯一的不同是优先级数字 master 为 110,back 为 109。
但是当我使用 /etc/init.d/process stop 停止我的进程时,keepalived 不会发生故障转移。我只得到 VRRP_Script(chk_script) 失败的信息,没有其他信息。没有故障转移,什么都没有。
vrrp_script chk_script {
script "/usr/local/bin/failover.sh"
interval 2
weight 2
}
vrrp_instance HAInstance {
state BACKUP
interface eth0
virtual_router_id 8
priority 109
advert_int 1
nopreempt
vrrp_unicast_bind 10.10.10.8
vrrp_unicast_peer 10.10.10.9
virtual_ipaddress {
10.10.10.10/16 dev eth0
}
notify /usr/local/bin/keepalivednotify.sh
track_script {
chk_script weight 20
}
}
下面是我的 chk_script。当我使用 killall -0 process 作为脚本时,也会出现同样的问题。
!/bin/bash
SERVICE='process'
STATUS=$(ps ax | grep -v grep | grep $SERVICE)
if [ "$STATUS" != "" ]
then
exit 0
else
exit 1
fi
有人知道如何修复这个问题吗?谢谢。
答案1
我遇到了完全相同的问题,但是问题既不在于防火墙,也不在于以太网适配器,而在于检查脚本的“权重”设置。
这是我的配置:
掌握:
vrrp_instance haproxy {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
备份:
vrrp_instance haproxy {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
检查脚本:
vrrp_script chk_haproxy {
script "python /root/ha_check.py"
interval 2 # check every 2 seconds
weight 2
rise 2
fall 2
}
主服务器拒绝释放 VIP 的原因是,尽管脚本失败了,但主服务器的优先级仍然高于备份服务器。发生这种情况是因为 check_script 上的“权重”设置不足以弥补优先级之间的“差距”,这意味着将备份服务器的优先级提升到高于主服务器的优先级。我将进一步解释:
根据keepalived手册,“权重”设置中的正数表示如果检查成功,则将该数字添加到优先级中。如果
检查失败,则负数表示从优先级中减去该数字。
因此,根据我的配置:
服务器优先级脚本先前失败:
主服务器:152
备份服务器:100
故障转移 IP:主服务器
主服务器正确“获取”故障转移 IP,因为主服务器与备份服务器相比具有更高的优先级(152 > 100)
脚本失败后的服务器优先级:
主服务器:148
备份服务器:102
故障转移 IP:仍在主服务器上
故障转移 IP 仍在主服务器上,因为主服务器与备份服务器相比具有更高的优先级 (148 > 102)。主服务器拒绝释放 IP,这是正确的,因为它的优先级高于其他服务器。
针对我的情况的解决方案是:
解决方案 -1:更改两个服务器的优先级编号,以便它们不会有太多的“差距”。
例如:
主优先级:150
备份优先级:149
Check_script 权重:原样(2)。
使用上述配置,当脚本成功执行(意味着一切正常)时,优先级将是:
主服务器:152
备份服务器:149
IP_Location:在主服务器上(152 > 149)
当脚本失败时:
主服务器:150
备份服务器:151
IP_Location:备份服务器(151 > 150)
解决方案 - 2:将脚本的权重数从 2 更改为 -60
答案2
我遇到过同样的问题 - 两台 CentOS 7.1 服务器都带有 track_script,如果 MASTER 上的 vrrp_script 失败,则只会导致一条日志消息“VRRP_Script(chk_script) 失败”,而不会导致故障转移。但是,在 BACKUP 服务器上,只要 MASTER 服务器上的 track_script 失败,我就会收到大量 keepalived 尝试接管虚拟 IP 的消息。
我的解决方案:MASTER 服务器上的防火墙(iptables)未正确配置以允许 VRRP 数据包/多播数据包,而同时另一台服务器 BACKUP 上的防火墙配置正确。
我在两个服务器中输入了相同的 iptables 规则,如下所示:
iptables -A INPUT -i eth0 -d 224.0.0.0/8 -j ACCEPT
iptables -A INPUT -p vrrp -i eth0 -j ACCEPT
这在其中一台服务器(BACKUP VRRP 服务器)上有效,但在 MASTER 服务器上无效,因为我忘记了 MASTER 服务器上的接口不是名为“eth0”,因此这两条规则根本没有效果。
这解释了我观察到的行为:
如果 keepalived 无法看到某个 virtual_router_id 的任何其他 VRRP 发言人,它仍然认为自己是优先级最高的发言人(因此是合法的 MASTER),即使在负权重修改之后也是如此,因为它从未收到优先级高于其自身的 VRRP 消息(因为其他发言人的广告被防火墙阻止,并且永远无法到达 keepalived 进程以使其知道它们)。这就是为什么您看不到它释放 VIP 的原因。
但是,备份服务器能够看到(现已失败的)主服务器的广告,发现这些数据包中的优先级降低到低于其自身的值,并继续宣布自己是主服务器,并发送免费的 ARP 来索取 VIP。因此,我们最终处于这样一种境地:两台服务器都认为它们需要以主服务器的身份为 VIP 提供服务。
结论:总是如果遇到奇怪的行为(无故障转移,多个 MASTER),请检查所有 VRRP 扬声器上的防火墙配置。Keepalived 日志记录并没有它应有的那么有用(在“VRRP_Script(chk_script) 失败”行之后,出现一条简单的消息“VIP 未发布,因为我仍然是最高优先级”,这将极大地简化故障排除。
- track_script 不是开/关类型的开关(“如果脚本 OK:有资格参加 VIP 选举;如果脚本 NO:完全没有资格参加 VIP 选举”) - 它只是增加/减少赢得选举的可能性,并且如果 keepalived 只将自己视为仅有的VRRP 发言人永远不会收到其他发言人的任何消息,实际上并没有太多的选举 - 你总是获胜。
答案3
我刚刚遇到了和你一样的情况,并对 keepalived 做了一些研究。让我们想想每台服务器发生了什么。假设你想实现手动故障回复架构,
在第一个备份节点上
每次 track_script 失败时落下向第二个 BACKUP 节点发送广告的次数。这里的重点是优先事项设置在广告中。对于你的情况,
129(109 + 20)
被发送到第二个BACKUP服务器。
在第二台备份服务器上
接下来是第二个BACKUP节点。
根据请求函数,
If the Priority in the ADVERTISEMENT is Zero, then:
o Set the Master_Down_Timer to Skew_Time
else:
If Preempt_Mode is False, or If the Priority in the
ADVERTISEMENT is greater than or equal to the local
Priority, then:
o Reset the Master_Down_Timer to Master_Down_Interval
else:
o Discard the ADVERTISEMENT
endif
endif
因为,你有不抢占启用并接收更高优先级的 vrrp,第二个 BACKUP 节点不会进入状态转换阶段。
解决方案
因此,如果你想让状态转换发生在第二个节点上,你可以
放重量到0在第一个备份节点上。这将发送优先级0向第二个 BACKUP 节点发布广告。文档详细描述了有关权重0的信息。
关闭不抢占在第二个备份节点上。
将体重至少设置为-2在第一个备份节点上。