Corosync + PaceMaker + Lcmc no Debian Wheezy

O Pacemaker é um gerenciador de recursos de cluster ou cluster resource manager (CRM). Sua função é oferecer uma interface para que o usuário possa gerenciar o conjunto de clusters.

Para evitar dados corrompidos, a administração é feita através de uma estrutura centralizada. Quando um evento de falha é relatado, automaticamente é iniciado o processo de recuperação da disponibilidade da aplicação iniciando o recurso em outra máquina do cluster.

Características:

  1. Detecta e recupera falhas em computadores no nível de aplicação
  2. Administração centralizada através de shell
  3. Suporta cluster por quorate e resource-driven
  4. Suporte o envio de sinal de desligamento conforme o estado da aplicação
  5. Suporta aplicações com múltiplos nós (master/slave)
  6. Correção automática de falhas

Corosync Cluster Engine

Publicada em 2008, é considerada a evolução do Heartbeat. Possui recursos adicionais ao Heartbeat e com mais suporte.

Características:

  1. Confiabilidade na criação de réplicas de máquina de estado
  2. Reinício de aplicações em caso de falha
  3. Sistema de quorum com notificação caso uma aplicação ou máquina venha a falhar.

Resource Agent

Os Resource Agent's são scripts que contém uma série de comandos fornecendo uma interface para um recurso de cluster. Sua função é traduzir o resultado das operações executadas por um serviço verificando se ouve sucesso ou falha.

O Pacemaker suporta três tipos de agentes de recurso.

  1. LSB (Linux Standard Base)
  2. OCF (Open Cluster Framework)
  3. HRA (Heartbeat Resource Agents)

A maioria dos scripts estão no formato LSB ou OCF, o HRA tornou-se obsoleto.

Lcmc é uma ferramenta gráfica para gerenciamento de cluster disponibilizada pela pacemaker, a ferramente é escrita em java com isso podemos portar ela para qualquer plataforma.

O que eu vou utilizar:

  1. Debian Squeeze Nodo1
  2. Nome: nodo1
  3. IP: 192.168.25.40
  4. Debian Squeeze Nodo2
  5. Nome: nodo2
  6. IP: 192.168.25.41

Prepare o seu sistema com o seguinte script http://wiki.douglasqsantos.com.br/doku.php/confinicialwheezy_en para que não falte nenhum pacote ou configuração.

Ajustes iniciais

Agora vamos mandar fazer um update dos repositórios e vamos fazer um upgrade do sistema nos dois nodos

aptitude update && aptitude dist-upgrade -y

Agora vamos ajustar o arquivo /etc/hosts dos dois nodos este arquivo tem que ficar como abaixo.

127.0.0.1       localhost
192.168.25.40     nodo1.douglasqsantos.com.br       nodo1
192.168.25.41     nodo2.douglasqsantos.com.br       nodo2

Agora vamos fazer a instalação dos seguintes pacotes nós dois nodos

aptitude install corosync pacemaker -y

SSH com troca de Chaves

Agora no Nodo1 vamos gerar as chaves de ssh para efetuarmos a conexão de ssh via troca de chaves

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): #ENTER
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): #ENTER
Enter same passphrase again: #ENTER
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
b2:88:e4:58:ff:c7:07:05:2a:55:05:03:1e:a4:43:1b root@nodo1
The key's randomart image is:
+--[ RSA 2048]----+
|    E.+o+o.      |
|   . =....       |
|    +... .       |
|    ...   .      |
|  o  .. S.       |
| = o . o.        |
|. o o .. .       |
|     .  o .      |
|      .. .       |
+-----------------+

Agora no Nodo2 vamos gerar as chaves de ssh para efetuarmos a conexão de ssh via troca de chaves

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): #ENTER
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): #ENTER
Enter same passphrase again: #ENTER
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
4d:b0:df:ef:b1:08:fb:9f:2e:5c:fb:3c:b0:8f:d4:77 root@nodo2
The key's randomart image is:
+--[ RSA 2048]----+
|        .        |
|         o       |
|        . .      |
|         + .     |
|        S o .    |
|             oo  |
|          .. o=oE|
|           o++o*o|
|          ..o=Bo+|
+-----------------+

Agora no Nodo1 vamos copiar as chaves para o Nodo2

