Balanceamento de carga e alta disponibilidade com Bonding Driver e Iproute2
Tem muita coisa sobre o assunto mas tanto o Bonding Driver quanto o Iproute 2 se mostram um tanto incompletos para a tarefa, então juntei ambos em uma solução muito simples e eficaz como reza o preceito da Escola Russa.
Parte 2: Implementando o Bonding
Primeiramente verifique se o Bonding Driver está compilado como módulo em seu sistema, com o comando:
# modprobe -l | grep bonding
A saída deverá ser:
kernel/drivers/net/bonding/bonding.ko
Caso o módulo não esteja presente será preciso recompilar o Kernel e marcando-o como módulo, pois isso facilita e muito a passagem de parâmetros ao módulo durante seu carregamento, se compila-lo como built-in, isso precisará ser feito via sysfs. Não mencionarei detalhes acerca de compilação do Kernel por fugir ao objetivo do artigo.
Agora vamos configurar o bonding com o comando:
# modprobe bonding mode=balance-rr miimon=1000 arp_ip_target=xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy
Onde xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy são os endereços IP dos roteadores. O parâmetro miimon é especificado em milisegundos e verifica o estado dos links com requisições ARP e o parâmetro mode define qual será o modo de operação do bonding, em nosso caso empreguei o round-robin.
Mais detalhes sobre estes tópicos e outros podem ser verificados na documentação do Bonding Driver nos fontes do Kernel, o path é /usr/src/linux/Documentation/networking/bonding.txt. Neste mesmo diretório encontramos o fonte do ifenslave o utilitário que manipula o bond que deverá ser compilado com o seguinte comando:
# gcc -Wall -O -I/usr/src/linux/include ifenslave.c -o ifenslave
Agora copiaremos o binário executável para um diretório que esteja no PATH:
# cp /usr/src/linux/Documentation/networking/ifenslave /usr/sbin/
Agora vamos especificar o endereço MAC do bonding:
# ifconfig bond0 hw ether 00:12:ab:30:ae:9b
Como eu tive problemas com os roteadores do cliente, conforme mencionado acima, fiz diferente. Especifiquei primeiramente o MAC das interfaces de rede físicas pois o bonding pegara o endereço da primeira interface a ser adicionada. Podem estranhar eu haver atribuído o mesmo MAC para ambas as interfaces mas isso tem um propósito, como os roteadores apresentavam restrições ARP, se no futuro eu precisar trocar ou inverter a ordem das interfaces de rede simplifica e muito a tarefa:
# ifconfig eth1 hw ether 00:12:ab:30:ae:9b
# ifconfig eth2 hw ether 00:12:ab:30:ae:9b
Agora vamos levantar as interfaces de rede e o bonding. Atentem que a ordem é importante, o bond0 deve ser levantado primeiro e depois disso as interfaces físicas, que devem estar em modo promíscuo mas apenas elas e não o bonding.
# ifconfig bond0 up
# ifconfig eth2 up promisc
# ifconfig eth1 up promisc
Agregamos as interfaces ao bonding:
# ifenslave bond0 eth1 eth2
Atribuiremos os endereços IPs de ambas as operadoras ao bonding:
# ip addr add xxx.xxx.xxx.xxA/30 brd + dev bond0
# ip addr add yyy.yyy.yyy.yyyA/28 brd + dev bond0
Pronto! Agora temos um bonding totalmente funcional, falta agora apenas implementar o roteamento avançado onde inclusive dimensionaremos o peso de cada um dos links visto que são de velocidades diferentes.
# modprobe -l | grep bonding
A saída deverá ser:
kernel/drivers/net/bonding/bonding.ko
Caso o módulo não esteja presente será preciso recompilar o Kernel e marcando-o como módulo, pois isso facilita e muito a passagem de parâmetros ao módulo durante seu carregamento, se compila-lo como built-in, isso precisará ser feito via sysfs. Não mencionarei detalhes acerca de compilação do Kernel por fugir ao objetivo do artigo.
Agora vamos configurar o bonding com o comando:
# modprobe bonding mode=balance-rr miimon=1000 arp_ip_target=xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy
Onde xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy são os endereços IP dos roteadores. O parâmetro miimon é especificado em milisegundos e verifica o estado dos links com requisições ARP e o parâmetro mode define qual será o modo de operação do bonding, em nosso caso empreguei o round-robin.
Mais detalhes sobre estes tópicos e outros podem ser verificados na documentação do Bonding Driver nos fontes do Kernel, o path é /usr/src/linux/Documentation/networking/bonding.txt. Neste mesmo diretório encontramos o fonte do ifenslave o utilitário que manipula o bond que deverá ser compilado com o seguinte comando:
# gcc -Wall -O -I/usr/src/linux/include ifenslave.c -o ifenslave
Agora copiaremos o binário executável para um diretório que esteja no PATH:
# cp /usr/src/linux/Documentation/networking/ifenslave /usr/sbin/
Agora vamos especificar o endereço MAC do bonding:
# ifconfig bond0 hw ether 00:12:ab:30:ae:9b
Como eu tive problemas com os roteadores do cliente, conforme mencionado acima, fiz diferente. Especifiquei primeiramente o MAC das interfaces de rede físicas pois o bonding pegara o endereço da primeira interface a ser adicionada. Podem estranhar eu haver atribuído o mesmo MAC para ambas as interfaces mas isso tem um propósito, como os roteadores apresentavam restrições ARP, se no futuro eu precisar trocar ou inverter a ordem das interfaces de rede simplifica e muito a tarefa:
# ifconfig eth1 hw ether 00:12:ab:30:ae:9b
# ifconfig eth2 hw ether 00:12:ab:30:ae:9b
Agora vamos levantar as interfaces de rede e o bonding. Atentem que a ordem é importante, o bond0 deve ser levantado primeiro e depois disso as interfaces físicas, que devem estar em modo promíscuo mas apenas elas e não o bonding.
# ifconfig bond0 up
# ifconfig eth2 up promisc
# ifconfig eth1 up promisc
Agregamos as interfaces ao bonding:
# ifenslave bond0 eth1 eth2
Atribuiremos os endereços IPs de ambas as operadoras ao bonding:
# ip addr add xxx.xxx.xxx.xxA/30 brd + dev bond0
# ip addr add yyy.yyy.yyy.yyyA/28 brd + dev bond0
Pronto! Agora temos um bonding totalmente funcional, falta agora apenas implementar o roteamento avançado onde inclusive dimensionaremos o peso de cada um dos links visto que são de velocidades diferentes.
Gostei de sua idéia, pensei em algo parecida há um tempo atrás e não consegui implementar. Mas você conseguiu juntar muito bem os links.
Parabéns, espero que faça muitos outros assim.