Вы находитесь на странице: 1из 6

Balanceamento de carga e alta disponibilidade

com Bonding driver e Iproute2

LIMITAES, PROBLEMAS E NECESSIDADES

O balanceamento de links com o Iproute 2 tem alguns inconvenientes, quando a


coisa entra no campo da alta disponibilidade dado ao fato que o cache de rotas
vinculado a cada uma das interfaces de rede lgicas, ento faz-se necessrio o
emprego de scripts para testar o estado das conexes, excluir rotas inoperantes,
limpar o cache e conforme o caso alterar marcas de pacotes, o resultado alm de
ser uma gambiara muito deselegante pouco eficiente.

O Bonding Driver por sua vez excelente no balanceamento e redundncia, porm


no usado para manipular rotas, visto que trabalha unicamente na camada 2,
semelhante as bridges, na verdade foi desenvolvido para aumentar a largura de
banda de conexes de controle em Clusters Beowulf e o seu criador no pensava
em aplica-lo para a finalidade que proponho.

A NECESSIDADE

Durante um bom tempo empreguei o balanceamento de carga com Iproute 2 e


marca de pacotes, desviando o trfego por cada rota de acordo com a
convenincia de cada cliente, mas de uns anos para c o perfil de utilizao da
internet mudou muito.

A alguns anos eu atribua uma marca para o trfego podre (P2P, etc. Na verdade
tudo) com uma exceo para o trfego nobre (http, https e DNS), para que sasse
pela rota default, a coisa as vezes mudava um pouco dependendo de nmero de
links e tipos de servio mas basicamente era a mesma coisa.