ssh-copy-id 192.168.25.41
The authenticity of host '192.168.25.41 (192.168.25.41)' can't be established.
RSA key fingerprint is 8b:af:fc:ac:d7:8a:44:d5:30:ad:1e:b9:de:95:78:d0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.25.41' (RSA) to the list of known hosts.
root@192.168.25.41's password: #SENHA
Now try logging into the machine, with "ssh '192.168.25.41'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

Agora no Nodo2 vamos copiar as chaves para o Nodo1

ssh-copy-id 192.168.25.40
The authenticity of host '192.168.25.40 (192.168.25.40)' can't be established.
RSA key fingerprint is a0:73:55:67:86:11:8d:13:c6:45:cc:85:c6:d5:a9:a2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.25.40' (RSA) to the list of known hosts.
root@192.168.25.40's password: #SENHA
Now try logging into the machine, with "ssh '192.168.25.40'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

Configuração do Corosync

Agora no Nodo1 vamos gerar a chave de autenticação para o Corosync

corosync-keygen 
Corosync Cluster Engine Authentication key generator.
Gathering 1024 bits for key from /dev/random.
Press keys on your keyboard to generate entropy.
Press keys on your keyboard to generate entropy (bits = 176).
Press keys on your keyboard to generate entropy (bits = 240).
Press keys on your keyboard to generate entropy (bits = 304).
Press keys on your keyboard to generate entropy (bits = 368).
Press keys on your keyboard to generate entropy (bits = 432).
Press keys on your keyboard to generate entropy (bits = 496).
Press keys on your keyboard to generate entropy (bits = 560).
Press keys on your keyboard to generate entropy (bits = 624).
Press keys on your keyboard to generate entropy (bits = 688).
Press keys on your keyboard to generate entropy (bits = 752).
Press keys on your keyboard to generate entropy (bits = 816).
Press keys on your keyboard to generate entropy (bits = 880).
Press keys on your keyboard to generate entropy (bits = 944).
Press keys on your keyboard to generate entropy (bits = 1008).
Writing corosync key to /etc/corosync/authkey.

Agora abra um novo terminal para o servidor 192.168.25.40 enquanto é gerada a chave para o corosync, vamos agilizar a geração dos dados aleatórios para a chave

Agora no novo terminal no Nodo1 execute o seguinte comando

find / -iname "*" -exec ls -l {} \;

Depois que terminar a geração da chave para o corosync podemos cancelar o comando do find com um crtl + c e podemos fechar o terminal adicional que abrimos no Nodo1

Agora no Nodo1 vamos copiar as chaves do corosync para o Nodo2

scp /etc/corosync/authkey 192.168.25.41:/etc/corosync/authkey

Agora vamos executar o comando abaixo nos dois Nodos para deixarmos o corosync ativado na inicialização

sed -i 's/START=no/START=yes/g' /etc/default/corosync

No Nodo1 vamos fazer um backup do arquivo de configuração do Corosync

cp -a /etc/corosync/corosync.conf{,.bkp}

Agora vamos a configuração do corosync

vim /etc/corosync/corosync.conf
# /etc/corosync/corosync.conf

#Opção do protocolo totem
totem {
  version: 2

  #Tempo para verificar perca de pacotes em (ms)
  token: 3000

  #Quantas verificações antes de gerar notificações
  token_retransmits_before_loss_const: 10

  #Quanto tempo esperar para agrupar as notificações em (ms)
  join: 60

  #Quanto tempo esperar para uma solução antes de começar uma nova verificação (ms)
  consensus: 3600

  #Filtro de sincronismo virtual desabilitado
  vsftype: none

  #Número de mensagens processadas na recepção de pacotes
  max_messages: 20

  #Limite de cluster assinados
  clear_node_high_bit: yes

  #Criptografia desabilitada
  secauth: off

  #Quantas threads usadas para criptografar/descriptografar
  threads: 0

  #Atribui ID em um cluster fixo (opcional)
  # nodeid: 1234

  #Especifica que em modo de redundancia, não pode havar nenhum cluster ativo ou passivo.
  rrp_mode: none

  interface {
    #Número de clusters (0 default)
    ringnumber: 0
                #Início de ips utilizados por cluster 192.168.25.0 é 192.168.25.0/24 aqui mude para 
                #O endereço da sua rede ex: 192.168.0.0 que seria 192.168.0.0/24
    bindnetaddr: 192.168.25.0
                #Fim de ips utilizados por cluster
    mcastaddr: 226.94.1.1
                #Porta utilizaad pelo corosync
    mcastport: 5405
  }
}

#Configuração de AIS Availability Management Framework
amf {
  mode: disabled
}

