Failover automático com Keepalived

Alta disponibilidade é um assunto sempre discutido entre as rodas de nerds e pela alta cúpula das corporações. Afinal, garantir que sua aplicação esteja disponível mesmo em caso de uma presente falha, é algo que chama muito a atenção, e claro, isso faz com que o pessoal da área estratégica e negócio das corporações fiquem fascinados e motivados a implementar essas soluções em seu ambiente de tecnologia.

Porém quando esse assunto é discutido, são envolvidas muitas teorias que fazem desse tipo de solução algo extremamente complexo ou mesmo místico, chegando beirar o nebuloso entre alguns profissionais da área.

Antes de iniciarmos a parte prática é importante entendermos que alta disponibilidade é um conceito, não um serviço, então logicamente existem dezenas de ferramentas que oferecem essa solução.

Resumindo, de forma breve, a alta disponibilidade é garantir que minha aplicação ou serviço fique no ar mesmo em caso de falha. E esse serviço ou aplicação tem um IP que é popularmente conhecido como VIP (Virtual IP), esse VIP é um endereço IP flutuante, que fica no servidor ativo, ou seja, o mestre do cluster, isso quando estamos trabalhando com o modelo failover (passivo/ativo), onde você tem um mestre e um escravo. Quando você trabalha com o modelo de balanceamento de carga, o endereço VIP, é o IP flutuante do seu servidor e/ou balanceador de carga, que tem o papel de distribuir as requisições para o pool de servidores que esta atrás dele. Caso você queira saber mais sobre alta disponibilidade, segue o link onde esse assunto foi abordado em seu conceito de forma mais extensa: Link de HA

No post de hoje não só vamos esclarecer como funciona o faliover como vamos implementá-lo na prática. Importante salientar que o keepalived também pode trabalhar em balanceamento de carga em conjunto com ipvsadm, que usa o recurso de IPVS do kernel Linux, que nada mais é que um balanceador de carga sob camada 4 do modelo OSI (Camada de transporte).

A solução open source que vamos adotar neste post como já esclarecido acima é o keepalived, uma solução extremamente eficiente e digna de respeito, apresentando-se uma alternativa a altura do “falecido” projeto heartbeat, antiga solução de failover que foi muito adotada pela comunidade open source no passado.

Obviamente existem outras soluções que atendem esse propósito e que são até mais populares que o próprio keepalived, como o Pacemaker por exemplo, porém aqui no post foquei no objetivo de exemplificar e praticar o assunto de alta disponibilidade passivo/ativo de forma simples. Obviamente uma solução como o pacemaker é excelente, e atende diversos requisitos que provavelmente o keepalived não atenda, enquanto o pacemaker é uma ferramenta completa de alta disponibilidade, focada totalmente em prover tolerância a falha e gerenciamento de cluster.

Já deu né? Agora bora por a mão na massa! Como de praxe, faremos nas duas principais famílias de distribuições Linux do mercado: Debian (8) e CentOS (7).

Primeiramente vamos definir nosso ambiente. Para esse laboratório você precisa de 2 servidores no mínimo, sendo um mestre e um escravo (independente da distro que você escolher).

Então vamos para provavelmente o passo mais importante, instalar o keepalived. O keepalived esta disponível através do repositório da distribuição, com exceção da família Red Hat, onde o mesmo esta disponível via repositório EPEL (Extras Packages Enterprise Linux), caso você use o Red Hat puro, acionar o suporte da Red Hat para habilitar o repositório correto conforme orientação do suporte da mesma.

O failover que faremos aqui será em cima do serviço nginx, apenas porque optei por fazê-lo com esse serviço, por mera conveniência, caso você opte por outro serviço em seu laboratório, não vejo problema algum.

A instalação abaixo se aplica nos dois nós do cluster, ok?

# yum install epel-release -y
# yum install keepalived nginx -y

# apt-get update
# apt-get install keepalived nginx -y

Feita a instalação precisamos ajustar o arquivo de configuração do keepalived para que o serviço tenha declarado qual o endereço IP flutuante (VIP, lembre-se desse cara!) e para saber qual seu papel dentro do cluster, além disso, nele também consta qual o serviço que ele vai monitorar, no nosso laboratório, será o nginx.

No seu servidor mestre, você irá adicionar o arquivo de configuração abaixo. Nesse arquivo consta o nome do seu script de checagem, que pode ser qualquer nome, o script propriamente dito define qual serviço ele ira verificar se esta no ar ou não, o pidof como a maioria já sabe verifica se existem processos daquele serviço pesquisado, caso exista o retorno será sempre 0, caso não encontre, o retorno é diferente de 0 e portanto o cluster promove o escravo, nomeando como mestre e adicionando o IP flutuante nele.

O failover do keepalived trabalha com o protocolo VRRP, um protocolo que trabalha em multicast, onde não é necessário informar quem é mestre e quem é escravo, porque ele vai se basear no estado (estate) que foi definido e no nome que você determinou pra instância VRRP na configuração, aqui no Lab coloquei o nome de VRRP1, porque eu quis, simples.

Outro fator importante, a interface de rede onde será configurado o IP flutuante, esse IP flutuante fica como um IP secundário, então se preocupe que ele não vai remover o IP setado nesta interface de rede. No caso do Red Hat e CentOS em suas versões recentes ele segue padrões parecidos com os BSD’s, adotando esse nome feio pras interfaces de rede, enquanto para o Debian permanece com o padrão antigo (ethX).

Na cláusula virtual_ipaddress é onde é declarado o endereço VIP (Flutuante), o IP a qual será o ponto único de acesso do cliente. E por fim temos a cláusula track_script onde você precisa chamar o vrrp_script que você definiu, onde foi passado os passos que o keepalived ira conferir se o serviço nginx esta no ar.

