Skip to content
На этой странице:

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

Балансировщик нагрузки (Load Balancer) предоставляет сервис для приложений по распределению сетевого трафика между несколькими серверами или ресурсами, размещенными в облаке. Балансировщик нагрузки помогает достичь оптимальной утилизации ресурсов, горизонтального масштабирования и обеспечения отказоустойчивости.

В Kubernetes за балансировку сетевого трафика на уровне L4 отвечает сущность Service (сервис) с типом LoadBalancer. В Containerum Kubernetes реализован Диспетчер облачных контроллеров (Cloud Controller Manager, CCM), который после применения манифеста самостоятельно создаст нужный Балансировщик нагрузки.

Существует 2 типа балансировщиков нагрузки:

  • LoadBalancer с публичным IP-адресом

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

  • LoadBalancer с внутренним IP-адресом

    Приложение будет доступно из облачной сети Cloud MTS либо из внутренних сетей организации, подключенных через VPN. При выборе этой опции IP адрес балансировщика не должен пересекаться с выделенными внутри облака CloudMTS подсетями, либо с подсетями организации, из которых требуется доступ до приложения.

Примечание

Созданный сетевой балансировщик тарифицируется согласно установленным правилам тарификации:

  • Балансировщик нагрузки - 0,5 рублей / час без НДС
  • Публичный IP-адрес - 0,1667 рублей / час без НДС (только для LoadBalancer с публичным IP-адресом)

LoadBalancer с внутренним IP-адресом

IP-адрес для LoadBalancer с внутренним IP-адресом может быть назначен любым из следующих способов:

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

При автоматическом назначении выбирается свободный и валидный IP-адрес.

К внутренним адресам, доступным для создания LoadBalancer, относятся IP-адреса из следующих подсетей (стандарт RFC 1918):

  • от 10.0.0.0 до 10.255.255.255 с маской 255.0.0.0 или /8 (за исключением подсетей 10.28.0.0/16, 10.22.64.0/18, 10.22.8.0/24, 10.22.9.0/27, 10.22.128.0/18, 10.25.1.239/32, 10.30.0.0/24)
  • от 172.16.0.0 до 172.31.255.255 с маской 255.240.0.0 или /12
  • от 192.168.0.0 до 192.168.255.255 с маской 255.255.0.0 или /16

Внимание

Заданный вручную внутренний IP-адрес не должен пересекаться с:

  • IP-адресами других балансировщиков нагрузки из внутренней сети, то есть внутри одного проекта
  • подсетями, зарезервированными для инфраструктуры внутри облака CloudMTS (указаны выше)
  • подсетями Service CIDR, Cluster (Pods) CIDR (задаются в дополнительных настройках сети при создании кластера) всех кластеров Containerum в рамках одного проекта
  • с подсетью для нод, которая была выбрана при создании кластера
  • другими подсетями, созданными в рамках одного проекта

Таким образом:

  • невозможно создать 2 LoadBalancer с одним и тем же внутренним IP-адресом
  • невозможно создать LoadBalancer, если внутренний IP-адрес LoadBalancer пересечется с задействованными диапазонами подсетей

Важно

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

Создайте приложение

Для примера возьмем приложение echoserver, которое возвращает параметры запроса к приложению (IP адрес, заголовки, метод, тело запроса).

  1. Сохраните следующую спецификацию для создания приложения в YAML-файл с именем echoserver.yaml:

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echoserver
    spec:
      selector:
        matchLabels:
          app: echoserver
      replicas: 1
      template:
        metadata:
          labels:
            app: echoserver
        spec:
          containers:
            - image: gcr.io/google_containers/echoserver:1.0
              imagePullPolicy: IfNotPresent
              name: echoserver
              ports:
                - containerPort: 8080
  2. Выполните команду:

    sh
    kubectl apply -f echoserver.yaml

    Результат выполнения команды:

    sh
    deployment.apps/echoserver created

Создайте сервис типа LoadBalancer

  1. Сохраните следующую спецификацию для создания сервиса типа LoadBalancer в YAML-файл с именем service-lb.yaml:

    LoadBalancer с публичным IP-адресом
    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: sample-lb
    spec:
      selector:
        app: echoserver
      externalTrafficPolicy: Cluster # Возможные значения "Cluster" или "Local"
      type: LoadBalancer
      ports:
        - port: 80 # порт, на котором будет доступно ваше приложение извне
          name: "main"
          targetPort: 8080 # внутренний порт контейнера с вашим приложением
          protocol: TCP # Возможные значения "TCP" или "UDP"
        - port: 8080
          name: "secondary"
          targetPort: 8080
          protocol: TCP

    где:

    • externalTrafficPolicy — параметр, с помощью которого можно управлять маршрутизацией трафика на нод. Возможные параметры:

      • Cluster — трафик попадает на любой из узлов кластера; при этом в случае отсутствия нужных подов на узле трафик перенаправляется с помощью kube-proxy на другой узел.
      • [СКОРО] Local — трафик напрямую попадает на узлы, где запущены контейнеры приложений; при этом сохраняется IP-адрес запроса пользователя, и используется меньше горизонтального трафика между виртуальными машинами.
    • protocol — параметр, который позволяет выбрать протокол передачи данных. Возможные параметры:

      • TCP — гарантирует доставку данных. Подходит для большинства сценариев.
      • UDP — работает быстрее, но не гарантирует доставку данных. Используется для систем чувствительных к задержкам, например, для стриминга, видео-конференций и т.д.
    LoadBalancer с внутренним IP-адресом без указания диапазона
    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: sample-lb
      annotations:
        cloud.mts.ru/load-balancer-type: private # для указания типа балансировщика (обязательно)
        cloud.mts.ru/private-load-balancer-ip: {IP-адрес из допустимого диапазона} # задает внутренний IP балансировщика (опционально)
    spec:
      selector:
        app: echoserver
      externalTrafficPolicy: Cluster
      type: LoadBalancer
      ports:
        - port: 80 # порт, на котором будет доступно ваше приложение извне
          name: "main"
          targetPort: 8080 # внутренний порт контейнера с вашим приложением
          protocol: TCP # Возможные значения "TCP" или "UDP"
        - port: 8080
          name: "secondary"
          targetPort: 8080
          protocol: TCP

    где:

    • cloud.mts.ru/load-balancer-type: private — аннотация, которая позволяет пометить балансировщик с внутренним IP-адресом; указывать тип балансировщика необходимо, если это LoadBalancer с внутренним IP-адресом

    • cloud.mts.ru/private-load-balancer-ip — ключ аннотации, который позволяет задать внутренний IP-адрес; адрес можно не указывать - тогда балансировщику будет сгенерирован и присвоен внутренний IP-адрес автоматически; если IP-адрес балансировщика указывается, то он должен быть валидным, иначе балансировщик не создастся.

    • externalTrafficPolicy — параметр, с помощью которого можно управлять маршрутизацией трафика на узлах. Возможные параметры:

      • Cluster — трафик попадает на любой из узлов кластера; при этом в случае отсутствия нужных подов на узле трафик перенаправляется с помощью kube-proxy на другой узел.
      • [СКОРО] Local — трафик напрямую попадает на узлы, где запущены контейнеры приложений; при этом сохраняется IP-адрес запроса пользователя, и используется меньше горизонтального трафика между виртуальными машинами.
    • protocol — параметр, который позволяет выбрать протокол передачи данных. Возможные параметры:

      • TCP — гарантирует доставку данных. Подходит для большинства сценариев.
      • UDP — работает быстрее, но не гарантирует доставку данных. Используется для систем чувствительных к задержкам, например, для стриминга, видео-конференций и т.д.
    LoadBalancer с внутренним IP-адресом из заданного диапазона
    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: sample-lb
      annotations:
        cloud.mts.ru/load-balancer-type: private # для указания типа балансировщика (обязательно)
        cloud.mts.ru/private-load-balancer-ip-range: {IP-range из допустимого диапазона, например 192.168.0.0/24} # задает внутренний IP балансировщика (автоматически)
    spec:
      selector:
        app: echoserver
      externalTrafficPolicy: Cluster
      type: LoadBalancer
      ports:
        - port: 80 # порт, на котором будет доступно ваше приложение извне
          name: "main"
          targetPort: 8080 # внутренний порт контейнера с вашим приложением
          protocol: TCP # Возможные значения "TCP" или "UDP"
        - port: 8080
          name: "secondary"
          targetPort: 8080
          protocol: TCP

    где:

    • cloud.mts.ru/load-balancer-type: private — аннотация, которая позволяет пометить балансировщик с внутренним IP-адресом; указывать тип балансировщика необходимо, если это LoadBalancer с внутренним IP-адресом

    • cloud.mts.ru/private-load-balancer-ip-range — ключ аннотации, который позволяет задать внутренний диапазон для выбора IP-адреса; внутренний IP-адрес будет сгенерирован и присвоен автоматически из этого диапазона; если диапазон IP-адресов балансировщика указывается, то он должен быть валидным, иначе балансировщик не создастся.

    • externalTrafficPolicy — параметр, с помощью которого можно управлять маршрутизацией трафика на узлах. Возможные параметры:

      • Cluster — трафик попадает на любой из узлов кластера; при этом в случае отсутствия нужных подов на узле трафик перенаправляется с помощью kube-proxy на другой узел.
      • [СКОРО] Local — трафик напрямую попадает на узлы, где запущены контейнеры приложений; при этом сохраняется IP-адрес запроса пользователя, и используется меньше горизонтального трафика между виртуальными машинами.
    • protocol — параметр, который позволяет выбрать протокол передачи данных. Возможные параметры:

      • TCP — гарантирует доставку данных. Подходит для большинства сценариев.
      • UDP — работает быстрее, но не гарантирует доставку данных. Используется для систем чувствительных к задержкам, например, для стриминга, видео-конференций и т.д.

    Одновременная работа по протоколам TCP и UDP не поддерживается.

    Подробнее про настройки сервиса можно прочитать в документации K8s.

  2. Выполните команду:

    sh
    kubectl apply -f service-lb.yaml

    Результат выполнения команды:

    sh
    service/sample-lb created

