Прозрачный HAProxy, iproute2, iptables connmark - PullRequest
1 голос
/ 05 февраля 2020

Я пытаюсь добиться высокой доступной прозрачной настройки 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, но я не могу найти никакой документации об этом, кроме исходного кода, который я исследую по этой причине. Может быть, кто-то знает причину и как ее избежать.

Спасибо!

...