sábado, 25 de fevereiro de 2012

Bonding – Juntando interfaces de rede no Linux



Descrição do recurso
Conforme descrito na documentação do kernel do Linux, o driver bonding é utilizado para agregar múltiplas interfaces de rede em uma interface lógica única. Seu comportamento depende da necessidade e da estrutura física da rede. Então, apesar de ser uma tarefa bastante simples e bem divulgada, dificilmente encontra-se um artigo que cite o melhor modo para cada condição.
Principais modos de configuração
Há dois modos principais de configuração do bonding, sendo soma do link oumodo backup, chamados de balance-rr (balance round robin) e active backuprespectivamente. Nesse link estão descritos absolutamente todas as configurações de bonding incluindo alguns exemplos de configuração distribuidos pelo arquivo, mas esse post tratará apenas dos modelos descritos anteriormente.

No modelo acima, um host soma duas interfaces físicas em uma interface lógica, que chamaremos de bond0. Uma das interfaces será conectada a um switch e a outra interface a outro switch. Nesse modelo explicitamente deseja-se tolerância a falhas, então baseado nisso pode-se assimilar esse modelo da infra-estrutura com o modo de configuração active-backup (1), devido ao fluxo de dados distinto, onde a segunda interface de rede entrará em ação somente em caso de falha da primeira.
* Se houver interconexão dos switches (ISL), é seguro optar por active-backup.
* Se os switches não forem interconectados e as redes forem completamente independentes, então deve-se utilizar o modo broadcast.
Vejamos agora outro modelo:

No modelo acima o destino de ambas as interfaces seguem por um mesmo caminho. Há tolerância a falha nesse modelo, mas é visível que se pode somar os links para fazer um melhor aproveitamento dos recursos em caso de fluxo intenso. Apesar dessa vantagem, há um custo para sua utilização, que é a recepção desordenada dos pacotes, forçando retransmissões.
Um tunning pode ser feito alterando net.ipv4.tcp_reordering (sysctl). A velocidade de reordenação depende de diversos fatores físicos (infra-estrutura) e ficaria extenso demais gerar hipóteses aqui.
Se houver tráfego de UDP, deve-se considerar que a aplicação possa receber os dados desordenadamente, caso contrário não é recomendado a utilização da soma do link para aumentar o throughput.
Por fim, para a utilização desse modelo é necessário que o switch esteja com as respectivas portas em ‘etherchannel’ ou ‘trunking’, dependendo da marca.
Utilizando o modo active-backup não é necessário nenhuma configuração no switch, porque a interface de bonding faz spoofing do MAC da interface utilizada como mestre e ambas chegarão aos switches com o mesmo MAC. Em modo active-backup não há risco de conflito na tabela ARP dos switches porque a interface escrava só se tornará ativa em caso de falha da outra interface.
Configurando bonding
Já fiz essa configuração em diferentes sistemas em algumas empresas; não há restrições de uso para distribuições baseadas em Debian ou RedHat, mas as configurações em arquivos mudam de uma plataforma para outra, então o exemplo utilizado servirá para ambas, com configuração através de comandos que podem ser colocados em um rc que carregue após o sistema. Em caso de OpenSuse, pode-se colocá-lo em /etc/init.d/after.local; em Debian em /etc/rc.local e em RedHat em /etc/init.d/rc.local. Além disso, exemplificarei a configuração em arquivos padrão do sistema Debian.
Primeiramente será necessário carregar o módulo bonding. Ele aceita diversos parâmetros. Sua carga pode (e preferencialmente DEVE) ser feita através do arquivo /etc/modules.conf. O alias bond0 é uma convenção, poderia ter outro nome mas é comumente configurado assim:

#modelo de rede 1
alias bond0 bonding
options bond0 mode=1 miimon=100 downdelay=200 updelay=200
O parâmetro mode especifica o modo de operação da interface; balance-rr (0), active-backup (1), broadcast (3) etc.
O parâmetro miimon especifica o intervalo de monitoramento do link em milisegundos. O valor 100 é recomendado na documentação do kernel. Se o valor for 0, não haverá monitoramento do link.
O parâmetro downdelay especifica o tempo para derrubar uma interface em caso de falha. Esse valor deve ser múltiplo do parâmetro miimon.
O parâmetro updelay especifica o tempo para levantar a interface escrava. O valor também deve ser múltiplo de miimon e preferencialmente idêntico ao valor de downdelay, mas nunca menor.
Para levantar o módulo manualmente, utilize:

modprobe bonding -o miimon=100 mode=1 downdelay=200 updelay=200
O segundo passo é levantar as interfaces de rede sem IP e a interface de bonding. As interfaces físicas não receberão IP porque haverá apenas 1 para ambas as interfaces e esse IP estará configurado na interface bond0, como descrito abaixo:

ifconfig eth0 0.0.0.0 up
ifconfig eth1 0.0.0.0 up
ifconfig bond0 10.0.0.2 netmask 255.255.255.0 up
#nesse ponto pode-se já configurar o gateway também. Ex.:
route add default gw 10.0.0.1
route add -net 172.0.0.0/24 gw 10.0.0.254
#etc
Na parte de configuração de interface, finaliza-se atribuindo as interfaces ao bonding bond0:

ifenslave bond0 eth0 eth1
Perceba que isso indica que duas interfaces fazem parte do bond0. Seria possível ter mais interfaces bonding, tudo depende da disponibilidade física e necessidade.
Configurando o /etc/network/interfaces do Debian
Em Debian, o arquivo controlador de interfaces é o /etc/network/interfaces. Em openSuse e RedHat as configurações são distribuidas em arquivos em /etc/syconfig/network-scripts/, tal como ifcfg-eth0 etc.
Se os comandos anteriores forem colocados em algum script de startup, tudo deve funcionar tal como feito manualmente e servirá para qualquer uma destas distribuições Linux, mas gosto de deixar tudo ajeitado no Debian:

auto bond0
iface bond0 inet static
  address 10.0.0.2
  netmask 255.255.255.0
  gateway 10.0.0.1
  bond-slaves none
  bond-mode active-backup
  bond-miimon 100
  bond-downdelay 200
  bond-updelay 200

auto eth0
iface eth0 inet manual
  bond-master bond0
  bond-primary eth0 eth1

auto eth1
iface eth1 inet manual
  bond-master bond0
  bond-primary eth0 eth1

Se por algum motivo quiser consultar as configurações do bonding via scripts (ou por qualquer outro motivo que seja), os dados se encontrarão em /sys/class/net/bond0/bonding/ . Por exemplo, o arquivo /sys/class/net/bond0/bonding/mode contém o modo de operação do bond0.
Basicamente, é isso; diversão garantida!

2 comentários:

  1. Seria possível essa mesma configuração com dois links adsl's num firewal?
    Neste caso, acho que para funcionar, os ips de gw e dns dos dois modems teria que ser iguais, certo?

    ResponderExcluir
  2. Olá, Marllus.
    Nesse caso, você está querendo fazer soma dos links de entrada. Isso pode ser feito com uma junçao de iptables e roteamento avançado. Em uma pesquisa rápida encontrei uma receita-de-bolo. Veja se te serve. Abraços!
    http://under-linux.org/f227/jeito-simples-juntar-2-links-127340/

    ResponderExcluir