LVS

De Wiki
Ir para: navegação, pesquisa

O que é o LVS

Cenário

O LVS é um balanceador de carga por serviço em camada 4, que funciona como o switch, balanceando as conexões dos clientes com os servidores reais que fazem parte do pool LVS.

Nosso objetivo é montar um ambiente de balanceamento de carga por serviço com LVS e cujo serviço (que poderia ser outro, como o Proxy, SSH, LDAP), será o serviço HTTP utilizando o Apache. O que muda nas implementações no geral é: a topologia (NAT, tuneis ou roteamento direto), algoritmo de balanceamento dos servidores reais e a segurança do funcionamento dos diretores (que são os balanceadores em si).

A topologia geral do LVS é como a figura abaixo:

LVS Geral.png


o que muda é a forma como configuramos cada um destes modelos.

LVS por NAT

No modelo por NAT o servidor diretor gerencia todas as conexões entre os clientes e os servidores reais, embora este modelo seja o mais interessante pelo fato dos servidores reais utilizarem qualquer sistema operacional que suporte TCP/IP, ele acaba tendo o diretor como o gargalo do modelo.

LVS por Túneis

No modelo por túneis os servidores precisam suportar conexão por túnel, mas o mais interessante é que a topologia final pode ser espalhada pela Internet, ou seja, os servidores reais podem tanto estar na rede local LAN como atráves da WAN (e neste caso, podemos utilizar geolocalização para balancear as conexões entre os cliente e os servidores de forma a reduzir a latência de resposta)

LVS por Roteamento Direto

Neste modelo o diretor e os servidores reais estão no mesmo barramento de rede, o maior problema aqui é que neste modelo cada servidor real deve possuir o IP público que é utilizado pelo cliente, mas este IP público (que estará armazenado em uma interface virtual/dummy) não deve responder a requisições ARP para o cliente. A pergunta é: por que isso é necessário? porque se o servidor real reponde-se o IP público diretamente para o cliente, o balanceamento só ocorreria na primeira requisição para o cliente e nas demais as requisições não seriam mais encaminhadas para o diretor, quebrando toda a estrutura de balanceamento.

Da mesma forma que a topologia por túneis, a por roteamento direto entrega as requisições diretamente para o cliente

Uma visão geral dos modelos de LVS

Podemos ver na tabela abaixo uma visão geral de como o LVS funciona de acordo com seu modelo, apresentando suas vantagens e desvantagens:

Fornecedor NAT TÚNEIS ROTEAMENTO
OS Qualquer Suporte a TUN Supressão de ARP
REDE LAN (privada) LAN ou WAN LAN
Número baixo (10~20) alto (>100) alto (>100)
Gateway diretor independente independente

Exemplo Prático

Pacotes necessários

Vamos criar um ambiente LVS com NAT utilizando o Debian Squeeze como diretor e quaisquer outros servidores executando o Apache.

                                  ===> Ubuntu Server 10.04 LTS
CLIENTES ===>   DIRETOR (Debian)  ===> FreeBSD 8.2
                                  ===> CentOS 5.6

Todos os servidores reais devem estar executando o servidor WEB Apache. A topologia de rede vai estar definida da seguinte forma:

  • Debian Squeeze
eth0: 200.129.202.132 (IP público)
eth1: 172.16.0.1/24 (IP privado)
  • Ubuntu Server 10.04 LTS
eth0: 172.16.0.2/24 (gateway: 172.16.0.1)
  • FreeBSD 8.2
eth0: 172.16.0.3/24 (gateway: 172.16.0.1)
  • CentOS 5.6
eth0: 172.16.0.4/24 (gateway: 172.16.0.1)

Vamos instalar os pacotes no diretor:

# apt-get install ipvsadm
update-rc.d: warning: ipvsadm start runlevel arguments (2 3 4 5) do not match LSB Default-Start values (2 3 5)
ipvsadm is not configured to run. Please run dpkg-reconfigure ipvsadm.

Devemos reconfigurar o pacote para ajustar as configurações:

# dpkg-reconfigure ipvsadm

A configuração será definida como master, a interface de comunicação entre os diretores pode ser definida para a eth0.

Vamos configurar agora o balanceamento do serviço web, para isso precisamos primeiro ativar o encaminhamento das conexões IP no servidor diretor:

# echo 1 > /proc/sys/net/ipv4/ip_forward

Agora que o encaminhamento do IP que será utilizado pelo pool está configurado, vamos ativar o pool utlizando o comando ipvsadm:

# ipvsadm -A -t 200.129.202.132:80 -s rr
# ipvsadm -a -t 200.129.202.132:80 -r 172.16.0.2:80  -m
# ipvsadm -a -t 200.129.202.132:80 -r 172.16.0.3:80  -m 
# ipvsadm -a -t 200.129.202.132:80 -r 172.16.0.4:80  -m

Como utilizamos a política de round robin sem pesos, bastou usar o parâmetro -m por estarmos utilizando NAT. Se quissémos utilizar persistência nas conexões bastaria criar o pool desta forma:

# ipvsadm -A -t 200.129.202.132:80 -s rr -p 60

Onde 60 é o tempo em segundos em que a persistência ficará valendo.

Uma vez criado o pool, podemos ver que ele está ativo com o comando:

# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  200.129.202.132:www rr
  -> 172.16.0.2:www               Masq   1      0          0
  -> 172.16.0.3:www               Masq   1      0          0
  -> 172.16.0.4:www               Masq   1      0          0
