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