service {
  #Carregamento do serviço para gerenciamento
  ver:       0
  name:      pacemaker
}

#Temos que setar o usuário e grupo como root para o ais ser capaz de gerenciar os recursos do pacemaker
aisexec {
        user:   root
        group:  root
}


#Configuração de log
logging {
        fileline: off
        to_stderr: yes
        to_logfile: yes
        logfile: /var/log/corosync/corosync.log
        #Aqui estou desabilitando os logs para o syslog, pq senão zoa demais o arquivo
        to_syslog: no
  syslog_facility: daemon
        debug: off
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
                tags: enter|leave|trace1|trace2|trace3|trace4|trace6
        }
}

Agora vamos copiar o nosso arquivo para o Nodo2

scp /etc/corosync/corosync.conf 192.168.25.41:/etc/corosync/

Agora vamos reiniciar o corosync nos dois nodos

/etc/init.d/corosync restart

Agora vamos ver se o nosso cluster está funcionando no Nodo1 vamos consultar

crm_mon --one-shot -V
crm_mon[13885]: 2013/06/24_11:47:10 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined
crm_mon[13885]: 2013/06/24_11:47:10 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option
crm_mon[13885]: 2013/06/24_11:47:10 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity
============
Last updated: Mon Jun 24 11:47:10 2013
Last change: Mon Jun 24 11:47:01 2013 via crmd on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ nodo1 nodo2 ]

Caso não apareça a mensagem como acima os dois nodos online, reinicie o corosync novamente para ele recarregar os nodos

/etc/init.d/corosync restart

Agora vamos ver se o nosso cluster está funcionando no Nodo2 vamos consultar

crm_mon --one-shot -V
crm_mon[3991]: 2013/06/24_11:47:09 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined
crm_mon[3991]: 2013/06/24_11:47:09 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option
crm_mon[3991]: 2013/06/24_11:47:09 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity
============
Last updated: Mon Jun 24 11:47:09 2013
Last change: Mon Jun 24 11:47:01 2013 via crmd on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ nodo1 nodo2 ]

Agora no Nodo1 vamos desabilitar o stonith para que ele não fique gerando erros, caso o comando abaixo demore, cancele ele com ctrl + C e reinicie o corosync e depois rode ele novamente.

crm configure property stonith-enabled=false

Agora vamos consultar novamente no Nodo1 agora com outro comando

crm_mon -1
============
Last updated: Mon Jun 24 11:47:16 2013
Last change: Mon Jun 24 11:47:01 2013 via crmd on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ nodo1 nodo2 ]

Agora podemos verificar senão temos nenhum problema com o nosso cluster da seguinte forma

crm_verify -L

Como não tivemos erros ele não retorna nada.

Vamos consultar a configuração do corosync no Nodo1

crm configure show
node nodo1
node nodo2
property $id="cib-bootstrap-options" \
  dc-version="1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff" \
  cluster-infrastructure="openais" \
  expected-quorum-votes="2" \
  stonith-enabled="false"

Agora vamos consultar a configuração do corosync no Nodo2

crm configure show
node nodo1
node nodo2
property $id="cib-bootstrap-options" \
  dc-version="1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff" \
  cluster-infrastructure="openais" \
  expected-quorum-votes="2" \
  stonith-enabled="false"

Pacemaker

Para o Pacemaker ser configurado ser utilizado o utilitário de linha de comando crm.

Através do crm é possível criar tipos básicos e avançados de cluster, regras, nodes de failback e failover, monitoramento, migração entre outros.

Vamos listar os recursos do tipo OCF

crm ra list ocf
ASEHAagent.sh        AoEtarget            AudibleAlarm         CTDB                 ClusterMon           Delay                Dummy                EvmsSCC              Evmsd                Filesystem           HealthCPU
HealthSMART          ICP                  IPaddr               IPaddr2              IPsrcaddr            IPv6addr             LVM                  LinuxSCSI            MailTo               ManageRAID           ManageVE
Pure-FTPd            Raid1                Route                SAPDatabase          SAPInstance          SendArp              ServeRAID            SphinxSearchDaemon   Squid                Stateful             SysInfo
SystemHealth         VIPArip              VirtualDomain        WAS                  WAS6                 WinPopup             Xen                  Xinetd               anything             apache               apache.sh
asterisk             clusterfs.sh         conntrackd           controld             db2                  drbd                 eDir88               ethmonitor           exportfs             fio                  fs.sh
iSCSILogicalUnit     iSCSITarget          ids                  ip.sh                iscsi                jboss                ldirectord           lvm.sh               lvm_by_lv.sh         lvm_by_vg.sh         lxc
mysql                mysql-proxy          mysql.sh             named.sh             netfs.sh             nfsclient.sh         nfsexport.sh         nfsserver            nfsserver.sh         nginx                o2cb
ocf-shellfuncs       openldap.sh          oracle               oracledb.sh          orainstance.sh       oralistener.sh       oralsnr              pgsql                ping                 pingd                portblock
postfix              postgres-8.sh        proftpd              rsyncd               samba.sh             script.sh            scsi2reservation     service.sh           sfex                 smb.sh               svclib_nfslock
symlink              syslog-ng            tomcat               tomcat-5.sh          tomcat-6.sh          vm.sh                vmware          

