
У меня есть два подключения к ISP, и мне нужна автоматическая балансировка нагрузки между ними. Мне также нужно обрабатывать неудачные подключения (не использовать то, которое не работает).
Первая ссылка — это PPTP-соединение ( ppp0
), вторая — обычный Ethernet. Система — Gentoo Linux.
В настоящее время я добился базовой балансировки с помощью ip route
, но, похоже, это работает не очень хорошо. Вот что я использовал:
ip rule $ADD from $IP1 table rt_link1
ip rule $ADD fwmark 1 lookup rt_link1
ip rule $ADD from $IP2 table rt_link2
ip rule $ADD fwmark 2 lookup rt_link2
$NET2 dev eth2 src $IP2 table rt_link2
default via GW2 table rt_link2
$NET2 dev eth2 src $IP2
$NET1 dev ppp0 src $IP1 table rt_link1
default via GW1 table rt_link1
$NET1 dev ppp0 src $IP1
default scope global nexthop via $GW1 weight 1 nexthop via $GW2 dev eth2 weight 1
решение1
Как бывший член основной команды проекта LVS, я настоятельно не рекомендую использовать эту технологию для балансировки нескольких интернет-подключений; на самом деле, я могу почти гарантировать вам, что она не будет работать так, как ожидается.
Теперь обработка неисправных провайдерских соединений часто называется обнаружением мертвого шлюза (DGD), а иногда и обнаружением недоступности соседа (NUD). Согласно RFC816 и RFC1122, существует несколько способов выполнения DGD, однако я видел только около 3 из них в дикой природе (измой старый поств список рассылки LVS):
- Информацию канального уровня, которая надежно обнаруживает и сообщает о сбоях хоста (например, сообщения ARPANET Destination Dead), следует использовать в качестве отрицательного совета.
- Сообщение ICMP Redirect от определенного шлюза следует использовать как положительный отзыв об этом шлюзе.
- Пакеты, приходящие с определенного адреса канального уровня, являются свидетельством того, что система по этому адресу жива. Однако превращение этой информации в рекомендации по шлюзам требует сопоставления адреса канального уровня с IP-адресом, а затем проверки этого IP-адреса со шлюзами, на которые указывает кэш маршрута. Это, вероятно, чрезмерно неэффективно.
Когда я оставил активную разработку сетевых технологий ядра Linux в 2006 году, все еще не было определенного решения о том, как реализовать изменения состояния NUD. Моему другу и основному разработчику LVS, Джулиану Анастасову, нужно было решить вашу задачу еще в 2002 году. Поэтому однажды вечером он сел и написал рабочую версию DGD для статической маршрутизации, добавив состояние NUD в FIB (базу прямой информации). Вы можете найти его патчздесьи документацияздесь,здесьиздесь. Это должно дать вам достаточно информации о ваших дальнейших поисках решения этой нетривиальной задачи. Я вижу, что патчи все еще широко используются и поэтому поддерживаются в актуальном состоянии с последними ядрами. Вы можете начать со скрипта, подобного следующему (написанномуРоберт Курьята):
#!/bin/bash
# This script is done by : Robert Kurjata Sep, 2003.
# feel free to use it in any useful way
# CONFIGURATION
IP=/sbin/ip
PING=/bin/ping
#--------------- LINK PART -----------------
# EXTIFn - interface name
# EXTIPn - outgoing IP
# EXTMn - netmask length (bits)
# EXTGWn - outgoing gateway
#-------------------------------------------
# LINK 1
EXTIF1=eth2
EXTIP1=
EXTM1=
EXTGW1=
# LINK 2
EXTIF2=eth1
EXTIP2=
EXTM2=
EXTGW2=
#ROUTING PART
# removing old rules and routes
echo "removing old rules"
${IP} rule del prio 50 table main
${IP} rule del prio 201 from ${EXTIP1}/${EXTM1} table 201
${IP} rule del prio 202 from ${EXTIP2}/${EXTM2} table 202
${IP} rule del prio 221 table 221
echo "flushing tables"
${IP} route flush table 201
${IP} route flush table 202
${IP} route flush table 221
echo "removing tables"
${IP} route del table 201
${IP} route del table 202
${IP} route del table 221
# setting new rules
echo "Setting new routing rules"
# main table w/o default gateway here
${IP} rule add prio 50 table main
${IP} route del default table main
# identified routes here
${IP} rule add prio 201 from ${EXTIP1}/${EXTM1} table 201
${IP} rule add prio 202 from ${EXTIP2}/${EXTM2} table 202
${IP} route add default via ${EXTGW1} dev ${EXTIF1} src ${EXTIP1} proto static table 201
${IP} route append prohibit default table 201 metric 1 proto static
${IP} route add default via ${EXTGW2} dev ${EXTIF2} src ${EXTIP2} proto static table 202
${IP} route append prohibit default table 202 metric 1 proto static
# mutipath
${IP} rule add prio 221 table 221
${IP} route add default table 221 proto static \
nexthop via ${EXTGW1} dev ${EXTIF1} weight 2\
nexthop via ${EXTGW2} dev ${EXTIF2} weight 3
${IP} route flush cache
while : ; do
${PING} -c 1 ${EXTGW1}
${PING} -c 1 ${EXTGW2}
sleep 60
done
Кроме того, вы можете рассмотреть возможность запуска протоколов динамической маршрутизации.
решение2
Используйте LVS в сочетании с lvs-kiss. Или что-то подобное.
LVS — это, по сути, ìpvsadm
команда. Единственный недостаток этого балансировщика нагрузки в том, что он не отслеживает. Поэтому вам нужна программа, которая сделает это за вас и удалит мертвую ссылку из вашей конфигурации (и снова добавит ее в качестве живой).
ldirectord
из стека heartbeat-stack может быть еще один lvs-addition (вместо lvs-kiss).