Balanceamento de Link

Mário Augusto Souza Nunes
07-12-2003



Balanceamento de Link

Introdução

Neste artigo estarei falando um pouco sobre balanceamento de Link, ou seja como utilizar 2 ou mais links em uma mesma conexao, tambem estarei falando um pouco sobre os diversos modulos do kernel que podem no ajudar a solucionar problemas de sobre carga em servidores, um exemplo é o modulo bonding que nos permite agrupar interfaces de rede e balancear a carga e aliviar o servidor.

Distribuindo a carga

Uma coisa que aprendi durante os meus muitos anos de trabalho é que não adianta ter um belo servidor, uma boa rede, bons softwares ou mesmo bons programadores, se não pudermos utilizar os recursos do sistema ao maximo. Quando estamos trabalhando com grande quantidade de dados, acesso a grandes bancos de dados ou mesmo servidores departamentais ou de arquivo, sempre esbarramos num problema gargalo, toda vez que sobrecarregamos uma interface de rede ela começar a perder dados nisso perdemos desempenho pois é criado uma colisão e toda a rede para por alguns segundos, para solucionar isso o GNU/Linux possui um modulo bem interessante que nos permite agrupar diversas interfaces de rede e faze-las agir como se fossem uma unica interface, este modulo chama-se bonding.

Este modulo foi criado junto com o projeto beowulf por Donald Becker's, foi desenvolvido justamente para ambientes de alto desempenho como clusters, mas no entanto podemos utiliza-lo para melhor desempenho até mesmo em redes comuns como Lan Houses já que os games em rede hoje em dia demandam cada vez mais banda.

Carregando o modulo

Bem antes de mais nada temos de verificar se o kernel foi compilado com suporte a bonding, normalmente ele é colocado como modulo.

Para carregar utilizamos o famoso modprobe:

  # modprobe bonding

Caso seu sistema não possua este modulo você tera de recompilar o kernel. Para habilitar configure o kernel assim:

make config/menuconfig/xconfig e selecione "Bonding driver support" na sessão "Network Device Support". Prefira compilar este driver como modulo pois ainda é a unica forma de passarmos parametros a ele e assim criarmos mais de um dispositivo bonding.

Compile e instale o kernel.

Compilando o utilitario ifenslave.c

O responsavel por agrupar as interfaces de rede é o utilitario que acompanha o kernel o ifenslave.c.

Este utilitario você o encontra no diretório Documentation/network do seu fonte do GNU/Linux.

Para instalar o ifenslave.c execute:

  # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o 
  ifenslave
  # cp ifenslave /sbin/ifenslave

Configurando o sistema

A configuração do sistema não podia ser mais facil, inicialmente insira a seguinte linha no seu /etc/modules.conf ou /etc/conf.modules:

  alias bond0 bonding

Somente para teste vamos fazer um simples configuração, depois veremos como integrar esta solução permanentemente ao seu sistema. Apos adicionar a linha acima em seu arquivo de modulos, vamos executar os seguintes comandos para iniciar a interface:

  # ifconfig bond0 192.168.1.1 up
  # ifenslave bond0 eth0
  # ifenslave bond0 eth1

( Substitua 192.168.1.1 pelo ip de sua rede adicione tambem sua netmask caso sua configuração de rede exija.)

Com isso sua configuração basica para teste esta em funcionamento

Configurando distros baseadas em RedHat

Para começarmos verifique se realmente as configurações do arquivo modules.conf ou conf.modules.

O proximo passo é criar o arquivo de configuração da interface de rede bond0, nas modernas distribuições baseadas em Red Hat crie o arquivo de configuração ifcfg-bond0 em /etc/sysconfig/network-scripts, ele deve se parecer com isto:

  DEVICE=bond0
  IPADDR=192.168.1.1
  NETMASK=255.255.255.0
  BROADCAST=192.168.1.255
  ONBOOT=yes
  BOOTPROTO=none
  USERCTL=no

(Lembre-se ajuste as configurações de acordo com sua rede, isto é apenas um exemplo).

Todas as interfaces que farão parte do trunk, devem possuir as definições MASTER e SLAVE. Por exemplo, no caso da Red Hat, se você desejar que as interfaces eth0 e eth1 façam parte da interface bonding bond0, os arquivos de configuração (ifcfg-eth0, ifcfg-eth1, etc), devem se parecer com isto:

  DEVICE=eth0
  USERCTL=no
  ONBOOT=yes
  MASTER=bond0
  SLAVE=yes
  BOOTPROTO=none