Agora vamos listar os recursos do tipo lsb

crm ra list lsb
acpid                     atd                       atop                      bootlogs                  bootmisc.sh               checkfs.sh                checkroot-bootclean.sh    checkroot.sh              console-setup
corosync                  cron                      dbus                      exim4                     halt                      hdparm                    hostname.sh               hwclock.sh                kbd
keyboard-setup            killprocs                 kmod                      logd                      motd                      mountall-bootclean.sh     mountall.sh               mountdevsubfs.sh          mountkernfs.sh
mountnfs-bootclean.sh     mountnfs.sh               mtab.sh                   networking                nfs-common                openhpid                  pacemaker                 postfix                   procps
rc                        rc.local                  rcS                       reboot                    rmnologin                 rpcbind                   rsync                     rsyslog                   sendsigs
single                    ssh                       sudo                      udev                      udev-mtab                 umountfs                  umountnfs.sh              umountroot                urandom
virtualbox-guest-utils    x11-common        

Agora vamos desabilitar o quorum para não recebermos erros durante a configuração dos recursos, podemos executar em algum dos dois nodos

crm configure property no-quorum-policy=ignore

Configuração de Recurso Endereço IP

Para poder prover a movimentação de serviços entre os nós do cluster sem a necessidade de alterarmos o endereço IP do serviço, o endereço IP associado ao serviço deverá ser configurado como um recurso para que ele possa ser movido livremente entre os nós do cluster junto com o serviço.

Agora vamos criar um recurso do tipo endereço IP 192.168.25.200 usando o RA IPaddr2.

crm configure primitive R_IP_Apache ocf:heartbeat:IPaddr2 params ip=192.168.25.200 cidr_netmask=255.255.255.0 nic=eth0 op monitor interval=10s

Agora vamos verificar o nosso recurso

crm_mon -1
============
Last updated: Mon Jun 24 11:54:03 2013
Last change: Mon Jun 24 11:53:59 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ nodo1 nodo2 ]

 R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo1

Aqui nós não definimos em qual servidor o recurso deve ser alocado, com isso o Pacemaker já fez isso.

Agora vamos consultar o endereço ip configurado no servidor nodo1 que é no Nodo1

ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:01:18:8b brd ff:ff:ff:ff:ff:ff
    inet 192.168.25.40/24 brd 192.168.25.255 scope global eth0
    inet 192.168.25.200/24 brd 192.168.25.255 scope global secondary eth0
    inet6 fe80::a00:27ff:fe01:188b/64 scope link 
       valid_lft forever preferred_lft forever

Agora vamos testar, vamos desligar o servidor Nodo1 aonde esta o nosso recurso alocado.

shutdown -h now

Agora no Nodo2 vamos consultar os endereços ip

ip addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:66:da:85 brd ff:ff:ff:ff:ff:ff
    inet 192.168.25.41/24 brd 192.168.25.255 scope global eth0
    inet 192.168.25.200/24 brd 192.168.25.255 scope global secondary eth0
    inet6 fe80::a00:27ff:fe66:da85/64 scope link 
       valid_lft forever preferred_lft forever

Note que o nosso recurso agora está no servidor Nodo2, vamos consultar os nossos recursos

crm_mon -1
============
Last updated: Mon Jun 24 11:55:18 2013
Last change: Mon Jun 24 11:53:59 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition WITHOUT quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ nodo2 ]
OFFLINE: [ nodo1 ]

 R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2

Note que o pacemaker já notou que o nodo1 está OFFLINE. Agora vamos ligar ele novamente

Agora vamos consultar os nossos recursos novamente

