Páginas

domingo, 2 de dezembro de 2012

Balanceamento de carga utilizando KeepAlived

Fala pessoal...

Bom, depois de algum tempo sem escrever, irei escrever sobre balanceamento de carga.

Imagine o seguinte cenário onde você tem muitas requisições para suas aplicações e uma única máquina não dá conta. É ai que entra o balanceamento de carga.

Acredite, seu chefe não irá comprar uma appliance de balanceamento de carga tão fácil, porque isso custa bem caro :) Com certeza ele irá mandar você pesquisar alguma coisa ;)

Uma solução que utilizei por muito tempo é o keepalived.

O que ele faz? É um framework para interação com o Linux Virtual Server (LVS). Efetua checks em nível de rede, transporte e aplicação.
Ele faz todo o gerenciamento, se um check em um servidor falhar, ele retira automaticamente a máquina do LVS.
Outra funcionalidade muito bacana é sua alta disponibilidade utilizando o protocolo VRRP. Caso um balanceador apresente problemas (travar, cair, você precisar executar uma manutenção programada), ele faz todo o processo de migração do VIP para uma outra máquina de keepalive, e passa a atender os clientes de forma transparente.

Vale dar uma olhada no site do projeto: http://www.keepalived.org, no site ele descreve todas as funcionalidades e também tem muitos exemplos bacanas.

Outro site que também vale dar uma olhada é o site do projeto LVS: http://www.linuxvirtualserver.org/. Nesse site é descrito todas as funcionalidades do "ipvs".

Não irei descrever aqui quais os tipos de loadbalancer (NAT, DR), nem como ele funciona.
Nesse how-to iremos utilizar o DR, pois é o que menos onera o sistema e pode ser utilizado na rede interna sem a necessidade de uma nova rede.
Aqui há uma explicação de como funciona: http://www.linuxvirtualserver.org/VS-DRouting.html (em inglês)



Mãos a massa!

Ambiente de testes:

4 máquinas com Debian 6.0.6.
As máquinas tem duas interfaces de rede, a default do virtual box (10.0.2.15), e uma interface onde todos os serviços serão executados (172.16.1.0/24).
Duas são para o keepalived e outras duas eu instalei o apache servindo um arquivo simples de html

Balanceadores

As máquinas que executão os balanceadores podem ter configuração modestas. Já rodei grandes ambientes com 1 GB de ram e 2 processadores. O mínimo de disco.


1 - Instalação do keepalive

aptitude install keepalived

2 - Ativar o roteamento no kernel

Edite o arquivo /etc/sysctl.conf e encontre a linha:

net.ipv4.ip_forward=1 (Descomente-a ou a adicione)

sysctl -p (para ler o arquivo sysctl.conf sem a necessidade de reboot)

3 - Configuração do keepalived

No diretório /etc/keepalived crie um arquivo chamado keepalived.conf com o conteúdo:


 global_defs { # Configurações globais, aqui pode ser definido o e-mail para caso de falha em algum backend.  
   lvs_id LVS_Teste #Identificação do balanceador  
 }  
 vrrp_sync_group LVS_Teste { #Grupo VRRP, aqui é definido um grupo que será comum entre todos os participantes desse balanceador.  
   group {  
    LVS_Teste  
   }  
 }  
 vrrp_instance LVS_Teste{ #Esta seção descreve os parametros VRRP do virtual server  
   state MASTER # Indica que esse servidor terá o estado inicial definido como MASTER  
   interface eth1 # Interface onde o multicast do vrrp vai acontecer, e em qual interface o virtual server vai atender  
   virtual_router_id 500 #Numero unico de identificação do balanceador  
   priority 100  
   advert_int 1  
   authentication { #Mecanismo de autenticação, todas as máquinas do grupo devem ter a mesma senha  
     auth_type PASS  
     auth_pass LvSbAlancer # Senha, deve ser igual em todos os nós de keepalived  
   }  
   virtual_ipaddress {  
     172.16.1.1/24 # Esse é o ip virtual, que em caso de falha, será levado para a outra instancia do keepalived. Todos os clientes serão apontados para esse ip. Este campo suporta vários ips, um por linha com mascara.  
   }  
 }  
 virtual_server 172.16.1.1 80 { #Definição do Virtual Server. Aqui se define o VIP + porta que ele irá ouvir  
      delay_loop 1 # Tempo em segundos entre as verificações de servidores reais.  
      lb_algo rr # Algoritimo de balanceamento, nesse caso é o Round Robin, mas pode ser o WLC, WRR... veja na documentação o que mais te atende.  
      lb_kind DR # Tipo do balanceador, pode ser NAT ou DR (Direct Routing)  
      persistense_timeout 1800  
      protocol TCP # Protocolo de operação  
      real_server 172.16.1.10 80 { #aqui se define os servidores reais os backends  
           weight 1 # Peso desse servidor, quanto maior mais conexõe são enviadas para a máquina  
           HTTP_GET { # Probes, aqui é definido as regras de como se declara um host morto ou não. Pode ser trocado por somente uma conexão simples na porta, mas ai é utilizado o comando TCP_CHECK.  
                url {  
                     path /teste.html # URL de teste  
                     digest dcec999b7ece0cc82e62145eb832731f #Hash obtido através do comando genhash (mostrado abaixo)  
                }  
                connect_timeout 1 #Tempo de timeout para declarar o host morto  
                connect_port 80 #Porta de testes.  
           }  
      }  
      real_server 172.16.1.11 80 { #Mesma coisa que o acima, porém outro servidor.  
           weight 1  
           HTTP_GET {  
                url {  
                     path /teste.html  
                     digest 78617b939168605ad578d3625dc3e75e  
                }       
                 connect_timeout 1  
                 connect_port 80  
           }  
      }  
 }  