Agora reinicie o subsistema de redes ou somente levante o dispositivo bonding, ou mesmo reinicie o sistema. Em sistemas baseados em Red Hat utilize somente "ifup bond0" ou "/etc/rc.d/init.d/network restart".

Se as ferramentas de administração de sua distribuição não suportarem as notações MASTER/SLAVE nos arquivos de configuração sera necessario executar os passos abaixo:

  # ifconfig bond0 192.168.1.1 up
  # ifenslave bond0 eth0
  # ifenslave bond0 eth1

( Lembre de configurar sua interface de acordo com sua rede local, configurando endereço ip, netmask etc...)

Parâmetros do Módulo

Este são os parametros que podem ser passados ao modulo, certos parametros são essenciais para o bom funcionamento do sistema:

mode=

Os valores possiveis são:

0 Round-Robin 1 Active backup 2 XOR

miimon=

Use um valor inteiro para determinar a frequencia (em ms) para o MII Link Monitor. O valor zero é padrão tornando o sistema de monitoramento desabilitado. Um bom valor para ser usando se for utiliza o monitoramento de Link é 100.

downdelay=

Use um valor inteiro para o tempo de desativação do link (em ms) no caso de que seja detectado uma falha no link. Utilize um multiplo do miimon. O valor padrão é 0.

updelay=

Use um valor inteiro para o tempo de reativação do link (em ms) caso seja detectado o link esteja ativo. Utilize um multiplo de miimon. O valor padrão é 0.

arp_interval=

Use um valor inteiro para o tempo (em ms) de monitoramento arp. O valor zero nos diz que o o monitoramento esta desativado.

arp_ip_target=

Um endereço ip para uso caso arp_interval seja > 0. Este é o endereço utilizado para verificar se o host está ativo. Especifique o formato assim xxx.xxx.xxx.xxx.

Alta Disponibilidade - HA

Para se implementar alta disponibilidade utilizando bonding, é necessario que você compile o driver como modulo pois e a unica forma de se passar parametros a ele, isto deve ser mudado no futuro.

Um requisito para a Alta Diponibilidade é verificar se sua placa de rede possui suporte a MII link status, a partir do Kernel 2.2.17 todas as interfaces de 100Mbps possuem suporte em seus drivers, tambem as interfaces gigabit possuem suporte em seus drivers. Se seu sistema não possui suporte provavelmente ela não será detectada!

O Driver bonding regularmente checa todas as interfaces escravas (SLAVE) checando o status do registrador MII. O intervalo da checagem é especificado pelo argumento do modulo "miimon" (Monitoramento MII).

Exemplo:

# modprobe bonding miimon=100

ou adicione em se arquivo de modulos, modules.conf ou conf.modules:

  alias bond0 bonding
  options bond0 miimon=100

Atualmente a duas possibilidades para a Alta Diponibilidade, dependendo do caso.

a) O host é conectado a outro host ou switch que suporte trucking. b) O host é conectado a varios switches diferentes ou a um unico switch que não suporte trucking.

Possiveis usos e configurações

Introdução

Neste etapa estarei discutindo os principais usos deste tipo de configuração para que se possa obter o maximo desempenho de seu hardware.

HA em um unico switch ou host (Load Balancing)

Esta é a forma mais simples de configurar e entender. Simplesmente configure o equipamento remoto (host ou switch) para agregar o trafego sobre varias portas (Trunk, EtherChannel, etc.) e configure a interface bonding. Se o modulo for carregado corretamente com as opções do MII, ele ira funcionar automaticamente.

Exemplo 1 : De host para Host velocidade duplicada

            +----------+                          +----------+
            |          |eth0                  eth0|          |
            | Host A   +--------------------------+  Host B  |
            |          +--------------------------+          |
            |          |eth1                  eth1|          |
            +----------+                          +----------+

Em ambos os hosts :

       # modprobe bonding miimon=100
       # ifconfig bond0 addr
       # ifenslave bond0 eth0 eth1