crm_mon -1
============
Last updated: Mon Jun 24 11:56:00 2013
Last change: Mon Jun 24 11:53:59 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ nodo1 nodo2 ]

 R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2

Note que agora o recurso voltou para o servidor nodo1.

Configuração de recursos para monitoramento de serviços

Agora vamos instalar o apache nos dois nodos para utilizarmos o recurso para monitoramento de serviços

aptitude install apache2 -y

Agora no Nodo1 vamos deixar o index.html da seguinte forma

vim /var/www/index.html
<html><body><h1>Nodo 1</h1>
</body></html>

Agora no Nodo2 vamos deixar o index.html da seguinte forma

vim /var/www/index.html
<html><body><h1>Nodo 2</h1>
</body></html>

Agora vamos parar o apache nos dois nodos

/etc/init.d/apache2 stop

Agora vamos configurar um recurso para monitorar o apache2

crm configure primitive R_Apache lsb:apache2

Agora vamos consultar os recursos

crm_mon -1
============
Last updated: Mon Jun 24 11:57:53 2013
Last change: Mon Jun 24 11:57:50 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2
 R_Apache (lsb:apache2):  Started nodo1

Note que o recurso foi alocado no servidor nodo1, vamos acessar então http://192.168.25.40 o acesso vai estar ok pois o Pacemaker vai subir o serviço do apache automaticamente.

Criação de Grupos de Recursos

Para facilitar a movimentação e o gerenciamento de recursos associados a um serviço, podemos agrupar todos esses recursos em um único grupo de recursos. Assim ao definirmos uma localização para o grupo, todos os recursos serão movidos para a localização desejada.

Vamos levar em consideração o nosso servidor apache que precisa de um endereço ip para ser acessado, e nos nossos recursos o ip está em um servidor e o serviço do apache está em outro servidor, para resolvermos isso vamos criar um grupo

crm configure group G_HTTP_Server R_Apache R_IP_Apache

Agora vamos consultar os nossos recursos novamente

crm_mon -1
============
Last updated: Mon Jun 24 11:59:35 2013
Last change: Mon Jun 24 11:59:19 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo1
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo1

Note que agora tanto o ip quando o serviço do apache estão no servidor nodo1, vamos acessar ele em http://192.168.25.200 e vamos ter o acesso corretamente.

Configuração das localizações de Recursos

Agora vamos ver como fazemos para definir o local padrão para o G_HTTP_Server sendo o servidor nodo2

crm configure location L_HTTP_Server G_HTTP_Server 100: nodo2

Agora vamos consultar os nossos recursos

crm_mon -1
============
Last updated: Mon Jun 24 12:02:52 2013
Last change: Mon Jun 24 12:00:20 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo1
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo1

Ele não migrou os recursos pois os recursos estão em funcionamento, agora vamos verificar a configuração do crm

crm configure show
node nodo1
node nodo2
primitive R_Apache lsb:apache2
primitive R_IP_Apache ocf:heartbeat:IPaddr2 \
  params ip="192.168.25.200" cidr_netmask="255.255.255.0" nic="eth0" \
  op monitor interval="10s"
group G_HTTP_Server R_Apache R_IP_Apache
location L_HTTP_Server G_HTTP_Server 100: nodo2
property $id="cib-bootstrap-options" \
  dc-version="1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff" \
  cluster-infrastructure="openais" \
  expected-quorum-votes="2" \
  stonith-enabled="false"

Como ele não migrou vamos mandar migrar manualmente, aqui precisamos passar o nome do nodo ao invés do ip

crm resource migrate G_HTTP_Server nodo2

Agora vamos consultar os nossos recursos

crm_mon -1
============
Last updated: Mon Jun 24 12:04:05 2013
Last change: Mon Jun 24 12:04:02 2013 via crm_resource on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo2
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2

Agora vamos acessar novamente http://192.168.25.200 e vamos notar que temos a identificação do nodo2 :D

Manipulando Recursos

Para parar um recurso podemos fazer da seguinte forma

crm resource stop R_Apache

Aqui no exemplo acima mandamos parar o recurso do apache, vamos consultar os recursos

crm_mon -1
============
Last updated: Mon Jun 24 12:04:51 2013
Last change: Mon Jun 24 12:04:38 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

Note que não temos nada mais funcionando pois o R_Apache pertence ao G_HTTP que tem o recurso do apache e o recurso do ip, então temos que cuidar quando formos mandar baixar algum serviços.

