Как настроить балансировку нагрузки в Kubernetes?

Уровни балансировки в Kubernetes

Балансировка в Kubernetes может происходить на нескольких уровнях. На уровне L4 (TCP/UDP) — через объекты Service, которые распределяют трафик между подами; на уровне L7 (HTTP/HTTPS) — через Ingress или Gateway API; в более сложных сценариях — через сервис-меш (например, Istio или Linkerd), который управляет маршрутизацией и политиками на прикладном уровне.

Типы Service и их роль в балансировке

ClusterIP — создаёт виртуальный IP для доступа к сервису только изнутри кластера, балансирует трафик между подами через kube-proxy.
NodePort — дополнительно к ClusterIP открывает порт на каждом узле кластера, делая сервис доступным извне по NodeIP:NodePort.
LoadBalancer — создаёт внешний балансировщик (в облачных кластерах) или требует внешней реализации для bare-metal; использует NodePort под капотом.
Headless — не назначает виртуальный IP, а возвращает IP каждого пода напрямую, что позволяет клиентам самостоятельно балансировать трафик.

kube-proxy и алгоритмы распределения

kube-proxy — это компонент, работающий на каждом узле кластера и отвечающий за маршрутизацию трафика на уровне L4. Он может работать в режиме iptables или IPVS.

  • iptables: использует правила NAT в ядре, балансировка по принципу round-robin.

  • IPVS: поддерживает разные алгоритмы (round robin, least connections и другие), масштабируется лучше при большом числе сервисов и эндпоинтов.

Балансировка в облаке и на bare-metal

В облачных средах Service типа LoadBalancer создаёт внешний балансировщик автоматически (например, в AWS, GCP, Azure), получает внешний IP и распределяет трафик по узлам кластера.
В bare-metal окружении такой функционал отсутствует «из коробки», поэтому применяют решения вроде MetalLB. MetalLB назначает внешние IP-адреса сервисам и умеет работать в двух режимах:

  • Layer 2 — отвечает на ARP/NDP запросы, выдавая внешний IP.

  • BGP — анонсирует IP через протокол маршрутизации BGP.

Балансировка на уровне L7 — Ingress и Gateway API

Для HTTP(S) используют Ingress — объект, который описывает правила маршрутизации по домену и пути. Чтобы правила работали, в кластере должен быть установлен Ingress Controller (например, NGINX, Traefik, Envoy). Контроллер принимает внешний трафик, завершает TLS, распределяет запросы по сервисам и может применять дополнительные политики (лимиты, переписывание путей, sticky sessions).
Gateway API — более современная альтернатива Ingress, с расширенными возможностями маршрутизации и политик.

Здоровье подов и исключение неработающих экземпляров

Чтобы балансировка корректно исключала поды, которые не готовы к приёму трафика, в манифестах Deployment или StatefulSet настраивают readinessProbe. Kubernetes и балансировщики исключают поды, у которых probe не проходит. Это критично при обновлениях, сбоях или медленном старте приложения.

Пошаговая настройка балансировки нагрузки

  1. Определить уровень балансировки: L4 для произвольных протоколов или L7 для HTTP(S).

  2. Для внутреннего доступа — создать Service типа ClusterIP.

  3. Для внешнего доступа:

    • В облаке — Service типа LoadBalancer.

    • На bare-metal — установить и настроить MetalLB с пулом IP.

  4. Для HTTP(S) — развернуть Ingress Controller, создать Ingress с правилами маршрутизации и TLS-секретами.

  5. Включить и проверить readinessProbe у всех подов.

  6. При необходимости настроить sessionAffinity, таймауты, лимиты, алгоритмы балансировки.

  7. Провести тестирование отказоустойчивости и нагрузочное тестирование, проверив, как балансировщик ведёт себя при сбоях подов и увеличении нагрузки.

Частые ошибки при настройке

  • Отсутствие readinessProbe приводит к отправке трафика на поды, которые ещё не готовы.

  • Ожидание автоматического внешнего IP на bare-metal без установки MetalLB.

  • Неправильная конфигурация Ingress или неподходящий контроллер для выбранных аннотаций.

  • Игнорирование тестирования на отказоустойчивость и пиковую нагрузку, что приводит к проблемам в продакшене.