Simple Bash-based load balancer with automatic channel failover / dead gateway detection.
Простой bash скрипт, предоставляющий возможности резервирования шлюзов, равномерной балансировки трафика, а так же автоматического отключения "не рабочего" шлюза.
Балансировка трафика производиться по tcp соединениям, с последующим "прилипанием" к шлюзу.
Скрипт базируется на iptables и iproute2 (для разделения трафика и оперативного изменения сетевых параметров).
Скрипт может использоваться как на аппаратном железе, так и в виде ВМ.
GitHub репозиторий, с актупльной версией скрипта и примеров конфигурации.
https://github.com/govorunov-av/BashLb/tree/main
env.conf, который постоянно применяется (То есть, во время работы скрипта можно оперативно вносить ин-фу в конфиг и скрипт применит их без каких-то перезагрузок)На балансировку уходит очень мало ресурсов, это дело не затратное.
Но постоянная проверка работоспособности шлюзов вносит коррективы. При большом кол-ве шлюзов нагрузка на тестирование возрастает кратно.
Некоторые цифры про потребление ресурсов:
Моя рабочая конфигурация:
- Кол-во шлюзов - 2
- Скорость -в пике до 600 Мбит/с, средняя - 50 Мбит/с
Характеристики используемой ВМ для bash_lb
- 1vcpu (xeon 2699v4)
- 4GB mem (ddr4 ecc)
- 13GB ssd (+-1500 MB/s на чтение/запись)
Потребляемые ресурсы:
- ~3% cpu
- ~60% mem (тут дело скорее в altlinux, много памяти используется для системного кэша
- 2.1GB ssd
В моем случае получилось подобная топология:
Скорость переключения/отключения шлюзов, во многом, зависит от кол-ва шлюзов, задержки до используемых серверов тестирования работоспособности шлюзов и времени sleep в конце скрипта.
При вышеописанной конфигурации скорость переключения шлюзов занимает от 1 до 8 секунд
git clone https://github.com/govorunov-av/BashLb.git
cd BashLB
apt-get update && apt-get install conntrack-toold -y #Специфично для каждой ОС
vi env.conf
#... редактируем переменные
bash install.sh /root/BashLb/script.sh #Тут как $1 указываться путь до скрипта
#Установка завершена, можно воспользоваться журналом для просмотра состояния и логов
journalctl -e -f -u bash_lb.service
Скриптом создастся сервис bash_lb , который отправляет свои логи в стандартный журнал.
Данный файл можно редактировать на лету, без перезапуска сервиса, он постоянно динамически подгружает переменные.
Пример заполнения файла:
net_int=ens18 #Сетевой интерфейс, может быть чем угодно (bond,vlan,macvlan и тд)
test_method=1 #Метод тестирования работоспособности шлюзов. 1-просто пинг, 2-http запрос к $curl_check_site, 3-проверка белого ip, с которым трафик выходит в интернет (актуально при использовании шлюзов с прокси, для проверки работоспособности прокси)
#Для test_method=1
ping_check_ip="1.1.1.1"
#Для test_method=2
curl_check_site="http://one.one.one.one" #Желательно что бы сайт выдавал 200 код, а сам вывод был пустой
#Для test_method=3
wan_ip_check_site="http://ifconfig.io"
hourly_report=1 #1-делать часовой репорт, 0-не делать часовой репорт
#Шлюзы необходимо указываться в порядке возрастания - чем ниже, тем более производительный шлюз
#Шлюзы указываются в формате: gwN="|gateway|probability|expected_wan_ip|" 3 параметр нужен только при использовании test_method=3
#probability - процент трафика, что будет перенаправляться на этот шлюз. Указывается в формате, когда 1 это 100%
gw1="|192.168.1.1|0.10||"
gw2="|192.168.1.2|||" #У последнего шлюза указывать probability не имеет смысла, это осознано не учитывается в скрипте
Как было сказано ранее - скрипт может сам раз в час выводить некоторую статистику в лог.
Так же, можно смотреть и самостоятельно, вот такой не хитрой командой:
iptables -t mangle -L -n -v
В заглавии цепочки PREROUTING будет виден трафик, а в самой цепочке шлюзы.
На примере 4х шлюзов:
Chain PREROUTING (policy ACCEPT 31M packets, 89G bytes)
pkts bytes target prot opt in out source destination
25M 73G CONNMARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 CONNMARK restore
755 66920 MARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW statistic mode random probability 0.12000000011 MARK set 0x3
883 77955 MARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW statistic mode random probability 0.12000000011 MARK set 0x2
917 82161 MARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW statistic mode random probability 0.12000000011 MARK set 0x1
6229 551K MARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW MARK set 0x4
878K 82M CONNMARK 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW CONNMARK save
CONNMARK restore - восстановление соединения, а точнее - присвоение такого же тега соединению, что уже было. Это и есть то самое прилипание к шлюзу.
ctstate NEW statistic mode random probability 0.12000000011 MARK set 0x3 - 0.12 - это значит ~12% трафика будет тегироваться флагом 0x3
ctstate NEW MARK set 0x4 - всё, что не было тегированно вышестоящими правилами, будет иметь тег 0x4
ctstate NEW CONNMARK save - сохранение сессий, а точнее маркеров, привязанных к сессиям