Balanceamento de 3 links com redundância no Linux

Introdução

Seguindo a sequência dos artigos sobre balanceamento e redundância, segue o script atualizado e modificado para uso de três links de internet.

Referência:

Últimas modificações:

  1. Balanceamento de 3 links + Redundância para os 3 links;
  2. Data e Hora dos eventos;
  3. Modificação nas regras para marcar e desmarcar rotas.

Funcionamento:

1. Se cair um link, ele continua fazendo o balanceamento entre 2 links.

2. Caso caiam 2 links, a rede continua funcionando em 1 link.

3. *Soma dos links, é feita da seguinte maneira: 1ª conexão estabilizada pelo link 1, 2ª conexão estabilizada pelo link 2, 3ª conexão estabilizada pelo link 3; estamos usando peso 1:1:1.

4. Os serviços podem ser divididos e remanejados para determinados links usando regras de marcação.

5. Este método de balanceamento e redundância só serve como saída para a Internet.

* Use um programa do tipo download manager que possa dividir o arquivo em partes para testar.

Modificando as tabelas e rotas

Modificando as tabelas e rotas, mudanças em negrito.

1. Acrescente no arquivo rt_tables:

1 gvt
2 brt
3 net

2. Acrescente a nova rota para os três links, abaixo incluo a regra no arquivo rc.local:

ip route flush table gvt #Limpa as rotas no cache da tabela gvt

ip route flush table brt #Limpa as rotas no cache da tabela brt

ip route flush table net #Limpa as rotas no cache da tabela net

ip route add 192.168.1.0/24 dev eth1 src 192.168.1.10 table gvt
ip route add default via 192.168.1.1 table gvt

ip route add 192.168.2.0/24 dev eth2 src 192.168.2.10 table brt
ip route add default via 192.168.2.1 table brt

ip route add 192.168.3.0/24 dev eth3 src 192.168.3.10 table net
ip route add default via 192.168.3.1 table net

ip rule add from 192.168.1.10 table gvt
ip rule add from 192.168.2.10 table brt
ip rule add from 192.168.3.10 table net

#Esta regra abaixo é responsável pelo balanceamento, vamos dividir a saída com peso 2:1:1, vamos supor que a gvt é 2x
mais rápida com link de 3 mega, link da brt com 1 mega, e link da net com 1 mega.

ip route add default scope global nexthop via 192.168.1.1 dev eth1 weight 2 nexthop via 192.168.2.1 dev eth2 weight 1
nexthop via 192.168.3.1 dev eth3 weight 1

ip route flush cache #Limpa as rotas no cache

Dicas

1. Caso queira trabalhar somente com dois links balanceados e três links redundantes, é necessário remover a regra de balanceamento “nexthop via 192.168.3.1 dev eth3 weight 1” dos arquivos “rc.local” e “gwping.sh”, nesse caso os três links ficarão fora do balanceamento.

2. Posso utilizar os três links que ficaram de fora do balanceamento usando a marcação de pacotes, neste caso os três links trabalharão especificamente para um serviço ou um destino, veja exemplo:

#A regra abaixo determina que toda rede interna balanceada irá acessar o Bradesco pelo 3 link:
iptables -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d bradesco.com.br -j MARK –set-mark 0x30

#A regra abaixo determina que toda rede interna balanceada irá acessar as portas 110(pop) e 25(smtp) pelo 3 link:
iptables -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport –dports 110,25 -j MARK –set-mark 0x30

3. Cuidado ao trabalhar com regras de marcação, como trabalhamos com redundância se algum link cair e não deletar a marcação feita para ele, o serviço ficará indisponível até o link voltar… para corrigir esse problema adicionei ao arquivo “gwping.sh” a regra para deletar a marcação do link que caiu… é necessário limpar a tabela mangle e adicionar as novas regras de marcação para quando o link voltar.

#Deleta marcação da tabela de roteamento:
ip rule del fwmark 0x30 lookup net prio 3

#Deleta as regras da tabela mangle:
iptables -F -t mangle
iptables -X -t mangle

Obs.: Não esqueça de desativar o balanceamento dos três links se for utilizá-los com marcação de pacotes, caso contrário não funcionará.

4. Na explicação anterior, para a chamada do script no arquivo rc.local, o comando nohup cria um arquivo “nohup.out” e isso gera um grande acúmulo de dados ocupando espaço desnecessário no HD, se esse log não for necessário para você, é possível desativá-lo acrescentando a opção > /dev/null o que jogará todo esse lixo para o buraco negro. Veja como ficaria a linha de comando:

# nohup > /dev/null /etc/link/gwping &

Script gwping.sh

#!/bin/bash -x

IPTABLES=/sbin/iptables

# Convencionalmente ” 0 ” indica sucesso neste script.

# Tempo entre verificações em segundos
SLEEPTIME=5

# Endereço IP ou nome de domínio para o ping. O roteiro baseia-se no domínio a ser pingável e sempre disponível.
TESTIP=200.98.249.120

# Ping Timeout em segundos.
TIMEOUT=3

# Interfaces externas.
EXTIF1=eth1
EXTIF2=eth2
EXTIF3=eth3

# Endereço IP de interfaces externas. Este não é o endereço do gateway.
IP1=192.168.1.10
IP2=192.168.2.10
IP3=192.168.3.10

# Gateway endereços IP. Este é o primeiro (hop) gateway, poderia ser o seu router IP endereço, se tiver sido configurado como o gateway.
GW1=192.168.1.1
GW2=192.168.2.1
GW3=192.168.3.1

# Pesos relativos de rotas. Guarde este para um baixo valor inteiro. Estou usando 1 para GVT porque é 3 vezes mais rápida.
W1=1
W2=1
W3=1

# Nome dos Provedores; utilizar os seus próprios nomes aqui.
NAME1=gvt
NAME2=brt
NAME3=net

# N º de repetições de sucesso ou fracasso antes de mudar status de conexão.
SUCCESSREPEATCOUNT=1
FAILUREREPEATCOUNT=4

## Não mudar nada abaixo desta linha.

# Última link status indica que a macro estado da ligação é determinada.
#Trata-se inicialmente em vigor estabelece encaminhamento mudança adiantado. Não alterar estes valores.
LLS1=1
LLS2=1
LLS3=1

# Última ping estado. Não alterar estes valores.
LPS1=1
LPS2=1
LPS3=1

# Ping atual estatuto. Não alterar estes valores.
CPS1=1
CPS2=1
CPS3=1

# Mudança link status indica que a ligação tem de ser mudado. Não alterar estes valores.
CLS1=1
CLS2=1
CLS3=1

# Conde de repetidos até estatuto ou para baixo estatuto. Não alterar estes valores.
COUNT1=0
COUNT2=0
COUNT3=0

while : ; do
ping -W $TIMEOUT -I $IP1 -c 1 $TESTIP > /dev/null  2>&1
RETVAL=$?

if [ $RETVAL -ne 0 ]; then
echo $NAME1 Down
CPS1=1
else
CPS1=0
fi

if [ $LPS1 -ne $CPS1 ]; then
echo `date +%x” “%X` Ping status changed for $NAME1 from $LPS1 to $CPS1
COUNT1=1
else
if [ $LPS1 -ne $LLS1 ]; then
COUNT1=`expr $COUNT1 + 1`
fi
fi

if [[ $COUNT1 -ge $SUCCESSREPEATCOUNT || ($LLS1 -eq 0 && $COUNT1 -ge $FAILUREREPEATCOUNT) ]]; then
echo `date +%x” “%X` Uptime status will be changed for $NAME1 from $LLS1
CLS1=0
COUNT1=0
if [ $LLS1 -eq 1 ]; then
LLS1=0
else
LLS1=1
fi
else
CLS1=1
fi

LPS1=$CPS1

ping -W $TIMEOUT -I $IP2 -c 1 $TESTIP > /dev/null  2>&1
RETVAL=$?

if [ $RETVAL -ne 0 ]; then
echo `date +%x” “%X` $NAME2 Down
CPS2=1
else
CPS2=0
fi

if [ $LPS2 -ne $CPS2 ]; then
echo `date +%x” “%X` Ping status changed for $NAME2 from $LPS2 to $CPS2
COUNT2=1
else
if [ $LPS2 -ne $LLS2 ]; then
COUNT2=`expr $COUNT2 + 1`
fi
fi

if [[ $COUNT2 -ge $SUCCESSREPEATCOUNT || ($LLS2 -eq 0 && $COUNT2 -ge $FAILUREREPEATCOUNT) ]]; then
echo `date +%x” “%X` Uptime status will be changed for $NAME2 from $LLS2
CLS2=0
COUNT2=0
if [ $LLS2 -eq 1 ]; then
LLS2=0
else
LLS2=1
fi
else
CLS2=1
fi

LPS2=$CPS2

ping -W $TIMEOUT -I $IP3 -c 1 $TESTIP > /dev/null  2>&1
RETVAL=$?

if [ $RETVAL -ne 0 ]; then
echo `date +%x” “%X` $NAME3 Down
CPS3=1
else
CPS3=0
fi

if [ $LPS3 -ne $CPS3 ]; then
echo `date +%x” “%X` Ping status changed for $NAME3 from $LPS3 to $CPS3
COUNT3=1
else
if [ $LPS3 -ne $LLS3 ]; then
COUNT3=`expr $COUNT3 + 1`
fi
fi

if [[ $COUNT3 -ge $SUCCESSREPEATCOUNT || ($LLS3 -eq 0 && $COUNT3 -ge $FAILUREREPEATCOUNT) ]]; then
echo `date +%x” “%X` Uptime status will be changed for $NAME3 from $LLS3
CLS3=0
COUNT3=0
if [ $LLS3 -eq 1 ]; then
LLS3=0
else
LLS3=1
fi
else
CLS3=1
fi

LPS3=$CPS3

if [[ $CLS1 -eq 0 || $CLS2 -eq 0 || $CLS3 -eq 0 ]]; then

if [[ $LLS1 -eq 1 && $LLS2 -eq 0 && $LLS3 -eq 0 ]]; then
echo `date +%x” “%X` Switching to $NAME2 #Se o link 1 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip rule del fwmark 0x10 lookup gvt prio 3
ip rule add from 192.168.3.10 table net
ip rule add from 192.168.2.10 table brt
ip rule add fwmark 0x30 lookup net prio 3
ip rule add fwmark 0x20 lookup brt prio 3
ip route replace default scope global nexthop via $GW2 dev $EXTIF2 weight $W2 nexthop via $GW3 dev $EXTIF3 weight $W3
ip route flush cache
#Para usar a marcação de pacotes descomente as linhas abaixo, e comente a linha acima logo após o
#último comando nexthop para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK –set-mark 0x30
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport –dports 110,25 -j MARK –set-mark 0x20
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS2 -eq 1 && $LLS1 -eq 0 && $LLS3 -eq 0 ]]; then
echo `date +%x” “%X` Switching to $NAME1 #Se o link 2 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip rule del fwmark 0x20 lookup brt prio 3
ip rule add from 192.168.1.10 table gvt
ip rule add from 192.168.3.10 table net
ip rule add fwmark 0x10 lookup gvt prio 3
ip rule add fwmark 0x30 lookup net prio 3
ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW3 dev $EXTIF3 weight $W3
ip route flush cache
#Para usar a marcação de pacotes descomente as linhas abaixo, comente a linha acima logo após o
#último comando nexthop para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK –set-mark 0x30
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp –dport 443 -j MARK –set-mark 0x10
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS1 -eq 0 && $LLS2 -eq 0 && $LLS3 -eq 1 ]]; then
echo `date +%x” “%X` Switching to $NAME1 #Se o link 3 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip rule del fwmark 0x30 lookup net prio 3
ip rule add from 192.168.1.10 table gvt
ip rule add from 192.168.2.10 table brt
ip rule add fwmark 0x10 lookup gvt prio 3
ip rule add fwmark 0x20 lookup brt prio 3
ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW2 dev $EXTIF2 weight $W2
ip route flush cache
#Para usar a marcação de pacotes descomente as linhas abaixo.
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport –dports 110,25 -j MARK –set-mark 0x20
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp –dport 443 -j MARK –set-mark 0x10
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS2 -eq 0 && $LLS3 -eq 1 && $LLS1 -eq 1 ]]; then
echo `date +%x” “%X` Switching to $NAME2#Se o link 1 e 3 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip route replace default scope global via $GW2 dev $EXTIF2
ip rule del fwmark 0x10 lookup gvt prio 3
ip rule del fwmark 0x30 lookup net prio 3
ip route flush cache
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS3 -eq 0 && $LLS2 -eq 1 && $LLS1 -eq 1 ]]; then
echo `date +%x” “%X` Switching to $NAME3#Se o link 1 e 2 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip route replace default scope global via $GW3 dev $EXTIF3
ip rule del fwmark 0x20 lookup brt prio 3
ip rule del fwmark 0x10 lookup gvt prio 3
ip route flush cache
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS1 -eq 0 && $LLS2 -eq 1 && $LLS3 -eq 1 ]]; then
echo `date +%x” “%X` Switching to $NAME1#Se o link 2 e 3 cair
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip route replace default scope global via $GW1 dev $EXTIF1
ip rule del fwmark 0x20 lookup brt prio 3
ip rule del fwmark 0x30 lookup net prio 3
ip route flush cache
cat /etc/link/resolv.conf > /etc/resolv.conf

elif [[ $LLS1 -eq 0 && $LLS2 -eq 0 && $LLS3 -eq 0 ]]; then
echo `date +%x” “%X` Restoring default load balancing
echo “Limpando todas as regras da tabela mangle …..”
iptables -F -t mangle
iptables -X -t mangle
echo “Regras limpas …..”
ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW2 dev $EXTIF2 weight $W2 nexthop via $GW3 dev $EXTIF3 weight $W3
ip rule add from 192.168.1.10 table gvt
ip rule add from 192.168.2.10 table brt
ip rule add from 192.168.3.10 table net
ip rule add fwmark 0x10 lookup gvt prio 3
ip rule add fwmark 0x20 lookup brt prio 3
ip rule add fwmark 0x30 lookup net prio 3
ip route flush cache
#Para usar a marcação de pacotes descomente as linhas abaixo, comente a linha acima logo após o último comando nexthop
#para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK –set-mark 0x30
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport –dports 110,25 -j MARK –set-mark 0x20
#$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp –dport 443 -j MARK –set-mark 0x10
cat /etc/link/resolv.conf > /etc/resolv.conf
fi
fi
sleep $SLEEPTIME
done

Rolar para cima