Para iniciar um recurso podemos fazer da seguinte forma

crm resource start R_Apache

Agora vamos consultar os nossos recursos novamente

crm_mon -1
============
Last updated: Mon Jun 24 12:05:08 2013
Last change: Mon Jun 24 12:05:05 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo2
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2

Note que agora temos os nossos recursos funcionando novamente

Podemos mandar listar somente os recursos da seguinte forma

crm resource list
 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2) Started 
     R_IP_Apache  (ocf::heartbeat:IPaddr2) Started 

Para remover um recurso podemos fazer da seguinte forma, obs: o recurso deve estar parado

crm configure delete R_Apache

Podemos colocar um nodo em standby da seguinte forma

crm node standby nodo2

Agora vamos consultar os nossos recursos

crm_mon -1
============
Last updated: Mon Jun 24 12:06:48 2013
Last change: Mon Jun 24 12:05:46 2013 via crm_attribute on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Node nodo2: standby
Online: [ nodo1 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo1
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo1

Note que os recursos foram migrados automaticamente para o nodo nodo1.

Agora vamos deixar o nodo online novamente podemos fazer da seguinte forma

crm node online nodo2

Agora vamos consultar os nossos recursos novamente

crm_mon -1
============
Last updated: Mon Jun 24 12:07:12 2013
Last change: Mon Jun 24 12:07:09 2013 via crm_attribute on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache (lsb:apache2):  Started nodo2
     R_IP_Apache  (ocf::heartbeat:IPaddr2): Started nodo2

Note que os recursos voltaram para o servidor padrão que é o nodo2.

Podemos editar a configuração do crm da seguinte forma também, use estão opção somente em última alternativa.

crm configure edit
node nodo1
node nodo2 \
        attributes standby="off"
primitive R_Apache lsb:apache2 \
        meta target-role="Started"
primitive R_IP_Apache ocf:heartbeat:IPaddr2 \
        params ip="192.168.25.200" cidr_netmask="255.255.255.0" nic="eth0" \
        op monitor interval="10s"
group G_HTTP_Server R_Apache R_IP_Apache
location L_HTTP_Server G_HTTP_Server 100: 192.168.25.41
location cli-prefer-G_HTTP_Server G_HTTP_Server \
        rule $id="cli-prefer-rule-G_HTTP_Server" inf: #uname eq nodo2
property $id="cib-bootstrap-options" \
        dc-version="1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        stonith-enabled="false"

Monitoramento de Recursos

Agora vamos ver uma lista de comandos úteis para o monitoramento dos recursos criados

Monitorar os recursos do cluster com atualizações a cada 1 segundo

crm_mon --interval=1
============
Last updated: Mon Jun 24 12:08:07 2013
Last change: Mon Jun 24 12:07:09 2013 via crm_attribute on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache   (lsb:apache2):  Started nodo2
     R_IP_Apache        (ocf::heartbeat:IPaddr2):       Started nodo2

O comando acima é similar ao seguinte

watch crm_mon -1
Every 2,0s: crm_mon -1                                                                                                                                                                                               Mon Jun 24 12:08:44 2013

============
Last updated: Mon Jun 24 12:08:44 2013
Last change: Mon Jun 24 12:07:09 2013 via crm_attribute on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_HTTP_Server
     R_Apache   (lsb:apache2):  Started nodo2
     R_IP_Apache        (ocf::heartbeat:IPaddr2):       Started nodo2

Monitorar os recursos do cluster e exibir a saída em um arquivo html

crm_mon --daemonize --as-html /var/www/cluster.html

Agora já podemos consultar o nosso relatório em http://ip_servidor/cluster.html

vamos ter algo como a imagem abaixo

Podemos deixar este comando para ser carregado na inicialização do sistema da seguinte forma

echo "crm_mon --daemonize --as-html /var/www/cluster.html" >> /etc/rc.local

Instalando e configurando o Lcmc

Podemos utilizar um cliente qualquer agora para instalar o Lcmc eu vou abordar a instalação no CentOS e no Debian :D porém podemos obter o .exe dele em http://sourceforge.net/projects/lcmc/files/?source=directory

Como é uma ferramenta feita em java vamos mandar instalar os pacotes necessários.

No Debian precisamos instalar

aptitude install sun-java6-jdk -y

No CentOS precisamos instalar

yum install java-1.7.0-openjdk -y

Agora podemos obter o pacote para Debian

cd /usr/src
wget -c http://wiki.douglasqsantos.com.br/Downloads/misc/lcmc_1.5.5-1_all.deb

Agora vamos mandar instalar ele

dpkg -i lcmc_1.5.5-1_all.deb

Caso tenha alguma dependência não satisfeita podemos executar o comando abaixo para resolver.

apt-get -f install -y

Agora vamos obter o pacote para CentOS

cd /usr/src
wget -c http://wiki.douglasqsantos.com.br/Downloads/misc/lcmc-1.5.5-1.noarch.rpm

Agora vamos mandar instalar ele

yum install lcmc-1.5.5-1.noarch.rpm -y

Ou se preferir pode obter o executável para Windows

http://wiki.douglasqsantos.com.br/Downloads/misc/LCMC-1.5.5-setup.exe

Agora para mandar executar ele precisamos executar o seguinte comando tanto no Debian quanto no CentOS

lcmc &

Vamos ter algo como a imagem abaixo:

Aqui nesta tela precisamos selecionar Add Host / Wizard:

  1. Agora precisamos informar o endereço ip do Nodo1 ex: 192.168.25.40
  2. Agora se a porta de ssh não for a padrão precisamos informar a porta e selecionar Next
  3. Agora vamos selecionar Next novamente
  4. Agora informe a senha do root
  5. Talvez ele peça a senha 3 vezes
  6. Agora selecione Next
  7. Agora ele vai reconhecer qual o Distro que está sendo utilizada selecione Next
  8. Agora ele vai dar uma reclamada que não temos o drbd instalado como não vamos utilizar ele selecine Ski this dialog e selecione Next
  9. Agora selecione Add Another Host
  10. Agora precisamos informar o endereço ip do Nodo2 ex: 192.168.25.41
  11. Agora se a porta de ssh não for a padrão precisamos informar a porta e selecionar Next
  12. Agora vamos selecionar Next novamente
  13. Agora informe a senha do root Caso tenha configurado a troca de chaves não vamos precisar informar a senha do root
  14. Talvez ele peça a senha 3 vezes
  15. Agora selecione Next
  16. Agora ele vai reconhecer qual o Distro que está sendo utilizada selecione Next
  17. Agora ele vai dar uma reclamada que não temos o drbd instalado como não vamos utilizar ele selecine Ski this dialog e selecione Next
  18. Agora selecione Add Cluster/Wizard
  19. Agora precisamos informar um Nome para ele ex: Cluster_Matriz agora selecione Next
  20. Agora precisamos informar quais Nodos pertencem a este cluster vamos selecionar o nodo1 e o nodo2 e vamos selecionar Next
  21. Agora o sistema vai querer saber quem vamos utilizar o Heartbeat ou o Corosync/OpenAIS vamos selecionar o Corosync/OpenAIS e selecione Next
  22. Agora ele vai nos mostrar a configuração do corosync.conf vamos deixar ela como está e vamos selecionar Next/Keep Old Config
  23. Agora vamos ter um aviso que o DRBD e o Heartbeat não estão funcionando mais como não estamos utilizando eles selecione Skip this dialog e selecione Next
  24. Agora deixe selecionado Save e selecione Finish

Se tudo foi seguido como explicado vamos ter algo como a imagem abaixo:

Agora podemos fazer todas as configurações dos recursos pela interface gráfica :D

Uso Real

Situação:

Temos um servidor de FW de borda que vai fazer o balanceamento dos serviços para a DMZ, e só temos um endereço ip público para este servidor, com isso não temos como setar um endereço ip em cada servidor e depois mais um para balanceamento, com isso podemos criar dois recursos um para o endereço ip e outro para o router do provedor de serviços, com isso temos um cluster com somente um endereço ip compartilhado, ou múltiplos endereços compartilhados entre os dois servers e com o GW compartilhado também sem a necessidade de colocar ips sem uso nos servers.

Vamos levar em consideração o seguinte:

  • IP Nodo1: 192.168.25.40
  • IP Nodo2: 192.168.25.41
  • IP público: 200.200.200.1/24
  • GW Público: 200.200.200.254
  • Interface pública: eth1
  • Nome do recurso IP: ClusterIP
  • Nome do recuros GW: ClusterGW
  • Nome do grupo de recursos: G_LVS
  • Nome da localização: L_Cluster_LVS

Para utilizar o recurso de GW precisamos remover o route default da seguinte forma nos dois nodos

route del default

Efetue a configuração do Corosync e não adicione recursos e depois vamos a configuração do nosso ambiente

Vamos criar o recurso que vai conter o endereço ip compartilhado

crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 params ip=200.200.200.1 cidr_netmask=24 nic=eth1 op monitor interval=30s

Agora vamos criar o recurso que vai conter o endereço ip do GW

crm configure primitive ClusterGW ocf:heartbeat:Route params destination="0.0.0.0/0" device=eth1 gateway=200.200.200.254 op monitor interval=30s

Agora vamos configurar um grupo de recursos para podermos agrupar o ip e o gw em um mesmo servidor, aqui leve em consideração a ordem dos recursos como é um ip e o gw então informa o recurso ip primeiro depois o gw pois se a interface não tiver um gw padrão, quando for inserir o gw e não tiver o ip da faixa vai ficar dando erro.

crm configure group G_LVS ClusterIP ClusterGW

Agora vamos criar a configuração de onde vamos deixar os nossos recursos, vou deixar no nodo1

crm configure location L_Cluster_LVS G_LVS 100: nodo1

Agora vamos criar a configuração de onde vamos deixar os nossos recursos caso o primeiro nodo caia

crm configure location L_Cluster_LVS2 G_LVS 50: nodo2

Agora vamos listar a nossa configuração

crm configure show
node nodo1
node nodo2 \
  attributes standby="off"
primitive ClusterGW ocf:heartbeat:Route \
  params destination="0.0.0.0/0" device="eth1" gateway="200.200.200.254" \
  op monitor interval="30s"
primitive ClusterIP ocf:heartbeat:IPaddr2 \
  params ip="200.200.200.1" cidr_netmask="24" nic="eth1" \
  op monitor interval="30s"
group G_LVS ClusterIP ClusterGW
location L_Cluster_LVS G_LVS 100: nodo1
location L_Cluster_LVS2 G_LVS 50: nodo2
property $id="cib-bootstrap-options" \
  dc-version="1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff" \
  cluster-infrastructure="openais" \
  expected-quorum-votes="2" \
  stonith-enabled="false"

Agora vamos visualizar os nossos recursos

crm_mon -1
============
Last updated: Mon Jun 24 12:38:29 2013
Last change: Mon Jun 24 12:37:43 2013 via cibadmin on nodo1
Stack: openais
Current DC: nodo2 - partition with quorum
Version: 1.1.7-ee0730e13d124c3d58f00016c3376a1de5323cff
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ nodo1 nodo2 ]

 Resource Group: G_LVS
     ClusterIP  (ocf::heartbeat:IPaddr2): Started nodo1
     ClusterGW  (ocf::heartbeat:Route): Started nodo1

