Alta Disponibilidade (HA) com Debian (Heartbeat + DRBD + Mon)
Observações:
- Iremos levar em consideração que você possui uma instalação “limpa” do S.O. Debian GNU/Linux.
- Os serviços que estão sendo usandos na solução também devem estar devidamente configurados e em operação.
- Todos os passos a seguir deverão ser realizados em ambas as máquinas para que o HA funcione corretamente.
Ambiente
Máquina Master
- SO: Debian GNU/Linux
- Kernel: 2.6.25-2-686
- Eth0: 172.16.1.241 (HA)
- Eth1: 192.168.1.240 (Lan)
- Eth2: 200.1.1.240 (Wan)
- Serviços: Apache2, Postfix, Heartbeat, DRBD, Mon
Máquina Slave
- SO: Debian GNU/Linux
- Kernel: 2.6.25-2-686
- Eth0: 172.16.1.242 (HA)
- Eth1: 192.168.1.240 (Lan)
- Eth2: 200.1.1.240 (Wan)
- Serviços: Apache2, Postfix, Heartbeat, DRBD, Mon
Heartbeat
Instalação
Primeiramente instale o pacote do heartbeat (versão2).
root@debian:~# aptitude install heartbeat-2
Em seguida, precisamos copiar os arquivos necessários para a configuração do mesmo da área de documentação do heartbeat já que no Debian esses arquivos não vem no diretório de config por padrão.
root@debian:~# cd /usr/share/doc/heartbeat-2 root@debian:/usr/share/doc/heartbeat-2# cp authkeys ha.cf.gz haresources.gz /etc/ha.d root@debian:/usr/share/doc/heartbeat-2# cd /etc/ha.d root@debian:/etc/ha.d# gunzip ha.cf.gz haresources.gz
Configuração
Em seguida, vamos configurar os arquivos.
O primeiro arquivo que iremos configurar é o authkeys, que cuida da autenticação entre os dois nodos.
root@debian:/etc/ha.d# vi authkeys auth 3 #1 crc #2 sha1 HI! 3 md5 sua_senha
Precisamos configurar as permissões do arquivo authkeys. Para isso, execute:
root@debian:/etc/ha.d# chmod 600 authkeys
Em seguida configure o arquivo principal do serviço, o ha.cf.
root@debian:/etc/ha.d# vi ha.cf logfile /var/log/ha-log logfacility local0 keepalive 2 deadtime 10 warntime 5 initdead 20 udpport 694 bcast eth0 auto_failback off node master node slave
E por fim, o arquivo haresources que gerencia os daemons de responsabilidade do heartbeat.
root@debian:/etc/ha.d# vi haresources master \ IPaddr2::192.168.1.240/24/eth1/192.168.1.255 \ IPaddr2::200.1.1.240/24/eth2/200.1.1.255 \ apache2
NOTA: Se for utilizar IP virtual, retire as entradas IPaddr2:: do arquivo haresources.
IMPORTANTE: É necessário desabilitar da inicialização os serviços declarado no arquivo haresources, pois quem irá levantá-los será o serviço heartbeat.
Para desativar os serviços, execute:
root@debian:~# cd /etc/rc2.d root@debian:/etc/rc2.d# mv S91apache2 K91apache2
Além disso, é preciso desabilitar o carregamento da placa de rede eth1 e eth2 nos dois nodos, já que a mesma também será carregada pelo heartbeat. Isso é realizado no arquivo /etc/network/interfaces.
Depois de tudo configurado, reinicie ambas as máquinas para que possamos testar o heartbeat, porém, reinicie primeiro a máquina master e depois a slave.
DRBD
Pré-requisitos do sistema
No caso do DRBD, iremos compilá-lo. Com isso, iremos preparar o sistema com os pacotes necessários para que possamos continuar.
Primeiramente iremos instalar o kernel-headers e kernel-source, necessários para a compilação do DRBD.
root@debian:~# aptitude install linux-headers-2.6.25-2-686 linux-source-2.6.25
Em seguida desempacote o kernel-source.
root@debian:~# cd /usr/src root@debian:/usr/src# tar xjvf linux-source-2.6.25.tar.bz2
Agora vamos instalar os pacotes adicionar, necessários para a compilação.
root@debian:~# aptitude install gcc g++ make kernel-package dpkg-dev gettext flex
Compilando ...
Primeiramente vamos realizar o download do DRBD e desempacotá-lo.
root@debian:~# cd /usr/src root@debian:/usr/src# wget -c http://oss.linbit.com/drbd/8.2/drbd-8.2.6.tar.gz root@debian:/usr/src# tar xzvf drbd-8.2.6.tar.gz
Em seguida vamos preparar o kernel para que a compilação seja realizada.
root@debian:/usr/src# cd linux-source-2.6.25 root@debian:/usr/src/linux-source-2.6.25# make mrproper root@debian:/usr/src/linux-source-2.6.25# cp /boot/config-2.6.25-2-686 .config root@debian:/usr/src/linux-source-2.6.25# make modules_prepare root@debian:/usr/src/linux-source-2.6.25# cd ..
Agora vamos compilar o DRBD.
root@debian:/usr/src# cd drbd-8.2.6/drbd root@debian:/usr/src/drbd-8.2.6/drbd# make clean all root@debian:/usr/src/drbd-8.2.6/drbd# make clean root@debian:/usr/src/drbd-8.2.6/drbd# make KDIR=/usr/src/linux-source-2.6.25/ root@debian:/usr/src/drbd-8.2.6/drbd# cd .. root@debian:/usr/src/drbd-8.2.6# make tools root@debian:/usr/src/drbd-8.2.6# make install root@debian:/usr/src/drbd-8.2.6# make install-tools root@debian:/usr/src/drbd-8.2.6# make all install
E por fim, carregue o módulo do DRBD.
root@debian:/usr/src# modprobe drbd
Configuração
Primeiramente precisamos configurar os nomes das máquinas utilizadas.
root@debian:~# vi /etc/hosts 127.0.0.1 localhost 172.16.1.241 master 172.16.1.242 slave
IMPORTANTE: Antes de continuarmos, precisamos parar o DRBD para configurá-lo e criar os recursos isoladamente na máquinas, evitando a sincronização imediata dos mesmos, já que a sincronização deverá ser iniciada somente após a sua configuração e após os recursos estiverem devidamente formatados.
root@debian:~# /etc/init.d/drbd stop
Em seguida vamos configurar o DRBD.
root@debian:~# vi /etc/drbd.conf resource nome_do_recurso { protocol C; disk { on-io-error detach; } net { timeout 60; connect-int 10; ping-int 10; } syncer { rate 100M; #group 1; } on master { device /dev/drbd2; disk /dev/md2; address 172.16.1.241:7788; meta-disk internal; } on slave { device /dev/drbd2; disk /dev/md2; address 172.16.1.242:7788; meta-disk internal; } }
OBSEVAÇÃO: Não esqueça de comentar a linha referente a montagem do device /dev/md2 no /etc/fstab, lembrando que esse device está sendo utilizado em nosso exemplo, podendo variar em outras instalações.
A seguir iremos criar o recurso DRBD (nome_do_recurso) e ativar e formatar o device (/dev/drbd2).
root@debian:~# dd if=/dev/zero bs=1M count=1 of=/dev/md2 root@debian:~# sync root@debian:~# modprobe drbd root@debian:~# drbdadm create-md nome_do_recurso root@debian:~# drbdadm up all root@debian:~# drbdadm -- -o primary nome_do_recurso root@debian:~# mkfs.xfs /dev/drbd2
E por fim, iremos inicializar o serviço DRBD.
IMPORTANTE: O serviço só deverá ser iniciado se todos os passos anteriores estiverem sido executados nas duas máquina.
root@debian:~# /etc/init.d/drbd start
Com isso, o DRBD já está ativo, funcionando e já deve estar sincronizando os dados. Para verificar a sincronização, execute:
root@debian:~# watch -n1 cat /proc/drbd version: 8.2.6 (api:88/proto:86-88) GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by root@master, 2008-08-20 13:29:43 2: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r--- ns:1138640 nr:0 dw:0 dr:1146720 al:0 bm:70 lo:1 pe:5 ua:253 ap:0 oos:967033512 [.>...................] sync'ed: 1.2% (944168/945480)M finish: 15:37:02 speed: 16,960 (11,272) K/sec
Para finalizar, precisamos configurar o DRBD para ser carregado na inicialização do sistema.
root@debian~# cd /etc/rc2.d root@debian~# ln -s ../init.d/drbd S20drbd
IMPORTANTE: O device só deverá ser montado após o processo de sincronização ter sido concluído por completo.
Problemas Conhecidos
Split-Brain
Este problema ocorre quando ambas as máquinas são carregadas de maneira isolada, não havendo conectividade entre os recursos. Com isso, as máquinas não conseguem conectar os devices ao recursos sincronizador.
Para solucionar esse problema, é necessário limpar os dados de conexão do recurso em um dos nós.
Na máquina slave, execute:
root@debian-slave:~# drbdadm secondary nome_do_recurso root@debian-slave:~# drbdadm -- --discard-my-data connect nome_do_recurso
Explicando: O primeiro comando irá tranformar o recurso em secundário, em seguida, você descarta os dados de conexão do recurso.
Na máquina master, execute:
root@debian-master:~# /etc/init.d/drbd stop root@debian-master:~# /etc/init.d/drbd start root@debian-master:~# drbdadm primary nome_do_recurso
ADD-ON
Para um melhor gerenciamento do sistema DRBD, em relação a montagem do volume nas duas máquinas, nós criamos um script que irá gerenciar a montagem dos devices, onde o mesmo será gerenciado pelo heartbeat.
Esse script será utilizado para tranformar o nodo que está em operação em primário além de montar, no nosso exemplo, o /dev/drbd2. Quando o nodo que está em operação cair, o outro nodo assume. Nesse caso, o heartbeat irá utilizar esse script para tranformar esse nodo em secundário no DRBD e desmontar o device. Com isso, o nodo que assumiu faz o processo inverso, tranformado o DRBD em primário e montando o device.
Vamos ao script:
root@debian:~# vi /etc/init.d/drbd.ha #!/bin/bash # DRBDADM="/sbin/drbdadm" MODPROBE="/sbin/modprobe" RMMOD="/sbin/rmmod" MOUNT="/bin/mount" UMOUNT="/bin/umount" case "$1" in start) echo -n "Starting all DRBD devices: " $DRBDADM primary all $MOUNT /dev/drbd2 /srv echo "Done." ;; stop) echo -n "Stopping all DRBD devices: " $UMOUNT /dev/drbd2 $DRBDADM secondary all echo "Done." ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac exit 0
Não esqueça de dar permissão de execução ao script …
root@debian:~# chmod +x /etc/init.d/drbd.ha
E de incluir a chamada do mesmo no arquvo do heartbeat.
root@debian:/etc/ha.d# vi haresources master \ IPaddr2::192.168.1.240/24/eth0/192.168.1.255 \ apache2 drbd.ha
Finalizado, reinicie o serviço heartbear.
root@debian:~# /etc/init.d/heartbeat stop root@debian:~# /etc/init.d/heartbeat start
NOTA: Isso poderá fazer com que a máquina slave assuma a master, pois vc está paralizando o heartbeat.
Mon
O mon será utilizado para monitorar os serviços locais da máquina e executar uma tarefa caso ocorra algum problema com o serviço monitorado.
No nosso exemplo, usaremos ele para monitorar o apache e caso o mesmo tenha problemas de requisição, o mon irá derrubar o heartbeat forçando assim a máquina slave a assumir os serviços.
OBSERVAÇÃO: O mon tem opções para enviar e-mail de alerta caso ocorra algum problema. Para isso, você poderá configurar um servidor de e-mail na máquina para enviar e-mails de alerta. Em nosso servidor, utilizamos o Postfix com Host Relay.
Instalação
Aqui, iremos apenas instalar o pacote.
root@debian:~# aptitude install mon
Configuração
Primeiramente, configure o arquivo principal do mon.
root@debian:~# vi /etc/mon/mon.cf alertdir = /usr/lib/mon/alert.d mondir = /usr/lib/mon/mon.d maxprocs = 20 histlength = 100 randstart = 60s hostgroup www localhost watch www service http interval 10s monitor http.monitor allow_empty_group period wd {Sun-Sat} alert heartbeat.alert alert mail.alert -S "web server is down" root@localhost upalert mail.alert -S "web server is up" root@localhost alertevery 1m
Essa configuração irá monitorar o processo do apache da seguinte maneira: ele irá verificar de 10 em 10 segundos (interval) se o apache está respondendo. Caso o mesmo apresenta falha de conexão na máquina local, ele irá executar o script heartbeat.alert, responsável pela paralização do heartbeat, obrigando assim a máquina slave assumir e irá disparar um e-mail através do script mail.alert com o assunto explicito em -S ASSUNTO para root@localhost.
O arquivo heartbeat.alert poderá ser baixado aqui, já que o mesmo não vem instalado por default.
Com isso, podemos iniciá-lo.
root@debian:~# /etc/init.d/mon stop root@debian:~# /etc/init.d/mon start
Ajustes de SUDO
Em nossos testes, detectamos que o daemon do mon é executado no sistema com o usuário daemon. Isso nos gerou um problema pois esse usuário não tem permissões para derrubar o heartbeat quando o apache cai.
Para solucionar esse problema, vamos usar o SUDO para dar as permissões necessárias para o usuário daemon executar a tarefa corretamente.
Vamos ao processo:
root@debian:~# aptitude install sudo
Em seguida, configure o SUDO.
root@debian:~# visudo Defaults env_reset root ALL=(ALL) ALL daemon ALL=NOPASSWD:/etc/init.d/heartbeat stop
E para finalizar, ajuste o arquivo heartbeat.alert para utilizar o SUDO.
Você deverá alterar a linha a seguir:
root@debian:~# vi /usr/lib/mon/alert.d/heartbeat.alert [...] # system ("/etc/init.d/heartbeat stop"); system ("sudo /etc/init.d/heartbeat stop");
E por fim, reinicie o mon.
root@debian:~# /etc/init.d/mon stop root@debian:~# /etc/init.d/mon start
Criado por:
Ciro Siqueira - siqueira.ciro[em]gmail.com
Fabricio Vaccari Constanski - fabriciovc[em]fabriciovc.eti.br