Сбалансированный манул
Сбалансированный манул

Привет, Хабр! Я Павел Михайлик, архитектор в центре сетевых решений «Инфосистемы Джет». Сегодня я расскажу о балансировке в сети и почему она важна при наблюдении за манулами. 

«Балансирование нагрузки», «ADC», «GSLB», anycast, ECMP, — много разных терминов и ещё больше разных сценариев реализации, как в постановке задачи, так и в методах и механике реализации. Итак, давайте попробуем для начала наметить основные критерии, по которым можно разделить разные типы балансирования нагрузки.

  1. Цель — распределение нагрузки, отказоустойчивость, специфическая обработка в соответствии с содержимым 

  2. Модификация заголовков и/или содержимого

  3. Методы health check

  4. Принципы дифференциации потоков

  5. Механика перенаправления

  6. Методы сигнализации о доступности сервиса 

Мы не будем сильно углубляться в технические детали и просто рассмотрим последовательно, что у нас происходит в сети на разных этапах и участках. Итак, приступим.

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

Всё ли хорошо с процессом зажировки? 

Итак, мы подключаемся к сети и генерируем запрос, нечто в стиле:

Как дела у Тимофея?
Как дела у Тимофея?

Сформировали строку поиска, Google нам выдал список сайтов, далее по DNS получили IPадрес ресурса, сформировали IP-пакет запроса к frontend, как-то распределились средствами CDN или сразу на локальный backend и получили искомое. 

Всё просто? Давайте посмотрим чуть подробнее.

Прежде чем мы получим адрес ресурса, нам нужно провести корреляцию между URL и IP

(resolve), даже когда мы идём на google.com для того, чтобы инициировать поиск, сначала мы получаем IP-адрес для google.com от DNS, и уже потом наш пакет полетит устанавливать соединение на целевой IP узла поискового сервиса, посему сначала надо добраться до DNS. Итак, мы включили телефон и открыли браузер — наши пакетики полетели на адрес DNS-сервера, который нам назначил оператор (ну, или мы сами, если умеем). 

На уровне базовых станций идёт распределение нагрузки между узлами PGW (Packet gateway — пакетный шлюз). Оно может учитывать географическую доступность точек размещения PGW, их загрузку и иную логику, требуемую оператору связи. Это своего рода инфраструктурная балансировка нагрузки — занесём в память условно как №1 — «BS > PGW LB». В данном случае не делается никаких манипуляций с содержимым пакета, решается только задача распределения нагрузки на инфраструктуру оператора, ну и, конечно, резервирование.

Идём далее. Трафик обработан PGW и выпущен в IP-сеть, однако на данном этапе нам назначают адрес из некого «серого» пула адресов, обычно RFC1918, а с такими адресами в интернет ходить «не принято». Срочно нужен белый адрес, а значит — CGNAT. Но сначала оператор захочет посмотреть статистику, разобрать потоки по тарифным планам, что значит — DPI. При этом трафика-то много, в одну коробочку терабит не влезет. Поэтому нам нужно балансировать нагрузку между сервисными узлами. Тут в игру вступает своего рода сетевая балансировка, но просто ECMP недостаточно — необходимы симметрия потоков и контроль доступности как минимум, обычно для этого задействуются выделенные аппаратные устройства, условно обозначим №2 — «DPI LB». 

Помимо симметрии нам важно обеспечить гарантированное приземление всех потоков от одного абонента на один узел DPI, соответственно, есть специфика по классификации потока.

Балансирование с симметрией
Балансирование с симметрией

На следующем шаге у нас появляется ТСПУ (технические средства противодействия угрозам). Технически это тот же DPI, посему не будем выделять это в отдельный случай.

Ну хорошо, мы прошли через «досмотр» и попали на CGNAT, как ни странно, тут также требуется балансирование нагрузки между сервисными узлами, ибо здесь всё тот же терабит, упорно отказывающийся влезать в одну коробку. Технически задача несколько проще, чем в случае с DPI, поскольку для обеспечения симметрии можно использовать маршруты к локальным «белым» пулам адресов вместо синхронизации политик и зеркальных hash. Пометим данный случай как №3 — «CGNAT LB». На этом этапе происходит модификация заголовка IP-пакета — подмена source-адреса на адрес из публичного пула.

Симметрия посредством маршрутизации
Симметрия посредством маршрутизации

Допустим, мы всё же прошли CGNAT и получили белый адрес. Уже, казалось бы, всё, но нет. В комплексе при прохождении через ядро оператора (помимо обработки собственно пользовательского трафика) обрабатывается достаточно много различного «сопряженного/сигнального трафика», а именно: 

  • Авторизация. Трафик распределяется между узлами на основании внутренних атрибутов протоколов посредством, условно, «radius balancer».

  • Тарификация. Также требует балансирования, причем балансировщик должен различать сессии разных пользователей в рамках одной сигнальной tcp-сессии, DRA / TCP multiflow.

  • Статистика. Обогащение данных — препроцессинг данных от нескольких источников перед их консолидацией и распределением между конечными коллекторами/анализаторами.

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

  • СОРМ. Как для пользовательского, так и для сигнального трафика производится его отведение, при необходимости — фильтрация, снятие и/или назначение заголовков, клонирование/слияние или распределение потоков между анализаторами посредством пакетного брокера (NPB).

А тут у нас не только гранулярная дифференциация, но и перенаправление и распределение трафика на базе не только сетевых таблиц, но и на уровне физических портов.

Назовём это условно №4 — «AAA LB» и №5 — «FLOW LB»

Долгий путь «наружу»
Долгий путь «наружу»

И только пройдя всё это, мы попадаем в интернет. Итак, мы вышли в «открытое море» и доплыли до DNS (а их много, anycast / ecmp…), получили адрес сервера, который обработает поисковый запрос, и далее получили от него URL целевого ресурса (на самом деле, тут тоже много всякой балансировки, но рассмотрим для упрощения только фазу после получения URL).

Поисковый запрос отработан, и у нас есть URL, мы снова идём на DNS за IP уже целевого ресурса. И тут тоже не всё так просто — целевой сайт может жить в распределённом облаке CDN, а DNS может использовать не просто Round Robin, но и «умную балансировку», например:

  • Метрики загрузки ЦОД

  • Геопривязку

  • Часовой пояс/время

  • Тарифные планы и стоимость ресурсов

  • Метрики доступности

Ровно такая же история на самом деле происходит даже на этапе открытия поисковой системы. Таким образом фиксируем ещё один тип балансирования, №6 — «DNS LB».

Ну, хорошо, мы получили IP-адрес, теперь-то всё определено? И снова нет! 

При «размазывании» нагрузки между ЦОД, даже посредством обычного anycast, у нас будет распределение между «точками входа» в соответствии с метриками маршрутизации, при этом дополнительно уже на уровне DCI (datacenter interconnect) может производиться выравнивание либо принудительное перенаправление нагрузки между ЦОД, например, на основании метрик ёмкости вычислительных ресурсов. Назовем это условно №7 — «ARCH LB».

Как мы ищем короткий путь?
Как мы ищем короткий путь?

Но всё же, допустим, мы добрались до ЦОД, в котором, собственно, будет производиться обработка нашего запроса, что же происходит внутри? А внутри у нас дублирующие устройства, множество параллельных каналов, агрегированные каналы и прочая красота, характерная для современных фабрик.

Фактически, прежде чем мы доберёмся до сервисных слоев, должно быть реализовано распределение нагрузки на сетевом уровне, как между точками входа в ЦОД, так и внутри, причём на каждом из шагов со своей спецификой.

Точки задействования механизмов сетевой балансировки
Точки задействования механизмов сетевой балансировки
  1. Распределение потоков между точками входа в облако

  2. Расчет L3/L2 hash, выбор удаленного VTEP

  3. Для выбранного VTEP выбор транзитного SPINE, для выбранного Spine – выбор порта

  4. Расчет L3/L2 hash, выбор пути к VTEP (а в случае MC-LAG общий адрес размещается на двух коммутаторах в рамках пары)

  5. Выбор исходящего порта – ECMP / LAG

  6. Расчет L3/L2 hash, выбор исходящего порта к серверу в случае локального LAG

При этом не стоит забывать об эффекте поляризации (Hashing Design in Modern Networks:

Challenges and Mitigation Techniques). Или, например, о необходимости обеспечения энтропии при расчете hash для overlay трафика (UDP source port / Inner Headers). Назовем это условно №8 — «NET LB». В некоторых случаях на этом уровне нам необходимо напрямую управлять назначением алгоритмов расчета hash, включая выбор полиномов и входных параметров.

Так вот, сервисный слой, и тут снова не всё так просто — в дело вступает безопасность. NGFW, AntiDDOS, WAF и подобное, и данные сервисные узлы тоже требуется балансировать. А так как они часто еще и tcp-proxy, то просто сетевой балансировки может уже не хватать, поскольку для контроля доступности недостаточно icmp /bfd, требуется L7 Health check. Назовём это №9 — «NET LB+». На этом слое чаще всего у нас также происходит подмена заголовков и дешифровка пакета.

И только после всех этих приключений мы попадаем на «Frontend», да и то — на самом деле это ещё один слой балансирования, на котором реализуются уже манипуляции прикладного уровня:

  • SSL offload

  • L7 healthcheck

  • URL based LB

  • Header modification

  • iRule и его аналоги

  • Многое другое

Это уже то, что более привычно, условно №10 — «APP LB».

И вот, наконец, пройдя этот тяжкий путь, наш запрос попадёт на веб-сервер, который его обработает. А учитывая, что это часто нечто, живущее, например, в K8S, всё ещё только начинается.

Но это уже другая история, а пока давайте сложим все вместе. 

Итак, у нас есть много слоёв балансирования, каждый со своей спецификой, да и встречаются многие из них на пути не раз и не два — «BS > PGW LB», «DPI LB», «CGNAT LB», «AAA LB», «FLOW LB», «DNS LB», «ARCH LB», «NET LB», «NET LB+», «APP LB». Даже в нашем упрощённом сценарии мы видим порядка 10 разных типов балансирования нагрузки, каждый со своей спецификой контроля ресурсов, модификации трафика и уровня/метода распределения. 

Главное —  это найти баланс
Главное — это найти баланс

Это может выглядеть сверхсложной, неуправляемой и неустойчивой конструкцией, однако, как бы это ни казалось странным, всё это великолепие работает, в чём мы можем убедиться. Собственно, даже то, что вы можете прочитать этот очерк, — лишнее тому подтверждение. 

Ну и, как мы все можем убедиться, у манулов с зажировкой всё хорошо, с чем я вас и поздравляю!

Зажировка прошла успешно
Зажировка прошла успешно