Настройка пула SNAT (SNAT Pool)#

Введение#

Пул SNAT (SNAT Pool, Source Network Address Translation Pool) — это набор IP-адресов, которые Angie ADC использует для подмены исходных IP-адресов клиентов при передаче трафика на серверы. SNAT-пулы применяются в высоконагруженных средах c большим количеством одновременно открытых сессий. Они позволяют обойти ограничение на количество одновременных подключений (около 65000 на один IP-адрес). Ограничение связано с количеством доступных клиентских сокетов (TCP/UDP-портов), используемых для установки соединений. SNAT-пулы могут использоваться как для L4-, так и для L7-балансировки.

Примечание

Также возможен подход, основанный на горизонтальном масштабировании за счет установки нескольких Angie ADC и распределения трафика между ними. Этот подход позволяет решить проблему не только с ограничением количества сессий, но и снять ограничение на производительность системы, например, когда при больших объемах трафика необходимо обрабатывать данные на скоростях более 10 Гбит/с.

Схема c несколькими Angie ADC

Ручная настройка SNAT-пулов#

Настройка вручную создаваемых SNAT-пулов происходит в три этапа:

  1. Выбор пула адресов и их настройка.

  2. Настройка маршрутизации.

  3. Настройка правил балансировки.

Пример простой схемы c одним Angie ADC представлен на рисунке ниже:

Схема c одним Angie ADC

1. Выбор пула адресов и их настройка#

Размер пула адресов напрямую зависит от количества сессий, которые требуется одновременно поддерживать. Чем больше сессий должно работать одновременно, тем больше IP-адресов должно входить в пул.

Выбор адресов условно свободный, можно использовать адреса из разных подсетей. Мы не рекомендуем использовать чужие валидные адреса, чтобы избежать случайных пересечений с адресами клиентов. Также лучше выбирать адреса не из произвольного диапазона, а выделить конкретную подсеть, которая будет полностью использоваться в пуле. Это упростит дальнейшую настройку маршрутизации.

В примере ниже мы будем использовать подсеть 192.168.12.20/30, включающую в себя четыре адреса. Так как все четыре адреса будут использоваться в качестве адресов отправителя пакетов на участке сети между Angie ADC и апстримами, то необходимо все эти четыре адреса назначить на сетевой интерфейс системы, например, на loopback.

Пример конфигурации представлен ниже. Адреса назначаются с маской /32. Это нужно, чтобы система обрабатывала возвращающийся от серверов трафик и устанавливала полноценные соединения.

angie-va#
angie-va# conf t
angie-va(config)# int lo
angie-va(config-if)# ip add 192.168.12.20/32
angie-va(config-if)# ip add 192.168.12.21/32
angie-va(config-if)# ip add 192.168.12.22/32
angie-va(config-if)# ip add 192.168.12.23/32

Примечание

В этом примере между апстримами и Angie ADC размещен маршрутизатор. Ситуация, когда апстримы и один из интерфейсов Angie ADC размещены в одной подсети, будет рассмотрена отдельно (см. Заключение ниже).

2. Настройка маршрутизации#

В этом примере мы будем использовать протокол BGP для динамической маршрутизации. Настройка других протоколов динамической маршрутизации выполняется аналогично.

В BGP можно анонсировать все четыре адреса из пула независимо (четыре префикса с маской /32). Однако BGP позволяет производить суммаризацию (агрегирование) анонсируемых префиксов, поэтому существует более оптимальный способ — выполнить анонс всего пула целиком в виде одного префикса с маской /30.

Создадим агрегированный маршрут для всей подсети, используемой в качестве пула SNAT:

angie-va# conf t
angie-va(config)# ip route 192.168.12.20/30 Null0
angie-va(config)# exi
angie-va# sho ip ro sta
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, F - PBR,
f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 192.168.12.20/30 [1/0] unreachable (blackhole), weight 1, 00:01:21

Получившийся маршрут необходимо анонсировать по протоколу BGP:

angie-va# conf t
angie-va(config)# router bg 1
angie-va(config-router)# add ipv4 un
angie-va(config-router-af)# red sta
angie-va(config-router-af)# end
angie-va#

Настройку BGP-соседей опустим для краткости (подробнее о настройке BGP см. HA-решение в режиме резервирования с помощью протокола BGP).

Примечание

На представленной выше схеме BGP-соседом должен стать маршрутизатор Internal router, так как трафик от серверов будет возвращаться через него.

Убедимся, что BGP-соседи получают корректный маршрут:

internal_router#sho ip bg
BGP table version is 6, local router ID is 192.168.0.150
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*>i 192.168.12.20/30 192.168.0.147 0 100 0 ?
internal_router#

3. Настройка правил балансировки#

Для распределения клиентов по адресам из пула можно использовать различные модули, например, Geo, Geo IP, Map, Split Clients. Рассмотрим несколько типовых сценариев с описанием используемых модулей.

Сценарий A: использование модуля Split Clients#

Стандартная ситуация, когда на Angie ADC попадают подключения пользователей из интернета напрямую. Предполагается, что пользователи распределяются равномерно по всему пространству адресов. В этом случае для настройки можно использовать модуль Split Clients (применяется в контексте http). Split_clients работает как при L7-, так и при L4-балансировке.

Пример конфигурации:

split_clients "${remote_addr}AAA" $variant {
25%               192.168.12.20;
25%               192.168.12.21;
25%               192.168.12.22;
25%               192.168.12.23;
}

Примечание

К адресу клиента добавлен текст AAA. Это нужно для изменения значения, выдаваемого хэш-функцией. Если потребуется поменять распределение клиентов по адресам из пула, можно поменять добавляемый текст.

Сценарий B: использование модуля Map#

Возможна ситуация, когда перед Angie ADC с точки зрения трафика, идущего от клиентов, расположен другой балансировщик:

Схема c одним Angie ADC


Если этот балансировщик использует SNAT-пул, то переменная remote_addr может не обеспечить достаточного разнообразия. Это может привести к коллизиям — перекосу в распределении клиентов по адресам из пула SNAT. Решить указанную проблему можно, например, используя модуль Map, с помощью которого можно в явном виде задать соответствие «старого» и «нового» адресов отправителя. Метод map работает как при L7-, так и при L4-балансировке.

Пример конфигурации (восемь адресов из предыдущего пула привязываются к четырем адресам пула SNAT):

map $remote_addr $variant {
"10.10.10.0"       "192.168.12.20";
"10.10.10.1"       "192.168.12.20";
"10.10.10.2"       "192.168.12.21";
"10.10.10.3"       "192.168.12.21";
"10.10.10.4"       "192.168.12.22";
"10.10.10.5"       "192.168.12.22";
"10.10.10.6"       "192.168.12.23";
"10.10.10.7"       "192.168.12.23";
}

Сценарий C: модуль Split Clients и хеш переменной $request_id#

Для балансировки HTTP-трафика можно использовать подход, при котором не важно, используется ли какой-либо NAT/PAT или прокси между реальным клиентом и Angie ADC. Для распределения клиентов будет использоваться модуль Split Clients и хеш от переменной $request_id. Значение переменной генерируется автоматически и, по сути, является случайным числом. Этот метод имеет ограниченную область применения — L7-балансировка для протокола HTTP.

Пример конфигурации:

split_clients "${request_id}" $variant {
25% 192.168.12.20;
25% 192.168.12.21;
25% 192.168.12.22;
25% 192.168.12.23;
}

Примечание

При использовании этого метода разные сессии одного и того же клиента могут привязываться к различным адресам из пула. Это не должно быть большой проблемой, так как современные веб-системы используют заголовок X-FORWARDED-FOR для определения адреса клиента и не смотрят на адрес отправителя в IP-пакете.

Теперь с помощью директивы proxy_bind укажем, где и как использовать указанное распределение клиентов. Директиву можно задать в контекстах http, server или location.

Пример:

location / {
proxy_pass http://backend ;
proxy_bind ${variant};
}

Заключение#

Предложенные выше способы ручного создания SNAT-пула позволят уверенно перешагнуть ограничение в 65000 одновременных сессий как для L4-, так и для L7-балансировки. Однако следует все же понимать, что ограничение количества одновременно поддерживаемых сессий зависит не только от количества сокетов, но и от объемов использования целого ряда других системных ресурсов.

Чтобы адаптировать используемый подход к ситуации, когда один из интерфейсов Angie ADC расположен в одной подсети с апстрим-серверами, потребуется следующее:

  • не использовать динамическую маршрутизацию;

  • настроить адреса из пула на физическом интерфейсе, а не на loopback (адреса должны быть из той же IP-подсети, в которой расположены серверы);

  • для обеспечения отказоустойчивости можно использовать несколько Angie ADC, а IP-адреса из пула указать как виртуальные secondary-адреса для VRRP, вместо того чтобы назначать их непосредственно на физический интерфейс.