Mas o perfil de uso da internet mudou, e o que era nobre acabou apodrecendo,
principalmente por conta do contedo dinmico de sites como o Youtube que
quase tornaram o bom e velho Squid obsoleto, sendo necessrio o emprego de
solues de url rewriter que trabalham em conjunto com o Squid, tais como
o Thundercache e o InComum (este ltimo excelente e muito fcil de
implementar, venho usando ele a mais de 1 ano com muita satisfao!
Recomendo!http://incomum.sourceforge.net).

Recentemente tive que rever a poltica de balanceamento de carga de um de


meus clientes e deparei-me com os problemas que mencionei acima ento resolvi
contorn-lo com o emprego do iproute2 usando uma nica interface de rede, o
resultado foi sofrvel.

Embora conceitualmente correto, e at funcionou muito bem em testes com


mquinas virtuais, as causas no tive tempo nem recursos para avaliar. At
suspeito de alguma implementao em um de seus roteadores algo como um
rp_filter ou algum mecanismo anti-spoof, mas no foi possvel constatar visto que
seus roteadores esto sob regime de comodato e no tenho acesso a eles.

Ento parti para uma bridge agregando as interfaces de rede de sada, funcionou
relativamente bem, entretanto a rede apresentava latncia alta e alguma
instabilidade quando o trfego aumentava e a redundncia no funcionou.

Foi a que me ocorreu ao invs de empregar uma bridge empregar o Bonding


Driver nativo do Kernel, afinal ele foi feito para isso! Para alegria de todos os
resultados foram excelentes tanto para o balanceamento quanto para a
redundncia!

IMPLEMENTANDO O BONDING

Primeiramente verifique se o Bonding Driver est compilado como mdulo em seu


sistema, com o comando:

#modprobel|grepbonding

A sada dever ser:

kernel/drivers/net/bonding/bonding.ko

Caso o mdulo no esteja presente ser preciso recompilar o Kernel e marcando-o


como mdulo, pois isso facilita e muito a passagem de parmetros ao mdulo
durante seu carregamento, se compila-lo como built-in, isso precisar ser feito via
sysfs. No mencionarei detalhes acerca de compilao do Kernel por fugir ao
objetivo do artigo.
Agora vamos configurar o bonding com o comando:

#modprobebondingmode=balancerrmiimon=1000
arp_ip_target=xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy

Onde xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy so os endereos IP dos roteadores. O


parmetro miimon especificado em milisegundos e verifica o estado dos links
com requisies ARP e o parmetro mode define qual ser o modo de operao do
bonding, em nosso caso empreguei o round-robin.

Mais detalhes sobre estes tpicos e outros podem ser verificados na


documentao do Bonding Driver nos fontes do Kernel, o path
/usr/src/linux/Documentation/networking/bonding.txt. Neste mesmo diretrio
encontramos o fonte doifenslave o utilitrio que manipula o bond que dever ser
compilado com o seguinte comando:

#gccWallOI/usr/src/linux/includeifenslave.coifenslave

Agora copiaremos o binrio executvel para um diretrio que esteja no PATH:

#cp/usr/src/linux/Documentation/networking/ifenslave/usr/sbin/

Agora vamos especificar o endereo MAC do bonding:

#ifconfigbond0hwether00: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
fsicas pois o bonding pegara o endereo da primeira interface a ser adicionada.
Podem estranhar eu haver atribudo o mesmo MAC para ambas as interfaces mas
isso tem um propsito, como os roteadores apresentavam restries ARP, se no
futuro eu precisar trocar ou inverter a ordem das interfaces de rede simplifica e
muito a tarefa:

#ifconfigeth1hwether00:12:ab:30:ae:9b
#ifconfigeth2hwether00: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
fsicas, que devem estar em modo promscuo mas apenas elas e no o bonding.

#ifconfigbond0up
#ifconfigeth2uppromisc
#ifconfigeth1uppromisc

Agregamos as interfaces ao bonding:

#ifenslavebond0eth1eth2

Atribuiremos os endereos IPs de ambas as operadoras ao bonding:

#ipaddraddxxx.xxx.xxx.xxA/30brd+devbond0
#ipaddraddyyy.yyy.yyy.yyyA/28brd+devbond0

Pronto! Agora temos um bonding totalmente funcional, falta agora apenas


implementar o roteamento avanado onde inclusive dimensionaremos o peso de
cada um dos links visto que so de velocidades diferentes.

O ROTEAMENTO AVANADO

Primeiramente vamos definir as tabelas de roteamento no arquivo


/etc/iproute2/rt_tables:

#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
252 operadora0
251 operadora1

As chamaremos de operadora0 e operadora1, afinal o VOL no ganha um tosto


delas para fazer propaganda! Rsssss.

Agora vamos acrescentar as rotas na tabela de roteamento:

Primeiro, limpar qualquer rota existente no cache: #iprouteflushcache;ip


routeflushcached

Finalmente acrescentar as rotas, para operadora0:

#iprouteadddefaultviaxxx.xxx.xxx.xxxdevbond0tableoperadora0
#iprouteaddxxx.xxx.xxx.xxAviaxxx.xxx.xxx.xxxtableoperadora0
#ipruleaddfromxxx.xxx.xxx.xxAtableoperadora0

Para operadora1:

#iprouteadddefaultviayyy.yyy.yyy.yyydevbond0tableoperadora1
#iprouteaddyyy.yyy.yyy.yyAviaxxx.xxx.xxx.xxxtableoperadora1
#ipruleaddfromyyy.yyy.yyy.yyAtableoperadora1

E finalmente vamos definir as rotas default:

#iprouteadddefaultscopeglobalnexthopviaxxx.xxx.xxx.xxxdev
bond0weight67nexthopviayyy.yyy.yyy.yyydevbond0weight33

Onde xxx.xxx.xxx.xxx e yyy.yyy.yyy.yyy so os endereos dos roteadores e


xxx.xxx.xxx.xxA e yyy.yyy.yyy.yyA so os endereos do host.

Os pesos:

Notaram os parmetros weight 67 e weight 33 acima? Pois ! Ocorre o seguinte:

Temos dois links de velocidades diferentes o primeiro de 2Mbit/s e segundo de


4Mbit/s logicamente a soma de ambos d 6Mbit/s, ento fazemos a seguinte
conta, 2 + 4 = 6 (4 / 6)*100 = 66,66% aredondamos para 67, 100 - 67 = 33.

Resumindo o link de 2Mbit/s corresponde a 33% da soma de ambos e o de 4Mbit/s


67% da soma de ambos. Se ambos fossem da mesma velocidade bastaramos
especificar o peso de cada um como igual a 1.
E agora limparemos o cache de rotas novamente!

#iprouteflushcache;iprouteflushcached

Para a redundncia funcionar corretamente o bonding requer que todas as


interfaces agregadas e os roteadores das operadoras estejam conectados em um
mesmo switch.