Por razões de segurança você pode definir critérios de segurança para o protocolo VRRP baseado em autenticação. Nesse modelo adotado estamos seguindo o modelo PASS, que basicamente transita em texto puro a senha, em produção não é recomendável, caso você queira um tipo de autenticação mais eficiente, recomendo a leitura a seguir: http://louwrentius.com/configuring-attacking-and-securing-vrrp-on-linux.html

# vim /etc/keepalived/keepalived.conf
vrrp_script linuxsysadmin {
        script "pidof nginx"
        interval 2
        weight 2
}
 
vrrp_instance VRRP1 {
    state MASTER
    interface enp0s3
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        10.100.0.135/24
    }
    track_script {
        linuxsysadmin
    }
 
}

# vim /etc/keepalived/keepalived.conf
vrrp_script linuxsysadmin {
        script "pidof nginx"
        interval 2
        weight 2
}
 
vrrp_instance VRRP1 {
    state MASTER
    interface eth0
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        10.100.0.135/24
    }
    track_script {
        linuxsysadmin
    }
 
}

No escravo configure como no modelo abaixo, basicamente idêntico ao modelo do mestre, com exceção de que o estado aqui ficado definido como BACKUP, ao invés de MASTER.

# vim /etc/keepalived/keepalived.conf
vrrp_script linuxsysadmin {
        script "pidof nginx"
        interval 2
        weight 2
}
 
vrrp_instance VRRP1 {
    state BACKUP
    interface enp0s3
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        10.100.0.135/24
    }
    track_script {
        linuxsysadmin
    }
 
}

# vim /etc/keepalived/keepalived.conf
vrrp_script linuxsysadmin {
        script "pidof nginx"
        interval 2
        weight 2
}
 
vrrp_instance VRRP1 {
    state BACKUP
    interface eth0
    virtual_router_id 100
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 9999
    }
    virtual_ipaddress {
        10.100.0.135/24
    }
    track_script {
        linuxsysadmin
    }
 
}

Antes de testar o failover, não se esqueça de incluir os serviços que serão monitorados para subirem durante o boot do sistema operacional.

# systemctl enable keepalived
# systemctl enable nginx
# systemctl start nginx

Nos servidor mestre inicie o serviço do keepalived. Aguarde alguns instantes e confira se o VIP subiu.

# systemctl start keepalived
# echo MASTER > /var/www/html/index.html
# ip addr show
ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:ae:d6:54 brd ff:ff:ff:ff:ff:ff
    inet 10.100.0.68/8 brd 10.255.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.100.0.135/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:feae:d654/64 scope link 
       valid_lft forever preferred_lft forever

# /etc/init.d/keepalived start
# echo MASTER > /var/www/html/index.html
# ip addr show
ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:ae:d6:54 brd ff:ff:ff:ff:ff:ff
    inet 10.100.0.68/8 brd 10.255.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.100.0.135/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:feae:d654/64 scope link 
       valid_lft forever preferred_lft forever

Com o mestre no ar, podemos iniciar o slave e efetuar os testes para validar a nossa alta disponibilidade.

# systemctl start keepalived
# echo SLAVE > /var/www/html/index.html

# /etc/init.d/keepalived restart
# echo SLAVE > /var/www/html/index.html

Em seguida abra seu navegador e acesse o VIP pelo seu navegador, a janela será semelhante a imagem abaixo. Você ra notar que ele esta apontando pro servidor mestre.

Agora faremos o teste propriamente dito, forçaremos o encerramento do processo do serviço nginx. Feito esse procedimento, o keepalived vai entrar no processo de eleição, onde ele precisa promover o servidor escravo (BACKUP) para mestre.

# pkill nginx

Pelos logs do keepalived também é possível acompanhar essa mudança. No serviço mestre execute o tail em messages e será possível verificar que houve falhe, e que ele passa se declarar como backup (escravo).

# tail -f /var/log/messages
Mar  9 14:59:43 master Keepalived_vrrp[5769]: VRRP_Script(linuxsysadmin) failed
Mar  9 14:59:44 master Keepalived_vrrp[5769]: VRRP_Instance(VRRP1) Received higher prio advert
Mar  9 14:59:44 master Keepalived_vrrp[5769]: VRRP_Instance(VRRP1) Entering BACKUP STATE

No servidor escravo também fica evidência de que o servidor corrente foi eleito (promovido) a mestre, devido a indisponibilidade do mestre primário.

# tail -f /var/log/messages
Mar  9 14:59:44 slave Keepalived_vrrp[5238]: VRRP_Instance(VRRP1) forcing a new MASTER election
Mar  9 14:59:45 slave Keepalived_vrrp[5238]: VRRP_Instance(VRRP1) Transition to MASTER STATE
Mar  9 14:59:46 slave Keepalived_vrrp[5238]: VRRP_Instance(VRRP1) Entering MASTER STATE

Essa eleição é feita, porque no keepalived é possível ter mais de um escravo, por isso o keepalived suporta trabalhar com níveis de prioridade, onde ele pode eleger o servidor escravo com maior prioridade.

Bem, acho que de failover é isso, e não tem muito o que falar sobre o assunto. Quem se interessou sobre o assunto, já escrevi um artigo sobre Alta Disponibilidade (Failover) com Heartbeat, dando como exemplo o Zabbix, caso tenha interesse no assunto, recomendo a leitura: http://www.linuxsysadmin.com.br/index.php/2015/08/05/zabbix-em-alta-disponibilidade-com-heartbeat/

Fico por aqui caros amigos e colegas, forte abraço e sucesso nessa empreitada!

See ya!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *