Estou usando keepalived para alternar um IP flutuante entre duas VMs.
/etc/keepalived/keepalived.conf
na 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
na 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
}
}
Isso basicamente funciona bem, com uma exceção: toda vez que o systemd é atualizado (está executando o Ubuntu 18.04), ele recarrega seu componente de rede, resultando na queda do IP flutuante porque não está configurado no sistema. Como ambas as instâncias keepalived ainda podem fazer ping uma na outra, nenhuma delas vê nada de errado e nenhuma delas reage a isso, resultando na permanência do IP flutuante.
Descobri que você pode verificar o IP com um script simples como este:
vrrp_script chk_proxyip {
script "/sbin/ip addr |/bin/grep 1.2.3.4"
}
vrrp_instance VI_1 {
# [...]
track_script {
chk_proxyip
}
}
Mas não tenho certeza se esta é uma abordagem de trabalho.
Se eu entendi corretamente, aconteceria o seguinte, se eu configurar este script na VM1:
- VM1 perde o IP devido a uma reinicialização do systemd
- keepalived na VM1 detecta a perda do IP
- keepalived muda para o
FAULT
estado e para de transmitir pacotes vrrp - keepalived na VM2 detecta a perda de keepalived na VM1 e coloca o IP flutuante
Neste ponto, o IP está funcionando novamente na VM2, mas a VM1 permaneceria nesse estado porque o IP nunca mais aparece na VM1. Se a VM2 ficar inativa (por qualquer motivo), a VM1 não a assumirá, porque ainda está em FAULT
estado.
Como posso garantir que o IP flutuante esteja sempre ativo em uma das VMs?
Testes adicionais:
Eu tentei pingar o IP flutuante em vez de verificar se ele está ativo em um host específico em um check_script:
vrrp_script chk_proxyip {
script "/bin/ping -c 1 -w 1 1.2.3.4"
interval 2
}
A configuração desse script no nó 2 resultou no seguinte:
- removeu o IP no nó 1 para teste
- o nó 2 detectou a perda de IP e mudou de
BACKUP
paraFAULT
- o nó 1 ignorou a mudança de estado e permaneceu
MASTER
O resultado: o IP ficou inativo.
A configuração do script no nó 1 resultou no seguinte:
- removeu o IP no nó 1
- o nó 1 detectou a perda de IP e mudou de
MASTER
paraFAULT
- o nó 2 detectou a mudança de estado no nó 1 e mudou de
BACKUP
paraMASTER
, configurando o IP flutuante no nó 2
Bem, e então...
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
...
Eu tive que reiniciar o keepalived no node1 para parar o jogo de pingue-pongue entre os nós.
Experimentamos esse problema e decidimos que é um problema com o systemd-networkd no Ubuntu 18.04 agora usando o netplan. Uma versão mais recente do keepalived deve corrigir isso, pois pode detectar a remoção do IP flutuante que causa um failover, consulte https://github.com/acassen/keepalived/issues/836 .
A versão mais recente do keepalived não está disponível em 18.04 e, em vez de tentar fazer backport, decidimos permanecer no Ubuntu 16.04 e esperar até o Ubuntu 20.04 para nossos servidores que usam keepalived.
Este problema foi corrigido no keepalived 2.0.0 de 2018-05-26, veja o changelog do keepalived
Eu acho que você pode fazer uma verificação de ping no ip flutuante e, quando falhar, reinicie o serviço keepalived em todos os nós
Seu ip voltará
Coloque isso em um cronjob que é executado a cada minuto ou 5 minutos
Eu acho que sua abordagem geral é boa, mas você precisa repensar sua condição de teste. A condição com a qual você está preocupado é se o systemd está reiniciando a infra da rede (a consequência indireta disso, se o seu VIP está ou não ativo), então é isso que você precisa verificar.
Eu não tenho um sistema que eu possa testar facilmente enquanto digito isso, então YMMV, no entanto,
systemctl is-active network.service
pode ser suficiente para cobrir isso. Deixar de verificar o estado desystemctl show network.service | grep 'ActiveState'
um estado diferente de 'ativo' deve fazê-lo.Como um aparte, um de seus nós não deve ser configurado com o estado 'BACKUP', em vez de ambos como 'MASTER'?
Como solução, configurei o IP flutuante como um IP adicional no nó primário (com a prioridade mais alta)
/etc/netplan/01-netcfg.yaml :
Dessa forma, ao inicializar ou reconfigurar o sistema, o IP flutuante está no nó primário. Caso falhe, ele é assumido pelo nó secundário via keepalived. Caso o nó primário retorne, o IP é liberado por keepalived no nó secundário.
Não é realmente uma solução, mas atualmente não vejo nada melhor.
Atualizar
Embora essa solução alternativa tenha funcionado, teve alguns efeitos colaterais. Após uma reinicialização, o endereço IP flutuante existia duas vezes na interface:
Isso não pareceu afetar nada, funcionou, mas me incomodou. No final , obtive a resposta do mp3foley e reinstalei as VMs com o Ubuntu 16.04.