Посмотрите информацию о созданном сетевом балансировщике нагрузки

В UI

  1. На странице Кластеры нажмите на название кластера, в котором создавался Load Balancer.
  2. Перейдите на вкладку Балансировщики нагрузки. Вы увидите список балансировщиков, созданных в этом кластере.

В терминале

Выполните команду:

sh
kubectl get services

Результат выполнения команды:

sh
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                       AGE
kubernetes   ClusterIP      10.96.0.1     <none>         443/TCP                       3d5h
sample-lb    LoadBalancer   10.96.99.48   89.22.180.65   80:31504/TCP,8080:30245/TCP   2m52s

Проверьте доступность приложения

LoadBalancer с публичным IP-адресом

В терминале выполните команду curl http://xxx.xxx.xxx.xxx, или перейдите в браузере по адресу http://xxx.xxx.xxx.xxx, где:

  • xxx.xxx.xxx.xxx — публичный IP-адрес из поля EXTERNAL-IP. Публичный IP-адрес также можно посмотреть в UI на странице Балансировщики нагрузки.

Результат выполнения команды:

sh
CLIENT VALUES:
client_address=('100.64.48.21', 13315) (100.64.48.21)
command=GET
path=/
real path=/
query=
request_version=HTTP/1.1
 
SERVER VALUES:
server_version=BaseHTTP/0.6
sys_version=Python/3.5.0
protocol_version=HTTP/1.0
 
HEADERS RECEIVED:
Accept=*/*
Host=91.185.95.154
User-Agent=curl/7.71.1
LoadBalancer с внутренним IP-адресом

Чтобы протестировать работоспособность балансировщика, нужно из одного кластера отправить запрос на другой. Для этого понадобится подключиться ко второму кластеру и открыть в нем терминал.

  1. Создайте еще один кластер в текущем проекте и разверните на нем еще одно приложение echoserver (или любое другое).

  2. В терминале локальной машины выполните команду:

    sh
    kubectl get pods

    Результат выполнения команды:

    sh
    NAME                     READY   STATUS    RESTARTS   AGE
    {полное название пода}   1/1     Running   0          20h
  3. Cкопируйте полное название пода и вставьте в следующую команду в терминал локальной машины:

    sh
    kubectl exec --stdin --tty {полное название пода} -- /bin/bash

    После подключения к кластеру откроется терминал:

    sh
    root@{полное название пода}:/#

    Совет

    Подключиться к кластеру и открыть терминал также можно через Lens. Импортируйте kubeconfig нового кластера в Lens, подключитесь к кластеру и во вкладке Pods выберите соответствующий под. Подключиться к терминалу можно по кнопке Shell.

  4. В открывшемся терминале выполните команду:

    sh
    curl xxx.xxx.xxx.xxx:pppp

    где:

    xxx.xxx.xxx.xxx — внутренний IP-адрес балансировщика нагрузки первого кластера из поля IP-адрес на странице "Балансировщики нагрузки" или из поля EXTERNAL-IP. pppp - порт, на котором работает созданный ранее балансировщик нагрузки.

    Результат выполнения команды:

    sh
    CLIENT VALUES:
    client_address=('100.64.144.149', 4338) (100.64.144.149)
    command=GET
    path=/
    real path=/
    query=
    request_version=HTTP/1.1
     
    SERVER VALUES:
    server_version=BaseHTTP/0.6
    sys_version=Python/3.5.0
    protocol_version=HTTP/1.0
     
    HEADERS RECEIVED:
    Accept=*/*
    Host=10.129.0.2
    User-Agent=curl/7.38.0

Операции редактирования LoadBalancer

Внимание

В Containerum Kubernetes не поддерживаются операции изменения LoadBalancer. Например, нельзя изменить тип балансировщика с публичного на приватный. Также нельзя заменить один IP-адрес на другой.

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

sh
kubectl delete -f service-lb.yaml

Для создания LoadBalancer с изменениями воспользуйтесь инструкцией по созданию различных типов LoadBalancer. Подробнее...