Ограничения стандартного балансировщика Service
В Kubernetes за внутреннюю и внешнюю балансировку запросов отвечает ресурс типа Service
. Он распределяет запросы между рабочими подами приложения и исключает из балансировки повреждённые экземпляры. Для проверки способности пода обрабатывать входящие запросы применяются readiness-пробы, которые указываются в спецификации контейнеров, входящих в этот под.
Стандартный инструмент балансировки Service подходит для большинства задач облачных приложений, но имеет два ограничения:
- Если хотя бы один контейнер в поде не проходит проверку готовности (readiness-пробу), весь под отмечается как
NotReady
и исключается из балансировки всех сервисов, с которыми он связан. - Для каждого контейнера можно настроить только одну пробу, поэтому невозможно создать отдельные пробы для проверки, например, доступности чтения и записи.
Примеры сценариев, где стандартного балансировщика недостаточно:
- База данных:
- Работает в трёх подах —
db-0
,db-1
иdb-2
, каждый из которых содержит один контейнер с запущенным процессом базы данных. - Необходимо создать два сервиса (Service) —
db-write
для записи иdb-read
для чтения. - Запросы на чтение должны балансироваться между всеми подами.
- Запросы на запись балансируются только на тот под, который назначен мастером средствами самой базы данных.
- Работает в трёх подах —
- Виртуальная машина:
- Под содержит единственный контейнер, в котором запущен процесс
qemu
, выполняющий роль гипервизора для гостевой виртуальной машины. - В гостевой виртуальной машине запущены независимые процессы, например, веб-сервер и SMTP-сервер.
- Требуется создать два Service —
web
иsmtp
, каждый из которых которых будет иметь свои readiness-пробы.
- Под содержит единственный контейнер, в котором запущен процесс
Возможности балансировщика ServiceWithHealthcheck
В отличие от стандартного балансировщика, где readiness-пробы привязаны к состоянию контейнеров, ServiceWithHealthcheck
позволяет настраивать активные пробы на отдельные TCP-порты. Таким образом, каждый балансировщик, обслуживающий один и тот же под, может работать независимо от других.
Настроить данный способ балансировки можно при помощи ресурса ServiceWithHealthchecks:
- Его спецификация идентична стандартному
Service
с добавлением разделаhealthcheck
, который содержит набор проверок. - На данный момент поддерживается три вида проб:
TCP
— обычная проверка с помощью установки TCP-соединения.HTTP
— возможность отправить HTTP-запрос и ожидать определённый код ответа.PostgreSQL
— возможность отправить SQL-запрос и ожидать его успешного завершения.
Ознакомиться с примерами можно в документации.
Внутреннее устройство балансировщика ServiceWithHealthcheck
Балансировщик состоит из двух компонентов:
- контроллер — работает на мастер-узлах кластера и управляет ресурсами
ServiceWithHealthcheck
, - агенты — работают на каждом узле кластера и выполняют пробы для подов, запущенных на этом узле.
Балансировщик ServiceWithHealthcheck спроектирован так, чтобы не зависеть от реализации CNI, используя при этом стандартные ресурсы Service
и EndpointSlice
:
- Контроллер при создании ресурса
ServiceWithHealthcheck
автоматически создает одноименный ресурс Service в том же пространстве имен с пустым полемselector
. Это позволяет избежать создания стандартным контроллеромEndpointSlice
, которые используются для настройки балансировки. - Каждый агент при появлении на своём узле подов, которые попадают под управление
ServiceWithHealthcheck
, осуществляет настроенные пробы и создаёт для нихEndpointSlice
со списком проверенных IP-адресов и портов. ДанныйEndpointSlice
привязан к дочернему ресурсуService
, созданному выше. - CNI сопоставит все
EndpointSlice
со стандартными сервисами, созданными выше и осуществит балансировку по проверенным IP-адресам и портам на всех узлах кластера.
Миграция с Service на ресурс ServiceWithHealthchecks, например в рамках CI/CD, не должна вызвать затруднений. Спецификация ServiceWithHealthchecks в основе своей повторяет спецификацию Service, но содержит дополнительный раздел healthchecks. Во время жизненного цикла ресурса ServiceWithHealthchecks создается одноименный сервис в том же namespace, чтобы привычным способом (kube-proxy или cni) направить трафик на рабочие нагрузки в кластере.