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