Agora vamos listar as rotas

route -n
Tabela de Roteamento IP do Kernel
Destino         Roteador        MáscaraGen.    Opções Métrica Ref   Uso Iface
0.0.0.0         200.200.200.254 0.0.0.0         UG    0      0        0 eth1
192.168.25.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
200.200.200.0   0.0.0.0         255.255.255.0   U     0      0        0 eth1

OBS: Caso esteja utilizando em fw de borda com politica de fw drop precisamos ajustar algumas regras.

No nodo1 tem que ser utilizado o ip dele mesmo pois ele trabalha com um tunnel.

iptables -A INPUT -p udp -m state --state NEW -s 192.168.25.40 -m multiport --dports 5404,5405 -j ACCEPT
iptables -A OUTPUT -p udp -m state --state NEW -d 192.168.25.40 -m multiport --dports 5404,5405 -j ACCEPT
iptables -A INPUT -p udp -m state --state NEW -s 226.94.1.1 -m multiport --dports 5404,5405 -j ACCEP
iptables -A INPUT -p udp -m state --state NEW -d 226.94.1.1 -m multiport --dports 5404,5405 -j ACCEP

No nodo2 tem que ser utilizado o ip dele mesmo para liberar pois ele trabalha com um tunnel.

iptables -A INPUT -p udp -m state --state NEW -s 192.168.25.41 -m multiport --dports 5404,5405 -j ACCEPT
iptables -A OUTPUT -p udp -m state --state NEW -d 192.168.25.41 -m multiport --dports 5404,5405 -j ACCEPT
iptables -A INPUT -p udp -m state --state NEW -s 226.94.1.1 -m multiport --dports 5404,5405 -j ACCEP
iptables -A INPUT -p udp -m state --state NEW -d 226.94.1.1 -m multiport --dports 5404,5405 -j ACCEP

Referências