Балансировщики нагрузки
Балансировщик нагрузки (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 адрес, заголовки, метод, тело запроса).
Сохраните следующую спецификацию для создания приложения в YAML-файл с именем
echoserver.yaml
:yamlapiVersion: 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
Выполните команду:
shkubectl apply -f echoserver.yaml
Результат выполнения команды:
shdeployment.apps/echoserver created
Создайте сервис типа LoadBalancer
Сохраните следующую спецификацию для создания сервиса типа LoadBalancer в YAML-файл с именем
service-lb.yaml
:LoadBalancer с публичным IP-адресом
yamlapiVersion: 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-адресом без указания диапазона
yamlapiVersion: 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-адресом из заданного диапазона
yamlapiVersion: 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.
Выполните команду:
shkubectl apply -f service-lb.yaml
Результат выполнения команды:
shservice/sample-lb created
Посмотрите информацию о созданном сетевом балансировщике нагрузки
В UI
- На странице Кластеры нажмите на название кластера, в котором создавался Load Balancer.
- Перейдите на вкладку Балансировщики нагрузки. Вы увидите список балансировщиков, созданных в этом кластере.
В терминале
Выполните команду:
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
Проверьте доступность приложения
LoadBalancer с публичным IP-адресом
В терминале выполните команду curl http://xxx.xxx.xxx.xxx
, или перейдите в браузере по адресу http://xxx.xxx.xxx.xxx
, где:
xxx.xxx.xxx.xxx
— публичный IP-адрес из поляEXTERNAL-IP
. Публичный IP-адрес также можно посмотреть в UI на странице Балансировщики нагрузки.
Результат выполнения команды:
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-адресом
Чтобы протестировать работоспособность балансировщика, нужно из одного кластера отправить запрос на другой. Для этого понадобится подключиться ко второму кластеру и открыть в нем терминал.
Создайте еще один кластер в текущем проекте и разверните на нем еще одно приложение echoserver (или любое другое).
В терминале локальной машины выполните команду:
shkubectl get pods
Результат выполнения команды:
shNAME READY STATUS RESTARTS AGE {полное название пода} 1/1 Running 0 20h
Cкопируйте полное название пода и вставьте в следующую команду в терминал локальной машины:
shkubectl exec --stdin --tty {полное название пода} -- /bin/bash
После подключения к кластеру откроется терминал:
shroot@{полное название пода}:/#
Совет
Подключиться к кластеру и открыть терминал также можно через Lens. Импортируйте
kubeconfig
нового кластера в Lens, подключитесь к кластеру и во вкладке Pods выберите соответствующий под. Подключиться к терминалу можно по кнопке Shell.В открывшемся терминале выполните команду:
shcurl xxx.xxx.xxx.xxx:pppp
где:
xxx.xxx.xxx.xxx
— внутренний IP-адрес балансировщика нагрузки первого кластера из поля IP-адрес на странице "Балансировщики нагрузки" или из поляEXTERNAL-IP
.pppp
- порт, на котором работает созданный ранее балансировщик нагрузки.Результат выполнения команды:
shCLIENT 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-адрес на другой.
Для того, чтобы выполнить изменения в балансировщике, нужно его полностью пересоздать. Для удаления сервиса выполните следующую команду:
kubectl delete -f service-lb.yaml
Для создания LoadBalancer с изменениями воспользуйтесь инструкцией по созданию различных типов LoadBalancer. Подробнее...