Com isso, ao acessar a URL:
http://200.129.202.132/
, você vai ver o index.html que está nos servidores que fazem parte do pool. O campo ActiveConn representa as conexões ativas e gerenciadas e o campo IncActConn representa as conexões que foram iniciadas (por exemplo, com alguns reloads na página, você verá que as conexões em IncActConn vão se alternando, isso porque o algoritmo selecionado foi o rr - Round Robin, e balanceando entre os servidores).

Para garantir que nosso pool seja iniciado corretamente a cada boot do servidor, precisamos salvar estas configurações:

# ipvsadm-save > /etc/ipvsadm.rules

Pronto, nosso pooll está configurado e funcionando.

Cuidados com ARP

No roteamento direto ou por túneis, vocês devem tomar cuidado com os problemas relacionados com o ARP nos servidores reais. Para que o cluster funcione de forma correta você pode se utilizar de várias soluções. A que foi testada e funcionou conosco, foi a supressão do ARP usando ARPTABLES, então é necessários instalar o ARPTABLES em cada servidor real:

# apt-get install arptables

É necessário e OBRIGATÓRIO que os comandos do arptables sejam executados antes de levantar as intarfaces virtuais, por exemplo, vamos supor que queremos que o IP público 200.129.202.132/25 seja utilizado pelo cluster no servidor real e que o IP do servidor seja 200.129.202.130/25, então teríamos a seguinte configuração:

# arptables -F
# arptables -A INPUT -d 200.129.202.132 -j DROP 
# arptables -A OUTPUT -s 200.129.202.132 -j mangle --mangle-ip-s 200.129.202.130
# ifconfig eth0:1 200.129.202.132 netmask 255.255.255.128

com isso as requisições arp não serão respondidas pelo servidor real, mas quando o pacote foi respondido para o cliente, ele vai com a marcação correta no cabeçalho do pacote ip.

Utilizando keepalived para garantir estabilidade

O KeepAlived é uma ferramenta que garante uma boa saúde para o seu pool e ele possui algumas funcionalidades nativas interessantes como:

  • Redundância de diretores, ou seja, se o mestre sair do ar, o slave vai assumir
  • Saúde dos servidores reais, ou seja, se um servidor real deixar de responder por um serviço ou sair do ar, ele será automaticamente removido do pool
  • Aviso constante, caso algo aconteça ao seu pool (como as duas atividades acima), você poderá ser notificado por email

Dito isso, vamos instalar os pacotes necessários:

# apt-get install keepalived

Por padrão não é instalado nenhuma configuração default, por isso, é recomendado fortemente que você leia os exemplos que vem junto com o pacote. Vamos sugerir aqui uma configuração para 2 servidores diretores e os mesmos 3 servidores do exemplo anterior.

No diretor MASTER a configuração do arquivo keepalived.conf vai ficar:

# vim /etc/keepalived/keepalived.conf
# Global Configuration
global_defs {
  notification_email {
    seu_email_pessoal@exemplo.com.br
  }
  notification_email_from gerente_pool@exemplo.com.br
  smtp_server localhost
  smtp_connect_timeout 30
  router_id LVS_MASTER
}
vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router_id 10
  priority 100
  authentication {
    auth_type PASS
    auth_pass SENHA_QUALQUER
  }
  virtual_ipaddress {
    200.129.202.135/25
  }
}
virtual_server 200.129.202.135 80 {
  delay_loop 15
  lb_algo rr
  lb_kind NAT
  persistence_timeout 60
  protocol TCP

  real_server 172.16.0.2 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 172.16.0.3 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 172.16.0.4 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }

Neste exemplo, colocamos o IPV (ip virtual) como 200.129.202.135, ao invés do 200.129.202.132, para que vocês entendam que o IP poderia ser qualquer outro IP e não o IP da interface eth0 necessariamente, e após iniciar o keepalived podemos confirmar que o IP está vinculado a eth0 (mesmo que não apareça no ifconfig):

# /etc/init.d/keepalived start

Note que o IP foi configurado corretamente na interface:

# ip addr list dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether d8:d3:85:a1:53:a2 brd ff:ff:ff:ff:ff:ff
    inet 200.129.202.132/25 brd 200.129.192.127 scope global eth0
    inet 200.129.202.135/25 scope global secondary eth0
    inet6 fe80::dad3:85ff:fea1:53a2/64 scope link 
       valid_lft forever preferred_lft forever

Agora a configuração do diretor SLAVE:

# vim /etc/keepalived/keepalived.conf
# Global Configuration
global_defs {
  notification_email {
    seu_email_pessoal@exemplo.com.br
  }
  notification_email_from gerente_pool@exemplo.com.br
  smtp_server localhost
  smtp_connect_timeout 30
  router_id LVS_BACKUP
}
vrrp_instance VI_1 {
  state BACKUP
  interface eth0
  virtual_router_id 10
  priority 50
  authentication {
    auth_type PASS
    auth_pass SENHA_QUALQUER
  }
  virtual_ipaddress {
    200.129.202.135/25
  }
}
virtual_server 200.129.202.135 80 {
  delay_loop 15
  lb_algo rr
  lb_kind NAT
  persistence_timeout 60
  protocol TCP

  real_server 172.16.0.2 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 172.16.0.3 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }
  real_server 172.16.0.4 80 {
    TCP_CHECK {
      connect_timeout 3
    }
  }

Alguns detalhes são importantes no SLAVE, primeiro a estado do servidor é BACKUP, embora o conceito seja de SLAVE, a palavra reservada é BACKUP. O segundo detalhe importante é que as máquinas de BACKUP devem ter sua prioridade (priority) inferior ao servidor MASTER. Agora é só testar removendo IPs e servidores reais ou adicionando outros e testar as funcionalidades do KeepAlived.


--Brivaldo 21h04min de 27 de junho de 2011 (AMT)