Page tree
Skip to end of metadata
Go to start of metadata

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

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

В Kubernetes за балансировку сетевого трафика на уровне L4 отвечает сущность Service (сервис) с типом LoadBalancer.

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

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

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

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

  • балансировщик нагрузки - 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-адрес, заголовки, метод, тело запроса).

  • сохраните следующую спецификацию для создания приложения в YAML-файл с именем echoserver.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
  • выполните в kubectl команду:
kubectl apply -f echoserver.yaml

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

deployment.apps/echoserver created

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

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

service-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-lb
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

Где:

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

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

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

Для создания LoadBalancer с внутренним IP-адресом необходимо добавить следующие аннотации: cloud.mts.ru/load-balancer-type: private и cloud.mts.ru/private-load-balancer-ip: {IP-адрес из допустимого диапазона}.

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

service-lb.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-адрес балансировщика указывается, то он должен быть валидным (смотрите раздел LoadBalancer с внутренним IP-адресом данной статьи), иначе балансировщик не создастся
  • externalTrafficPolicy — параметр, с помощью которого возможно управлять маршрутизацией трафика на нодах
    Возможные параметры:
    • Cluster — трафик попадает на любой из узлов кластера; при этом:
      • в случае отсутствия нужных подов на узле, трафик перенаправляется с помощью kube-proxy на другой узел
    • СКОРО Local — трафик напрямую попадает на узлы, где запущены контейнеры приложений; при этом:
      • используется меньше горизонтального трафика между виртуальными машинами
  • protocol — параметр, который позволяет выбрать протокол передачи данных
    Возможные параметры:
    • TCP — гарантирует доставку данных; подходит для большинства сценариев.  

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

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

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

  • выполните в kubectl команду:
kubectl apply -f service-lb.yaml

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

service/sample-lb created

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

  • выполните в kubectl команду:
kubectl get services

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

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

или

  • на странице "Кластеры" нажмите на название кластера, в котором создавался Load Balancer
  • перейдите на вкладку Балансировщики нагрузки - там доступен список балансировщиков, созданных в этом кластере

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

  • в терминале выполните команду:
curl xxx.xxx.xxx.xxx

или

  • перейдите в браузере на адрес xxx.xxx.xxx.xxx

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

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

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

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

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

  • в терминале локальной машины выполните команду:
kubectl get pods

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

NAME                     READY   STATUS    RESTARTS   AGE
{полное название пода}   1/1     Running   0          20h
  • скопируйте полное название пода и вставьте в следующую команду в терминал локальной машины:
kubectl exec --stdin --tty {полное название пода} -- /bin/bash
  • в итоге после подключения к кластеру откроется терминал:
root@{полное название пода}:/#

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

  • в открывшемся терминале выполните команду:
curl xxx.xxx.xxx.xxx:pppp

Где:

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

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

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


  • No labels