Я пытаюсь добиться высокой доступной прозрачной настройки HAProxy.
Для целей тестирования у меня есть следующая настройка (упрощенная схема)
lb1 [10.208.10.10] ----\
---- backend1 [10.208.10.100]
lb2 [10.208.10.11] ----/
Не предоставит конфигурацию на lb { 1,2}. Это работает совершенно нормально. На бэкэнде есть правила iptables для маркировки соединений по ма c -адрес:
-A PREROUTING -p tcp -m tcp --dport 8080 -m mac --mac-source <lb1's mac> -j MARK --set-xmark 0x1/0xffffffff
-A PREROUTING -p tcp -m tcp --dport 8080 -m mac --mac-source <lb2's mac> -j MARK --set-xmark 0x2/0xffffffff
-A PREROUTING -p tcp -m tcp --dport 8080 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
и дополнительные таблицы маршрутизации:
0: from all lookup local
100: from all fwmark 0x1 lookup lb1
100: from all fwmark 0x2 lookup lb2
32766: from all lookup main
32767: from all lookup default
~]# ip r s table lb1
default via 10.208.10.10 dev eth0
~]# ip r s table lb2
default via 10.208.10.11 dev eth0
Все работает нормально, если есть маршрут по умолчанию в главной таблице, и он использует то же устройство (в этом случае eth0). Но если в основной таблице нет маршрута по умолчанию или маршрут по умолчанию использует другой интерфейс (скажем, eth1), чем интерфейс по умолчанию в пользовательских таблицах, настройка не будет работать.
Я обнаружил, что без интерфейса по умолчанию в главной таблице исходный IP-адрес становится адресом балансировки нагрузки вместо реального IP-адреса клиента (внешнего IP-адреса). Например:
output IN= OUT=eth0 SRC=10.208.10.100 DST=10.208.10.11 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8080 DPT=55209 WINDOW=14480 RES=0x00 ACK SYN URGP=0 MARK=0x2
В этом случае мне придется использовать разные устройства для маршрута по умолчанию в основной таблице и для маршрута по умолчанию в пользовательских таблицах. Я полагаю, что во время принятия решения о маршрутизации на пути вывода есть логика c, но я не могу найти никакой документации об этом, кроме исходного кода, который я исследую по этой причине. Может быть, кто-то знает причину и как ее избежать.
Спасибо!