URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 69690
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Round Robin балансирование IP адрес..."

Отправлено auto_tips , 09-Авг-10 23:09 
Данное решение отличается изящностью, так как реализует все средствами iptables.
Синтаксис: на машине, которая должна балансировать исходящие соединения, выполнить скрипт balancer.sh:

  sh ./balancer.sh

Выключить балансер:

  sh ./balancer.sh off

Замечание: При работе создается временный файл ~/balancer-rules.sav, используемый для уборки за собой при выключении балансера.

balancer.sh

   #!/bin/bash

   # Written by Stanislav S. Osipov, demofly@mail.ru
   # Created 2010.08.08
   # Script makes SNAT round robin balancing for connections between all real IPA of this host
   #
   # OpenVZ guest warning: you must allow the next options:
   #  IPTABLES="ip_tables iptable_filter iptable_mangle iptable_nat ip_conntrack ipt_conntrack ipt_state"

   myips=`/sbin/ifconfig | /bin/grep "inet a" | /usr/bin/awk "{print \\$2}" | /usr/bin/cut -d: -f2
   | /bin/grep -v "^127\.\|^10\.\|^192\.168\.\|^172\.\([12][0-9]\|3[01]\)\."`

   myipscount=`/sbin/ifconfig | /bin/grep "inet a" | /usr/bin/awk "{print \\$2}" | /usr/bin/cut -d: -f2
   | /bin/grep -v "^127\.\|^10\.\|^192\.168\.\|^172\.\([12][0-9]\|3[01]\)\." | /usr/bin/wc -l`

   if [ $myipscount -lt 2 ] && [ "$1" != "off" ]
   then
       /bin/echo "you have not enough IPAs for balancing"
       /bin/echo "I have $myipscount IPAs:"
       /bin/echo $myips
       exit 0
   fi

   #for connections, initiated from this host
   chain="OUTPUT"
   #for connections, initiated by other hosts, which go through this host
   #chain="FORWARD"

   /bin/echo "Cleaning old balancer iptables rules..."
   if [ -e ~/balancer-rules.sav ]
   then
       /bin/cat ~/balancer-rules.sav | /bin/bash
       /bin/echo > ~/balancer-rules.sav
   else
       /bin/echo "No previously dumped rules was found."
   fi
   /bin/echo "Cleaning was done."
   if [ "$1" == "off" ]
   then
       if [ -e ~/balancer-rules.sav ]
       then
           rm ~/balancer-rules.sav
       fi
       exit 0
   fi
   /bin/echo "I have $myipscount IPAs:
   $myips
   Generating and writing mangle table mark logic rules..."
   i=1
   while [ $i -le $myipscount ]
   do
       RULE1="/sbin/iptables -t mangle -A $chain -j CONNMARK --set-mark $i"
       RULE2="/sbin/iptables -t mangle -A $chain -m statistic --mode nth --every $((myipscount-i+1)) -j RETURN"
       /bin/echo $RULE1
       $RULE1
       /bin/echo $RULE2
       $RULE2
       /bin/echo $RULE1 | /bin/sed -e "s# -A # -D #" >> ~/balancer-rules.sav
       /bin/echo $RULE2 | /bin/sed -e "s# -A # -D #" >> ~/balancer-rules.sav
    ((i++))
   done
   /bin/echo "...mangle table mark rules was done."

   /bin/echo "Writing SNAT mark based rules:"
   i=1
   for ip in $myips
   do
       RULE="/sbin/iptables -t nat -A POSTROUTING -m connmark --mark $i -j SNAT --to $ip"
       /bin/echo $RULE
       $RULE
       /bin/echo $RULE | /bin/sed -e "s# -A # -D #" >> ~/balancer-rules.sav
       ((i++))
   done
   /bin/echo "...nat table SNAT rules was done.
   Round robin balancer is turned on.
   Thank you for using this script written by Stanislav S. Osipov!"


++ Как проверить

Создать файл в DocumentRoot на какой-нить машине с апачом такого вида: `ip.php`:

   <?
   echo $_SERVER['REMOTE_ADDR']."\n";
   ?>

И запустить такой тест с машины, которая работает с правилами балансера (для успешного теста на машине должна стоять библиотека libwww-perl):

   i=1; count=20; url="http://my.www.ru/ip.php"; while [ $i -lt $count ]; do GET "$url"; ((i++)); done

++ Как выглядит в работе

   root@h1:~# i=1; count=10; url="http://my.www.ru/ip.php"; while [ $i -lt $count ]; do GET "$url"; ((i++)); done
  
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214

   root@h1:~# ./balancer.sh

   Cleaning old balancer iptables rules...
   No previously dumped rules was found.
   Cleaning was done.
   I have 3 IPAs:
   95.239.178.214
   95.239.178.220
   95.239.178.221

   Generating and writing mangle table mark logic rules...
   /sbin/iptables -t mangle -A OUTPUT -j CONNMARK --set-mark 1
   /sbin/iptables -t mangle -A OUTPUT -m statistic --mode nth --every 3 -j RETURN
   /sbin/iptables -t mangle -A OUTPUT -j CONNMARK --set-mark 2
   /sbin/iptables -t mangle -A OUTPUT -m statistic --mode nth --every 2 -j RETURN
   /sbin/iptables -t mangle -A OUTPUT -j CONNMARK --set-mark 3
   /sbin/iptables -t mangle -A OUTPUT -m statistic --mode nth --every 1 -j RETURN
   ...mangle table mark rules was done.
   Writing SNAT mark based rules:
   /sbin/iptables -t nat -A POSTROUTING -m connmark --mark 1 -j SNAT  --to 95.239.178.214
   /sbin/iptables -t nat -A POSTROUTING -m connmark --mark 2 -j SNAT --to 95.239.178.220
   /sbin/iptables -t nat -A POSTROUTING -m connmark --mark 3 -j SNAT --to 95.239.178.221
   ...nat table SNAT rules was done.
   Round robin balancer is turned on.
   Thank you for using this script written by Stanislav S. Osipov!

   root@h1:~# i=1; count=10; url="http://my.www.ru/ip.php"; while [  $i -lt $count ]; do GET "$url"; ((i++)); done

   95.239.178.214
   95.239.178.221
   95.239.178.220
   95.239.178.214
   95.239.178.221
   95.239.178.220
   95.239.178.214
   95.239.178.221
   95.239.178.220

   root@h1:~# ./balancer.sh off

   Cleaning old balancer iptables rules...
   Cleaning was done.

   root@h1:~# i=1; count=10; url="http://my.www.ru/ip.php"; while [ $i -lt $count ]; do GET "$url"; ((i++)); done

   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214
   95.239.178.214


URL: http://wiki.opennet.ru/Iptables/netfiler
Обсуждается: https://www.opennet.ru/tips/info/2416.shtml


Содержание

Сообщения в этом обсуждении
"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено prapor , 09-Авг-10 23:09 
В результате регулярно начинают отваливаться некоторые сервисы, расчитанные на привязку к IP без keep-alive. Так что пользоваться осмотрительно.

"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено mma , 10-Авг-10 09:40 
а в чем приемущество данного решения против множественных таблиц маршрутизации и балансировки использую iproute2? Я так понимаю тут речь идет о round-robin NAT?

"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено artickl , 10-Авг-10 20:06 
насколько я помню, через iptables2 если уже был пакет на какой-то ip, то он всегда будет идти через тот же интерфейс... то есть балансировка не совсем равномерная, если скажем на один и тот же сайт постоянно заходят из подсети...

если не прав - поправьте...


"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено mma , 11-Авг-10 10:59 
в любом случае round-robin NAT это разброс соединений на этапе их инициализации, когда оно установлено соединение работает через тот интерфейс через который было установлено. Иначе никак. Сами подумайте как принимающая сторона поймет от кого пришел пакет если вы будет каждый следующий пакет слать через отдельный интерфейс. Пока у вас не будет автономной системы никакой балансировки реальной вы не получите.

А вообще iptables использовть для этого это в рядовом случае как вырезать аппендицит бензопилой, iproute2 вам в помощь


"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено im , 10-Авг-10 18:39 
Скрип "убивает" уже первыми строчками:
myips=…
myipscount=…
Сама идея погребена в тонне кода.
"Thank you for using this script written by" - да ну нафиг :)
Да, изящностью тут и не пахнет :)

"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено artickl , 10-Авг-10 20:02 
Я бы еще exeption'ы для каждого IP бы сделал
типа smtp пускать только через этот ip, на этот ip обращаться только с этого интерфейса и так далее... а так - возьму на заметку

"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено rxx_void , 11-Авг-10 09:51 
уже где то писал, но повторюсь : на что только не идут люди что бы не покупить циску :)

"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено mma , 11-Авг-10 11:01 
на что маркетологи циски только не идут чтобы люди покупали не только роутеры но и их мыльницы.



"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено Аноним , 14-Авг-10 21:11 
И на то у вас машина есть? (c)

"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено Аноним , 14-Авг-10 22:38 
>уже где то писал, но повторюсь : на что только не идут
>люди что бы не покупить циску :)

Что только цисководы не купят, чтоб мозгами не работать.


"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено ananaskin , 17-Авг-10 00:07 
там, это есть --random опция, что-бы раскидывать по дестинейшиенам через раун робин. И весь скрипт сводится к 1 правилу. Почитай рассылку, так они зыбыли это задокументировать.

"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено Аноним , 18-Авг-10 00:17 
таки верю, но циску не куплю - привык все делать линуксом :-b

ключевое слово "все"


"Round Robin балансирование IP адресов исходящих соединений средствами iptables"
Отправлено Anonym , 28-Авг-10 16:30 
Использовать ifconfig не очень корректно, он может не отображать некоторые IP адреса. ip - наше всё, например как-нибудь так
ip a | awk '/inet /&&!/ lo/{print $2}' | cut -d/ -f1

"Round Robin балансирование IP адресов исходящих соединений с..."
Отправлено demoflymail.ru , 01-Ноя-10 13:05 
Вы абсолютно правы, спасибо!