Os dois servidores executando keepalived se tornam master

2

Após uma falha de rede, ambos os servidores executando keepalived se tornam mestre.

Quando a rede é restabelecida, ambos mantêm o estado MASTER.

O que poderia estar causando isso?

Editado: Outra informação que pode ser relevante, cada servidor tem dois NICs.

Aqui está a configuração da instância virtual:

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"}
    
por pcent 21.01.2011 / 14:19

2 respostas

3

Isso pode realmente ser causado por um bug. Eu sei porque eu tive que consertar isso sozinho.

De acordo com o RFC, quando as prioridades são iguais em ambos os nós;

        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

Então, quem tiver o maior endereço IP vencerá.

Em keepalived, a maneira como isso é feito é basicamente errado. Endianness não é considerado adequadamente ao fazer esta comparação.

Vamos imaginar que temos dois roteadores, (A) 10.1.1.200 e (B) 10.1.1.201.

O código deve realizar a seguinte comparação.

Em A:

if (10.1.1.201 > 10.1.1.200) // True
   be_backup();

Em B:

if (10.1.1.200 > 10.1.1.201) // False
  be_master();

No entanto, como o endianness não é manipulado incorretamente, a seguinte comparação é feita em seu lugar.

Em A:

if (10.1.1.201 > 200.1.1.10) // False
  be_master();

Em B:

if (10.1.1.200 > 201.1.1.10) // False
  be_master();

Esse patch deve funcionar, mas eu o refiz do meu patch original e não o testou . Nem mesmo testado compila! Então não há reembolso!

--- 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) {
    
por 13.10.2013 / 19:09
0

Experimente a solução publicada aqui.

Impede que o mestre de VRRP se torne mestre uma vez que tenha falhou

    
por 21.01.2011 / 14:29

Tags