Балансировка нагрузки в Kubernetes

    Команда Simple-Server
    03.06.2026
    9 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Отслеживание подов в Kubernetes с селектором и без него

    Поды в Kubernetes являются временными объектами и получают новый IP при каждом запуске: после выполнения определенной задачи они уничтожаются и затем создаются заново при новом развертывании. При отсутствии инструментов Kubernetes service нам пришлось бы отслеживать IP всех активных подов. И это было бы крайне сложной задачей, особенно по мере того, как наше приложение масштабируется. Служба Kube решает эту проблему благодаря селектору. Посмотрим на такой код (замените значения в ряде строк на нужные):

    kind: Service metadata: name: timewebapp spec: selector: app: timewebapp ports: - protocol: TCP name: timewebapp port: 5428 targetPort: 5428

    Селектор обеспечивает корректность сопоставления служб с относящимися к ним подами. Когда служба получает под с matching label, то происходит обновление IP пода в списках объектов Endpoints. Endpoints отслеживают IP-адреса всех подов и обновляются автоматически, а каждая служба создает свой объект Endpoint.

    Впрочем, для наших целей нам не нужно вдаваться в подробности об Endpoints. Просто помните, что именно Endpoints обновляют список IP-адресов, чтобы служба Kube могла перенаправлять свой трафик.

    Далее заметим, что способ определения службы с помощью селектора является наиболее распространенным, однако мы также можем определить службу без селектора. Например, если мы перенесем наше приложение в Kube, то сможем оценить его поведение без переноса сервера. Давайте попробуем использовать существующее приложение, находящееся на старом сервере:

    kind: Service metadata: name: timewebapp-without-ep spec: ports: - protocol: TCP port: 5428 targetPort: 5428 kind: Endpoints metadata: name: timewebapp-without-ep subsets: - addresses: - ip: x.x.x.x #укажите актуальный IP ports: - port: 5428

    Это позволит установить имя timewebapp-without-ep для подключения к серверу timewebapp.

    Kube по умолчанию всегда создает службу вида ClusterIP. Однако существует четыре вида служб, рассчитанных каждая на свои задачи, и вместе они помогают обеспечить достаточно гибкую балансировку нагрузки. Рассмотрим их все и приведем примеры кода для настройки.

    Предназначен для внутрикластерного взаимодействия приложений. Настраивается это так (значения приложения даны случайные, их следует заменить на свои):

    kind: Service #обязательная строчка для определения любой службы metadata: name: timewebapp spec: type: ClusterIP selector: app: timewebapp ports: - protocol: TCP port: 5428 targetPort: 5428

    Внешняя служба для сопоставления подов с хостами через постоянный порт, прописываемый отдельно ниже (все значения тоже даны случайные, замените их на свои):

    kind: Service metadata: name: timewebapp spec: type: NodePort selector: app: timewebapp ports: - protocol: TCP port: 5428 targetPort: 5428 nodePort: 32157

    Служба для работы в облачной инфраструктуре. Позволяет обеспечить маршрутизацию, например, через сайт. Вот код запуска:

    kind: Service metadata: name: timewebapp spec: type: LoadBalancer selector: app: timewebapp ports: - protocol: TCP port: 5428 targetPort: 5428

    Эта служба нужна для обеспечения внекластерного доступа. Делается это просто:

    metadata: name: timewebapp spec: type: ExternalName externalName: timewebapp.mydomain.ru

    Далее отметим, что у любой службы создается имя DNS по такому шаблону: название-службы.пространство-имен.svc.cluster.local. Такая запись будет указывать на IP кластера. А при ее отсутствии Kube будет обращаться к IP отдельных подов.

    Разновидности балансировки через службы Kube

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

    Внутрикластерная балансировка

    Для внутрикластерной балансировки предназначена служба ClusterIP (код для настройки этой и других служб Kube мы публиковали выше в их описаниях). Она подойдет, например, для организации взаимодействия отдельных групп подов, расположенных в пределах одного кластера Kube. Организовать доступ к службе можно организовать двумя способами: через DNS или при помощи переменных окружения.

    Про то, как это делается с помощью DNS, было сказано выше. Добавим, что такая организация доступа — это наиболее распространенный и рекомендуемый способ взаимодействия микросервисов. Однако учтите, что DNS работают в Kube только с надстройкой DNS-сервера: например, CoreDNS.

    Что касается переменных среды, то они устанавливаются при запуске нового пода через инструкцию service-name. Вам могут понадобиться переменные PORT и SERVICE_HOST, а вот инструкции для их установки:

    service-name_PORT service-name_SERVICE_HOST

    Она может выполняться с использованием NodePort (далее NP) и LoadBalancer (далее LB). NP подходит для балансировки ограниченного числа служб, а его преимущество заключается в обеспечении подключения без выделенного внешнего инструмента балансировки.

    Первое ограничение NP: он подходит только для частной сети, а вот интернет-подключение через NP организовать не получится. Еще один недостаток NP в том, что он работает только через статические порты и в ограниченном диапазоне, причем служба должна выделять один и тот же порт для каждого узла. Это становится проблематичным, когда приложение масштабируется до нескольких микросервисов.

    LB предоставляет общедоступный IP или DNS, к которым могут подключаться внешние пользователи. Трафик поступает от LB к сопоставляемой службе на назначенном порту, который в конечном итоге перенаправляет его на рабочие поды. Однако у LB нет прямого соответствия с подами.

    Давайте посмотрим, как создать внешний LB. В примере ниже мы запустим под и подключим его графический интерфейс из внешней сети. Обратите внимание, что LB не фильтрует входящий или исходящий трафик. Это просто прокси для связи с внешней сетью, перенаправляющий трафик на соответствующие модули/сервисы. Создаем кластер командой create cluster и прописываем следующие параметры (значения name и region приведены для примера, а в поле ssh-public-key введите свой публичный ключ SSH).

    --name myTimewebCluster  --region my-Simple-Server-region  --with-oidc  --ssh-access  --ssh-public-key <xxxxxxxxxx>  --managed

    О том, как сгенерировать ключи SSH, смотрите в нашем руководстве.

    Теперь редактируем yaml пода:

    kind: Pod metadata: name: timewebpod labels: app: timewebpod spec: containers: - name: timewebpod image: timewebpod:latest kubectl apply -f timewebpod.yaml

    Проверяем работоспособность:

    kubectl get pods --selector='app=timewebpod'

    И подключаем LB (значения в образцах кода случайные, замените их на актуальные):

    kind: Service metadata: name: timewebpod-ext-serv spec: type: LoadBalancer selector: app: timewebpod ports: - name: timewebpod-admin protocol: TCP port: 14953 targetPort: 14953

    Далее стартуем сервис и подтверждаем:

    kubectl apply -f timewebpod-svc.yaml service/timewebpod-ext-serv created kubectl get svc

    Полученный DNS копируем в браузер и не забываем там же прописать порт, указанный в коде выше. Допустим, мы получили такой DNS:

    http://b9f305e6d743a85cb32f48f6a210cb51.my-Simple-Server-region.ru

    Тогда нужно вставить в браузер следующее:

    http://b9f305e6d743a85cb32f48f6a210cb51.my-Simple-Server-region.ru: 14953

    Теперь вы сможете поделиться этим адресом с любым, кто желает подключиться к вашей записи администратора. Как видим, создать и настроить внешний балансировщик для приложения довольно легко. Правда, у Load Balancer есть некоторые ограничения, но их помогает обойти Ingress.

    Балансировка через Ingress

    Мы видели, что LoadBalance создает экземпляры приложения для каждой службы. Это нормально, пока у нас есть несколько служб, однако с увеличением служб управлять ими становится сложно. Кроме того, LB не поддерживает маршрутизацию URL, SSL и многое другое. И здесь на помощь приходит Ingress, который является расширением для NP и LB. В задачи Ingress входит обработка внутреннего трафика с целью определить, какие поды или службы пересылать дальше. Основной функцией Ingress является балансировка нагрузки, однако с его помощью можно также выполнять маршрутизацию URL, терминацию SSL и ряд других функций. Конфигураций Ingress довольно много, и их нетрудно найти по запросам. Приведем одну в качестве иллюстрации:

    В приведенном примере определены правила, по которым будет идти трафик от конечных пользователей. Нужно также добавить, что Ingress не является службой Kube, как, например, LB или NP, а представляет собой набор правил, используемый этими службами. Кроме того, кластеру, использующему Ingress, необходим Ingress Controller. Этих контроллеров создано довольно много, а ознакомиться с некоторыми популярными решениями вы можете по этим ссылкам: AWS ALB, NGINX, Istio, Traefik.

    Добавим, что различные контроллеры имеют разные функции и возможности, поэтому вам придется оценить их, исходя из ваших требований. Но какой бы контроллер вы ни использовали, Ingress значительно упростит настройку и управление правилами маршрутизации и поможет реализовать трафик на основе SSL. И, конечно, как и традиционные инструменты, контроллеры Ingress поддерживают различные алгоритмы балансировки.


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны