Новый Балансировщик Нагрузки L4 Со Встроенной Реализацией Обнаружения Служб Записей Srv И Обнаружения Служб Docker Api.

Как это все началось Работая с микросервисами, мы неоднократно сталкивались с проблемами обнаружения сервисов при автомасштабировании и схлопыванием лишних узлов.

Мы перепробовали почти все решения, которые существовали или существуют на данный момент, но как обычно ничего идеально не вписывается в наши динамические среды (десятки остановок/запусков однотипных контейнеров в час).

Ближайшим решением были шаблоны NGINX+Consul+Consul, но оно было некрасивым, требовало перезагрузки и не позволяло использовать внешние проверки работоспособности, кроме как через Consul. В общем, как всегда бывает, было принято решение написать свое решение.

В ходе обсуждения всплыли десятки вещей, которые было бы хорошо реализовать, и были выбраны наиболее критичные для нас и интересные для публики.

Реализованный функционал для первой итерации



Типы балансировки:

Ифаш Листконн По-круговой Масса

Обнаружение (определение пула бэкэндов для каждого фронтенда):

Статика — это просто список серверов в конфиге.

Docker — запрос к Docker/Swarm API, отфильтрованный по метке и внутренним портам контейнера.

Exec — инициирует запуск внешнего скрипта, читает из stdout и парсит его по штатной последовательности (пока это жестко запрограммировано).

JSON — запрашивает URL-адрес через http-запрос и разбирает его по шаблонам (поддерживает многоуровневый JSON).

Plaintext — запрашивает URL-адрес через http-запрос и анализирует его с помощью регулярного выражения, указанного в конфиге.

SRV — запрашивает указанный DNS для записей SRV по имени службы.

Проверка здоровья Поскольку изначально было совершенно ясно, что мы просто не сможем реализовать проверки работоспособности в масштабе того же хапрокси, было решено отделаться легко и сделать всего 2 вида проверок работоспособности.

Ping — простой TCP-пинг; Exec — запуск произвольного бинарного файла, передача ему параметров и чтение вывода со стандартного вывода.

Примеры использования

СРВ Дискавери

У нас есть произвольные сервисы, которые сами регистрируются, например, в Консуле.

Мы будем использовать Consul DNS для определения пула серверов.



Новый балансировщик нагрузки L4 со встроенной реализацией обнаружения служб записей SRV и обнаружения служб Docker API.

В этом примере мы определили тип балансировки как «srv»; мы также определили DNS-сервер и его порт, на который будут поступать запросы службы обнаружения.

Определена частота обновления списка серверов, а также важная переменная — политика на случай, когда DNS-сервер не ответил.

Для максимальной согласованности среды вам необходимо установить errorpolicy="setempty".

В этом случае при отсутствии ответа от DNS весь пул внутренних серверов будет сброшен, а входящие соединения будут сброшены.

В противном случае нужно использовать errorpolicy="keeplast", тогда балансировщик будет использовать самые последние данные, полученные до сбоя DNS-соединения.

  
   

toml [servers.sample2] bind = "localhost:3001" protocol = "tcp" balance = "weight" [servers.sample2.discovery] failpolicy = "keeplast" kind = "srv" srv_lookup_server = "66.66.66.66:8600" # dns server and port srv_lookup_pattern = "api.service.ireland.consul." # SRV service pattern [servers.sample2.healthcheck] fails = 1 passes = 1 interval = "2s" kind = "ping" timeout = "500ms"



Балансировка Docker/Swarm.

По сути, различий в API и способе настройки Docker/Docker Swarm нет. Мы можем одинаково работать как с хостом Docker, так и с кластером Docker Swarm. Давайте рассмотрим работу с ними на одном примере.



Новый балансировщик нагрузки L4 со встроенной реализацией обнаружения служб записей SRV и обнаружения служб Docker API.

Теперь мы сбалансируем отдельные сервисы, используя Docker Swarm в качестве более общего примера.

Все описанное ниже работает и для отдельного хоста Docker. В этом примере мы определяем тип обнаружения как «докер», определяем базовый URL-адрес докера, метки и внутренний порт докер-контейнера (со стороны сети самого контейнера), с помощью которого балансировщик будет делать выбор, из которого будет создан пул.

бэкэнд-серверов сформировано.

В этом примере мы будем использовать более «продвинутый» тип проверок работоспособности, а именно исполнительные проверки работоспособности.

Помимо параметров частоты запуска проверок, есть еще время выполнения скрипта.

Время между запусками должно быть больше времени выполнения скрипта, чтобы не было «налетов».

Команда для запуска этой проверки работоспособности формируется как /path/to/script [ip] [порт].

После запуска сценария он должен вывести на стандартный вывод строку, которая сравнивается с ожидаемыми положительными и отрицательными результатами.



[servers.sample3] bind = " localhost:3002 " protocol = "tcp" balance = "weight" [servers.sample3.discovery] interval = "10s" timeout = "2s" kind = "docker" docker_endpoint = " http://localhost:2377 " # Docker / Swarm API docker_container_label = "api=true" # label to filter containers docker_container_private_port = 80 # gobetween will take public container port for this private port [servers.sample3.healthcheck] kind = "exec" interval = "2s" exec_command = "/etc/gobetween/checks/exec_healthcheck.sh" exec_expected_positive_output = "1" exec_expected_negative_output = "0" exec_timeout_duration = "1s"

В последующих статьях я планирую привести несколько примеров более сложного использования других типов открытий.

Также будет описана специфика настройки и установки под Windows.

Теги: #балансировка нагрузки #docker #записи srv #обнаружение сервисов #golang #Windows #открытый исходный код
Вместе с данным постом часто просматривают: