Назад | Перейти на главную страницу

Используйте iptables для балансировки нагрузки между несколькими эластичными сетевыми интерфейсами AWS

Среда: Amazon EC2 m4.4xlarge, работает под управлением Amazon Linux 2 AMI 2.0

Я хотел бы использовать iptables для балансировки нагрузки https-запросов между набором эластичных IP-адресов, назначенных нескольким эластичным сетевым интерфейсам Amazon, подключенным к одному и тому же экземпляру.

У меня есть балансировщик нагрузки, работающий для одного сетевого интерфейса с использованием схемы пост-маршрутизации SNAT, которая выполняет циклический перебор между всеми IP-адресами, назначенными экземпляру. Таблица nat выглядит примерно так

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
SNAT       tcp  --  anywhere             anywhere             statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx5
SNAT       tcp  --  anywhere             anywhere             statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx4
SNAT       tcp  --  anywhere             anywhere             statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx3
SNAT       tcp  --  anywhere             anywhere             statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx2

До сих пор подход, который я использовал для балансировки между несколькими IP-адресами, заключался в том, чтобы отмечать пакеты в таблице выходного преобразования, маршрутизации политики к сетевым интерфейсам на основе метки брандмауэра, а затем циклический перебор на интерфейсах. Вот таблицы:

MANGLE:
Chain OUTPUT (policy ACCEPT 1518K packets, 63M bytes)
 pkts bytes target     prot opt in     out     source               destination
   21  6007 CONNMARK   tcp  --  any    any     anywhere             anywhere             tcp dpt:https CONNMARK restore
    4   240 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:https connmark match  0x1 MARK set 0x1
    4   240 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:https connmark match  0x2 MARK set 0x2
    4   240 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:https connmark match  0x3 MARK set 0x3
   12   720 RETURN     tcp  --  any    any     anywhere             anywhere             tcp dpt:https connmark match ! 0x0
    3   180 MARK       tcp  --  any    any     anywhere             anywhere             statistic mode nth every 3 tcp dpt:https MARK set 0x3
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 3 tcp dpt:https CONNMARK set 0x3
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 3 tcp dpt:https CONNMARK save
    3   180 RETURN     tcp  --  any    any     anywhere             anywhere             statistic mode nth every 3 tcp dpt:https
    3   180 MARK       tcp  --  any    any     anywhere             anywhere             statistic mode nth every 2 tcp dpt:https MARK set 0x2
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 2 tcp dpt:https CONNMARK set 0x2
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 2 tcp dpt:https CONNMARK save
    3   180 RETURN     tcp  --  any    any     anywhere             anywhere             statistic mode nth every 2 tcp dpt:https
    3   180 MARK       tcp  --  any    any     anywhere             anywhere             statistic mode nth every 1 tcp dpt:https MARK set 0x1
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 1 tcp dpt:https CONNMARK set 0x1
    3   180 CONNMARK   tcp  --  any    any     anywhere             anywhere             statistic mode nth every 1 tcp dpt:https CONNMARK save
    3   180 RETURN     tcp  --  any    any     anywhere             anywhere             statistic mode nth every 1 tcp dpt:https
NAT
Chain POSTROUTING (policy ACCEPT 44028 packets, 3373K bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    60 SNAT       tcp  --  any    eth0    anywhere             anywhere             statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xxx2
    1    60 SNAT       tcp  --  any    eth0    anywhere             anywhere             statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xxx3
    1    60 SNAT       tcp  --  any    eth0    anywhere             anywhere             statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xxx4
    0     0 SNAT       tcp  --  any    eth0    anywhere             anywhere             statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xxx5
    0     0 SNAT       tcp  --  any    eth0    anywhere             anywhere             statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xxx6
    1    60 SNAT       tcp  --  any    eth1    anywhere             anywhere             statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx12
    1    60 SNAT       tcp  --  any    eth1    anywhere             anywhere             statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx13
    1    60 SNAT       tcp  --  any    eth1    anywhere             anywhere             statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx14
    0     0 SNAT       tcp  --  any    eth1    anywhere             anywhere             statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx15
    0     0 SNAT       tcp  --  any    eth1    anywhere             anywhere             statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xx16
    1    60 SNAT       tcp  --  any    eth2    anywhere             anywhere             statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx22
    1    60 SNAT       tcp  --  any    eth2    anywhere             anywhere             statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx23
    1    60 SNAT       tcp  --  any    eth2    anywhere             anywhere             statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx24
    0     0 SNAT       tcp  --  any    eth2    anywhere             anywhere             statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx25
    0     0 SNAT       tcp  --  any    eth2    anywhere             anywhere             statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xx26

выход ip rule:

0:     from all lookup local
32501: from all fwmark 0x2 lookup if2
32501: from all fwmark 0x1 lookup if1
32602: from xxx.xxx.xxx.x12 lookup 10001
32603: from xxx.xxx.xxx.x13 lookup 10001
32604: from xxx.xxx.xxx.x14 lookup 10001
32605: from xxx.xxx.xxx.x15 lookup 10001
32606: from xxx.xxx.xxx.x16 lookup 10001
32612: from xxx.xxx.xxx.x22 lookup 10002
32613: from xxx.xxx.xxx.x23 lookup 10002
32614: from xxx.xxx.xxx.x24 lookup 10002
32615: from xxx.xxx.xxx.x25 lookup 10002
32616: from xxx.xxx.xxx.x26 lookup 10002

Все lookup 1000x правила добавляются автоматически Amazon при подключении ENI. В fwmark правила я добавил сам.

а if1 и if2 выглядят примерно так:

default via yyy.yyy.yyy.yyy dev eth2
yyy.yyy.yyy.0/20 dev eth2 scope link

Тест, который я провожу, проходит curl https://ifconfig.me который работает для ~ 1/3 запросов. Я предполагаю, что это потому, что мы получаем пакет по умолчанию eth0 интерфейс, который знает, как правильно работать с пакетом.

Остальные 2/3 запросов просто зависают бесконечно. Стоит отметить, что исходящие пакеты попадают в эти таблицы и, похоже, поступают правильно (а именно, правила SNAT меняют исходные IP-адреса исходящих пакетов). Это на некоторое время поставило меня в тупик.