web-dev-qa-db-fra.com

keepalived ne détecte pas la perte d'IP virtuelle

J'utilise keepalived pour basculer une IP flottante entre deux machines virtuelles.

/etc/keepalived/keepalived.conf le VM 1:

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 101
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret
    }
    virtual_ipaddress {
        1.2.3.4
    }
}

/etc/keepalived/keepalived.conf le VM 2:

vrrp_instance VI_1 {
    state MASTER
    interface ens160
    virtual_router_id 101
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret
    }
    virtual_ipaddress {
        1.2.3.4
    }
}

Cela fonctionne très bien, à une exception près: chaque fois que systemd est mis à jour (il exécute Ubuntu 18.04), il recharge son composant réseau, ce qui entraîne la suppression de l'IP flottante car elle n'est pas configurée dans le système. Étant donné que les deux instances keepalived peuvent toujours se cingler, aucune d'entre elles ne voit quoi que ce soit de mal et aucune ne réagit à ce sujet, ce qui entraîne la baisse de l'IP flottante.

J'ai trouvé que vous pouvez vérifier l'IP avec un script simple comme celui-ci:

vrrp_script chk_proxyip {
    script "/sbin/ip addr |/bin/grep 1.2.3.4"
}

vrrp_instance VI_1 {
    # [...]
    track_script {
        chk_proxyip
    }
}

Mais je ne sais pas s'il s'agit d'une approche de travail.

Si je le comprends correctement, les événements suivants se produiraient, si je configure ce script sur VM1:

  1. VM1 perd l'IP en raison d'un redémarrage de systemd
  2. keepalived sur VM1 détecte la perte de l'adresse IP
  3. keepalived passe à l'état FAULT et arrête la diffusion des packages vrrp
  4. keepalived sur VM2 détecte la perte de keepalived sur VM1 et met en place l'IP flottante

À ce stade, l'IP fonctionne à nouveau sur VM2, mais VM1 reste dans cet état car l'IP ne revient plus jamais sur VM1. Si VM2 tombe en panne (pour une raison quelconque), VM1 ne prendrait pas le relais, car il est toujours dans l'état FAULT.

Comment puis-je m'assurer que l'IP flottante est toujours active sur l'une des machines virtuelles?

Tests supplémentaires:

J'ai essayé d'envoyer une requête ping à l'IP flottante au lieu de vérifier si elle est active sur un hôte spécifique dans un check_script:

vrrp_script chk_proxyip {
    script "/bin/ping -c 1 -w 1 1.2.3.4"
    interval 2
}

La configuration de ce script sur le nœud 2 a donné les résultats suivants:

  1. supprimé l'adresse IP sur le nœud 1 pour les tests
  2. le nœud 2 a détecté la perte IP et est passé de BACKUP à FAULT
  3. le noeud 1 a ignoré le changement d'état et est resté MASTER

Le résultat: l'IP est resté bas.

La configuration du script sur le nœud 1 a donné les résultats suivants:

  1. supprimé l'adresse IP sur le nœud 1
  2. le nœud 1 a détecté la perte IP et est passé de MASTER à FAULT
  3. le nœud 2 a détecté le changement d'état sur le nœud 1 et est passé de BACKUP à MASTER, configurant l'IP flottante sur le nœud 2

Et puis ...

Feb 13 10:11:26 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 13 10:11:27 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 13 10:11:29 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100
Feb 13 10:11:29 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE
Feb 13 10:11:32 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 13 10:11:33 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 13 10:11:36 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100
Feb 13 10:11:36 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE
Feb 13 10:11:38 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 13 10:11:39 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 13 10:11:41 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100
Feb 13 10:11:41 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE
Feb 13 10:11:44 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE
Feb 13 10:11:45 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 13 10:11:47 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100
...

J'ai dû redémarrer keepalived sur node1 pour arrêter le jeu de ping-pong entre les nœuds.

8
Gerald Schneider

Nous avons rencontré ce problème et décidé qu'il s'agissait d'un problème avec systemd-networkd dans ubuntu 18.04 utilisant maintenant netplan. Une version plus récente de keepalived devrait résoudre ce problème car elle peut détecter la suppression de l'IP flottante qui provoque un basculement, voir https://github.com/acassen/keepalived/issues/836 .

La nouvelle version de keepalived n'est pas disponible en 18.04, et plutôt que d'essayer de rétroporter, nous avons décidé de rester sur Ubuntu 16.04 et d'attendre jusqu'à Ubuntu 20.04 pour nos serveurs qui utilisent Keepalived.

7
mp3foley

Ce problème est résolu dans keepalived 2.0.0 à partir du 2018-05-26, voir changelog of keepalived

  • Surveillez la suppression VIP/eVIP et la transition vers la sauvegarde si un VIP/eVIP est supprimé, à moins qu'il ne soit configuré avec l'option no-track.
5
teissler

Je pense que votre approche générale est bonne, mais que vous devez repenser votre condition de test. La condition qui vous préoccupe est de savoir si systemd redémarre le réseau infra (la conséquence indirecte de cela étant, que votre VIP est en place), c'est ce que vous devez vérifier pour.

Je n'ai pas de système sur lequel je puisse facilement tester pendant que je tape ceci, donc YMMV, cependant systemctl is-active network.service peut suffire à couvrir cela. A défaut de vérifier l'état de systemctl show network.service | grep 'ActiveState' pour un état autre que "actif" devrait le faire.

Soit dit en passant, l'un de vos nœuds ne doit-il pas être configuré avec l'état "BACKUP", plutôt que les deux en tant que "MASTER"?

0
clockworknet

Comme solution de contournement, j'ai configuré l'IP flottante en tant qu'IP supplémentaire sur le nœud principal (avec la priorité la plus élevée)

/etc/netplan/01-netcfg.yaml:

network:
  version: 2
  renderer: networkd
  ethernets:
    ens160:
      addresses: [ 1.2.3.5/24, 1.2.3.4/24 ]
      gateway4: 1.2.3.254
      nameservers:
          search: [ example.com ]
          addresses:
              - "1.2.3.40"

De cette façon, au démarrage ou lors de la reconfiguration de systemd, l'IP flottante se trouve sur le nœud principal. En cas d'échec, il est repris par le nœud secondaire via keepalived. Si le nœud principal revient, l'IP est libérée par keepalived sur le nœud secondaire.

Ce n'est pas vraiment une solution, mais actuellement je ne vois rien de mieux.


Mise à jour

Bien que cette solution de contournement ait fonctionné, elle a eu certains effets secondaires. Après un redémarrage, l'adresse IP flottante existait deux fois sur l'interface:

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:50:56:a3:d7:d1 brd ff:ff:ff:ff:ff:ff
    inet 1.2.3.5/24 brd 1.2.3.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet 1.2.3.4/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet 1.2.3.4/24 brd 1.2.3.255 scope global secondary ens160
       valid_lft forever preferred_lft forever

Cela ne semblait rien affecter, cela a fonctionné, mais cela m'a dérangé. À la fin, j'ai abouti à la réponse de mp3foley et réinstallé les machines virtuelles avec Ubuntu 16.04.

0
Gerald Schneider

Je pense que vous pouvez faire une vérification ping sur l'IP flottante, puis en cas d'échec, redémarrez le service keepalived sur tous les nœuds

Vous êtes de retour sur IP

Mettez cela dans un cronjob qui s'exécute toutes les minutes ou 5 minutes

0
Mark