Для обеспечения устойчивой работы приложений и равномерного распределения трафика между подами в Kubernetes используется балансировщик нагрузки. Он помогает избежать перегрузки отдельных подов, поддерживая высокую доступность и стабильность сервисов.
Базовая конфигурация балансировщика нагрузки
Для создания балансировщика нагрузки в Kubernetes создадим ресурс типа Service с типом LoadBalancer. Пример базового манифеста:
apiVersion: v1
kind: Service
metadata:
name: example-balancer
namespace: kubernetes-dashboard
spec:
selector:
app.kubernetes.io/name: nginx
ports:
- port: 80 # Внешний порт для доступа к приложению
targetPort: 80 # Порт пода, на который перенаправляется трафик
appProtocol: k8s.timeweb.cloud/proto-http
type: LoadBalancer
В этом примере балансировщик будет перенаправлять трафик с порта 80 на порт 80 внутри подов, соответствующих селектору app.kubernetes.io/name: nginx
.
Если вам нужно добавить несколько правил для балансировки, обязательно указывайте атрибут name
для каждого порта:
apiVersion: v1
kind: Service
metadata:
name: example-balancer
namespace: kubernetes-dashboard
spec:
selector:
app.kubernetes.io/name: nginx
ports:
- port: 80
targetPort: 80
appProtocol: k8s.timeweb.cloud/proto-http
name: http
- port: 443
targetPort: 443
appProtocol: k8s.timeweb.cloud/proto-https
name: https
type: LoadBalancer
Значение атрибута name
может быть произвольным.
Для каждого порта можно указать протокол трафика с помощью атрибута appProtocol
. Это позволяет явно задать, как будет обрабатываться трафик на стороне балансировщика. По умолчанию используется значение proto-tcp
.
Поддерживаются следующие значения:
k8s.timeweb.cloud/proto-http
— обычный HTTP-трафик.k8s.timeweb.cloud/proto-https
— HTTPS-трафик.k8s.timeweb.cloud/proto-tcp
— TCP-трафик.k8s.timeweb.cloud/proto-tcp-ssl
— TCP-трафик с поддержкой TLS.k8s.timeweb.cloud/proto-http2
- HTTP/2-трафик.
После создания балансировщик будет отображаться в панели управления в разделе «Балансировщики» с лейблом «K8S».
Обратите внимание, что балансировщик, созданный силами Kubernetes, нельзя изменить в панели управления или через API — только через kubectl
.
Дополнительные параметры для настройки балансировщика
Для более гибкой настройки балансировщика нагрузки в Kubernetes можно использовать дополнительные параметры. Они указываются в виде меток (labels
) в манифесте Service
.
Пример манифеста с дополнительными параметрами:
apiVersion: v1
kind: Service
metadata:
name: example-balancer
namespace: kubernetes-dashboard
labels:
k8s.timeweb.cloud/attached-loadbalancer-algo: "leastconn"
k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip: "true"
spec:
selector:
app.kubernetes.io/name: nginx
ports:
- port: 80
appProtocol: k8s.timeweb.cloud/proto-http
targetPort: 80
type: LoadBalancer
В этом примере задаются два дополнительных параметра:
k8s.timeweb.cloud/attached-loadbalancer-algo
: алгоритм балансировки —leastconn
(выбирает сервер с наименьшим числом активных подключений).k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip
: выделяет балансировщику внешний IP с защитой от DDoS.
Доступные параметры для балансировщика нагрузки
В таблице ниже перечислены доступные параметры для настройки балансировщика нагрузки. Каждый параметр задается в виде метки в манифесте Service:
Параметр |
Назначение |
|
Задает конфигурацию балансировщика. По умолчанию выбирается минимальная конфигурация для зоны. Получить id тарифов можно при помощи API. |
|
Алгоритм балансировки: |
|
Интервал между проверками доступности (в секундах). |
|
Таймаут проверки доступности (в секундах). |
|
Количество неудачных проверок перед отключением апстрима. |
|
Количество успешных проверок для восстановления апстрима. |
|
Отключение внешнего публичного IP для балансировщика. |
|
Выделение внешнего IP с защитой от DDoS. |
|
Исключает сервис из обработки балансировщиком Timeweb Cloud. Может быть полезно, если используется другой |
|
Включает прокси-режим для балансировщика. |
|
Время ожидания установления TCP-подключения с апстримом (в миллисекундах). |
|
Время ожидания новых TCP-сегментов от клиента (в миллисекундах). |
|
Таймаут ожидания ответа от бэкенда (в миллисекундах). |
|
Таймаут выполнения HTTP-запроса (в миллисекундах). |
|
Максимальное количество соединений, которое может обрабатывать балансировщик на фронтенде. |
|
Включение автоматического выпуска SSL-сертификата. Если указано |
|
Домен, на который необходимо выпустить SSL-сертификат. |
Практический пример использования балансировщика
Для демонстрации работы балансировщика создадим два деплоймента Nginx, каждый из которых будет отображать свою HTML-страницу. Балансировщик случайным образом распределит запросы между подами, и в зависимости от этого будет показана одна из страниц.
Подготовка окружения
Для удобства управления и быстрого удаления всех ресурсов, связанных с балансировщиком, создадим отдельный неймспейс. Это упростит тестирование и последующее удаление ресурсов, сохраняя основной кластер чистым.
Выполните команду для создания неймспейса:
kubectl create namespace test-namespace
После создания используем этот неймспейс для всех дальнейших ресурсов, включая балансировщик, деплойменты и ConfigMap
. Для этого добавьте namespace: test-namespace
в каждый манифест, связанный с примером.
Создание ConfigMap для HTML-страниц
Начнем с создания ConfigMap
, в котором будут храниться две HTML-страницы. Под 1 будет отображать страницу с заголовком «Pod 1», а Под 2 — с заголовком «Pod 2». Эти страницы подключаются к Nginx в подах.
Файл nginx-pages-configmap.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-pages
namespace: test-namespace
data:
index-page1.html: |
<html>
<body>
<h1>Pod 1</h1>
<p>This is page served by Pod 1.</p>
</body>
</html>
index-page2.html: |
<html>
<body>
<h1>Pod 2</h1>
<p>This is page served by Pod 2.</p>
</body>
</html>
Здесь мы создаем ConfigMap
с двумя HTML-файлами: index-page1.html
и index-page2.html
. Они будут монтироваться в подах Nginx, позволяя каждому поду отображать свою страницу.
Примените ConfigMap
:
kubectl apply -f nginx-pages-configmap.yaml
Создание деплойментов Nginx
Теперь создадим два деплоймента, каждый из которых будет использовать разные HTML-страницы из ConfigMap
. Деплойменты используют селектор app: nginx
— это метка, которую балансировщик будет использовать для выбора подов, участвующих в распределении нагрузки.
Файл nginx-deployment-pod1.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pod1
namespace: test-namespace
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: nginx-pages
mountPath: /usr/share/nginx/html/index.html
subPath: index-page1.html
ports:
- containerPort: 80
volumes:
- name: nginx-pages
configMap:
name: nginx-pages
Этот деплоймент создает один под (реплика 1) с образом Nginx, который монтирует страницу index-page1.html
из ConfigMap
в директорию /usr/share/nginx/html/index.html
. Порт 80 открыт для доступа к странице.
Примените деплоймент:
kubectl apply -f nginx-deployment-pod1.yaml
Файл nginx-deployment-pod2.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pod2
namespace: test-namespace
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: nginx-pages
mountPath: /usr/share/nginx/html/index.html
subPath: index-page2.html
ports:
- containerPort: 80
volumes:
- name: nginx-pages
configMap:
name: nginx-pages
Этот деплоймент также создает под Nginx, но монтирует страницу index-page2.html
, отличающуюся содержимым.
Примените второй деплоймент:
kubectl apply -f nginx-deployment-pod2.yaml
Настройка балансировщика нагрузки
Теперь создадим балансировщик, который будет направлять запросы на поды с меткой app: nginx
.
Файл nginx-loadbalancer.yaml
:
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
namespace: test-namespace
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
appProtocol: k8s.timeweb.cloud/proto-http
type: LoadBalancer
В этом Service
указываем type: LoadBalancer
, что создает балансировщик нагрузки, и selector: app: nginx
, который направляет запросы на поды Nginx из наших деплойментов. Запросы, поступающие на балансировщик, распределяются между подами при помощи алгоритма roundrobin
, так как этот алгоритм выбирается по умолчанию.
Примените балансировщик:
kubectl apply -f nginx-loadbalancer.yaml
Проверка работы балансировщика
После создания балансировщика его внешний IP-адрес можно увидеть в панели управления или выполнив команду:
kubectl get services -n test-namespace
При доступе по этому IP вы увидите страницу, отображаемую одним из подов. Каждый раз при обновлении страницы трафик может перенаправляться на разные поды, что позволяет балансировщику нагрузки случайным образом переключать отображаемую страницу.
Удаление ресурсов после проверки
После того как вы проверили работу балансировщика, вы можете удалить все созданные поды и ресурсы. Для этого выполните следующие команды:
kubectl delete service nginx-loadbalancer -n test-namespace
kubectl delete deployment nginx-pod1 -n test-namespace
kubectl delete deployment nginx-pod2 -n test-namespace
kubectl delete configmap nginx-pages -n test-namespace
Эти команды удалят балансировщик, деплойменты подов и ConfigMap
, созданные ранее.
Либо удалите неймспейс полностью, выполнив:
kubectl delete namespace test-namespace
Этот способ автоматически удалит все ресурсы, связанные с тестовым окружением.
Отличное руководство
Здравствуйте, а что на счёт аннотаций для включения proxy-protocol?