运行keepalived的两台服务器都成为主设备

networking故障后,两台运行keepalived的服务器成为主服务器。

当networking重新build立时,都保持MASTER状态。

什么可能导致它?

编辑:另一个可能相关的信息,每个服务器有两个网卡。

这是虚拟实例configuration:

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"} 

这实际上可能会导致一个错误。 我知道,因为我必须自己修复它。

根据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(); 

这个补丁应该可以工作,但是我已经从原来的补丁重新创build了,并没有testing过。 甚至没有testing它编译! 所以没有退款!

 --- 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) { 

试试这里发布的解决scheme。

一旦失败,防止VRRP Master成为Master