Com essa configuração é possivel ter um servidor de keepalived master funcionando.
Nos probes, eu utilizei hashes para verificação das páginas, eu acho isso melhor, pois se por algum motivo mínimo a pagina for alterada, o backend é retirado imediatamente do balanceador.
Isso é gerado através do comando genhash:

genhash -s 172.16.1.11 -p 80 -u /teste.html
MD5SUM = 78617b939168605ad578d3625dc3e75e

Onde: -s 172.16.1.11 = Servidor do apache
-p 80 = Porta 80 do servidor
-u = URL /teste.html (foi um arquivo que criei com um conteúdo pré-definido)

MD5SUM = hash que deverá ser usadno no campo digest do keepalived.

P.S. é importante que o arquivo "teste.html" exista e consiga ser acessado no webserver.


Balanceador Slave

É a mesma coisa, o conf é exatamente igual, com exeção da linha:

state MASTER

Ela deve ser

state SLAVE


Primeiros testes

O primeiro teste, é validar se no /var/log/messages há algum erro do keepalived, se houver erros como:

IPVS: Can't initialize ipvs: Protocol not available

Provavelmente o módulo ip_vs não foi carregado, faça sua inicialização com o comando:

modprobe ip_vs

e execute um restart no keepalived só por segurança.


O segundo teste é executar o comando:

ipvsadm -ln
Sua saída deve ser algo como:

root@SLB:~# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.1.1:80 rr
  -> 172.16.1.10:80               Route   1      0          0        
  -> 172.16.1.11:80               Route   1      0          0        

Se chegar nesse ponto, já podemos passar para a configuração das máquinas (real_servers)


Configuração dos Servidores Reais


1 - Inserir o seguinte conteúdo no sysctl.conf

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth1.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.eth1.arp_announce = 2

Depois disso:

sysctl -p

Isso irá garantir que a máquina não irá enviar o seu endereço de arp para o ip do vip. O MAC que irá aparecer é o do balanceador.


2 - Inserir o VIP na interface de loopback

No Debian, isso é feito no arquivo /etc/network/interfaces

auto lo:Vip
iface lo:Vip inet static
address 172.16.1.1 # Lembre-se esse é o VIP que setamos na conf do keepalived
netmask 255.255.255.255

Feito isso, um

ifup lo:Vip

Irá colocar a interface de loopback em up. Com o comando ifconfig é possível identifica-la

lo:Vip    Link encap:Local Loopback 
          inet addr:172.16.1.1  Mask:255.255.255.255
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

Repita o mesmo passo em todas as máquinas de backend.


Testes

Para que o teste seja visível, crie o arquivo na máquina:
Eu fiz o seguinte:

echo "<?php

echo date('l jS \of F Y h:i:s A');
echo "Voce foi atendido pelo servidor: ";
echo exec('hostname'); ?>" > /var/www/data.php


P.S. É necessário ter o php instalado no servidor (sim, isso é redundante, mas...)

Em uma outra máquina com um navegador qualquer, acesse: http://VIP/data.php, no meu caso http://172.16.1.1/data.php



Observe em qual servidor atendeu sua requisição (apache1)






Observe que o nome do servidor foi alterado (apache2), indicando que o balanceador funciona.

Esse balanceador pode ser utilizado em servidores proxy, da mesma forma que o apache, em instancias read only de banco de dados, enfim, em quase tudo. Use com criatividade!

Bom pessoal, espero ter ajudado.
Qualquer dúvida por favor me enviem um e-mail: