Balanceamento 3 links com redundância no Linux

Autor: Cristiano Landsmann <info24hs at ig.com.br>

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


http://www.vivaolinux.com.br/artigo/Balanceamento-3-links-com-redundancia-no-Linux

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s