网络故障后,运行 keepalived 的两台服务器都成为主服务器。
当网络重新建立时,两者都保持MASTER状态。
这可能是什么原因造成的?
编辑:另一个可能相关的信息是,每台服务器都有两个 NIC。
以下是虚拟实例配置:
vrrp_instance VGAPP {
interface eth0
virtual_router_id 61
state BACKUP
nopreempt
priority 50
advert_int 3
virtual_ipaddress {
10.26.57.61/24
}
track_interface {
eth0
}
track_script {
jboss_check
#tomcat_check
#interface_check
#interface_check02
}
notify_master "/opt/keepalived/scripts/set_state.sh MASTER"
notify_backup "/opt/keepalived/scripts/set_state.sh BACKUP"
notify_fault "/opt/keepalived/scripts/set_state.sh FAULT"
notify_stop "/opt/keepalived/scripts/set_state.sh STOPPED"}
答案1
这实际上可能是由错误引起的。我知道,因为我必须自己修复它。
根据 RFC,当两个节点上的优先级相等时;
If the Priority in the ADVERTISEMENT is equal to the local Priority and the primary IP Address of the sender is greater than the local primary IP Address, then: o Cancel Adver_Timer o Set Master_Down_Timer to Master_Down_Interval o Transition to the {Backup} state
因此,拥有最大 IP 地址的人将获胜。
在 keepalived 中,这种做法基本上是错误的。在进行这种比较时,字节序没有得到适当考虑。
假设我们有两个路由器,(A)10.1.1.200 和(B)10.1.1.201。
代码应该进行以下比较。
在 A:
if (10.1.1.201 > 10.1.1.200) // True
be_backup();
在 B 上:
if (10.1.1.200 > 10.1.1.201) // False
be_master();
但是由于字节顺序没有被错误处理,因此进行了以下比较。
在 A:
if (10.1.1.201 > 200.1.1.10) // False
be_master();
在 B 上:
if (10.1.1.200 > 201.1.1.10) // False
be_master();
此补丁应该可以,但我从原来的补丁重新制作了它,并且不是测试过了。甚至没有测试过编译!所以不退款!
--- vrrp/vrrp.c.old 2013-10-13 17:39:29.421000176 +0100
+++ vrrp/vrrp.c 2013-10-13 18:07:57.360000966 +0100
@@ -923,7 +923,7 @@
} else if (vrrp->family == AF_INET) {
if (hd->priority > vrrp->effective_priority ||
(hd->priority == vrrp->effective_priority &&
- ntohl(saddr) > ntohl(VRRP_PKT_SADDR(vrrp)))) {
+ ntohl(saddr) > VRRP_PKT_SADDR(vrrp))) {
log_message(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
, vrrp->iname);
if (proto == IPPROTO_IPSEC_AH) {
答案2
尝试此处发布的解决方案。