Exemplo 2 : Host para switch com velocidade duplicada

            +----------+                          +----------+
            |          |eth0                 port1|          |
            | Host A   +--------------------------+  switch  |
            |          +--------------------------+          |
            |          |eth1                 port2|          |
            +----------+                          +----------+

    No host A :                                No switch :
       # modprobe bonding miimon=100           # Configure trunk para Port1
       # ifconfig bond0 addr                     e port2
       # ifenslave bond0 eth0 eth1

HA em 2 ou mais switches (ou num unico switch sem suporte a trucking)

Este modo é o mais problematico por causa que existem diversas portas e apenas um endereço MAC é visto nas portas. É possivel solucionar este problema, como será utilizado links de backup, basta setar com o ifconfig as interfaces para NOARP.

Para se usar este modo, passe para o modulo a opcao mode=1:

# modprobe bonding miimon=100 mode=1

Ou atualize seu arquivo de modulo modules.conf ou conf.modules para:

  alias bond0 bonding
  options bond0 miimon=100 mode=1

Exemplo 1: Usando multiplos hosts e multiplos switches para criar uma solução "no single point of failure".

  
                  |                                     |
                  |port3                           port3|
            +-----+----+                          +-----+----+
            |          |port7       ISL      port7|          |
            | switch A +--------------------------+ switch B |
            |          +--------------------------+          |
            |          |port8                port8|          |
            +----++----+                          +-----++---+
            port2||port1                           port1||port2
                 ||             +-------+               ||
                 |+-------------+ host1 +---------------+|
                 |         eth0 +-------+ eth1           |
                 |                                       |
                 |              +-------+                |
                 +--------------+ host2 +----------------+
                           eth0 +-------+ eth1
  
  			 
  		
Nesta configuração possuimos um ISL - Inter Switch Link (Isto não é trunk), os servidores (host1, host2 ...) estão atachados a ambos os switches e uma ou mais portas estão ligadas ao mundo externo ou a outro segmento da rede (port3). apenas uma porta escrava (SLAVE) é ativa o tempo todo, enquantos todos os demais links são monitorados (o sistema ao detectar uma falha automaticamente ira acionar o link de backup (mode=1)).

No caso acima você pode ver que temos dois hosts que estão sendo utilizando em load balancing, por outro mecanismo externo, isto é muito bom pois temos ambos os hosts ligados a diferentes switch isto indica que ao sistema falhar, temos um segundo host conectado a ambos os switchers (não adianta nada se ouver uma falha na alimentação dos switchers pois ambos irão parar portanto seja precavido).

Exemplo 2: Usando multiplas interfaces ethernet conectadas ao switch para configurar um NIC failover (não é requerido que o switch possua suporte a trunking).

            +----------+                          +----------+
            |          |eth0                 port1|          |
            | Host A   +--------------------------+  switch  |
            |          +--------------------------+          |
            |          |eth1                 port2|          |
            +----------+                          +----------+

    No host A :                                 No switch :
       # modprobe bonding miimon=100 mode=1     # (opcional) minimize o tempo
       # ifconfig bond0 addr                    # para expiração da tabela.
       # ifenslave bond0 eth0 eth1

Adaptando para o timing do switches

Se o seu switch demanda um longo tempo para entrar em modo Backup, isto pode fazer com que o seu link de backup não torne-se ativo, pode ser necessário dar um "delay" na inicialização do Link de Backup até que o switch volte a ativa, para isso utilizamos o parametro "downdelay" em milisegundos, lembre que tem de ser um multiplo de miimon.

Outro problema pode ocorrer caso o link de backup torne-se ativo antes que seu switch reinicie por completo, neste caso utilizamos o parametro "updelay", este parametro fara que apos a inicialização do switch ele espere por um tempo para tornar-se realmente ativo.

Uma situação similar costuma acontecer quanto fazemos a troca de cabos e o host passa a renegociar o link com o host.

Um caso bem especial se diz respeito quando o host perde todos os seus links escravos (SLAVE). Neste caso ele automaticamente reutilizara o primeiro link que se tornar ativo. Isto é importante pois diminui o tempo parado assim aumentando a disponibilidade do sistema.

Alguns exemplos:

  # modprobe bonding miimon=100 mode=1 downdelay=2000 updelay=5000
  # modprobe bonding miimon=100 mode=0 downdelay=0 updelay=5000

Links e Informações

Atual site do driver bonding:


$Revision: 1.6 $