Автомасштабирование в Kubernetes позволяет гибко управлять ресурсами кластера, автоматически добавляя или удаляя ноды и поды в зависимости от нагрузки.
Опция доступна только для кластеров, созданных после 8 ноября 2024 года. Для кластеров, созданных ранее, данная возможность недоступна, даже при настройке через панель управления.
Включение автомасштабирования при создании кластера
Для включения автомасштабирования на этапе создания кластера, необходимо выбрать опцию «Автомасштабирование» в разделе «Конфигурация воркер-нод».

Минимальное количество нод на этапе создания кластера — 1.
Включение автомасштабирования для существующего кластера
Если кластер уже создан, включить автомасштабирование можно следующим образом:
-
Перейдите на вкладку «Ресурсы».
-
Выберите «Редактировать группу».

В появившемся меню включите опцию автомасштабирования для группы.

Минимальное количество нод — 0.
Принцип работы автомасштабирования
Для управления созданием и удалением нод используются следующие параметры:
--scale-down-unneeded-time 5m0s
--max-scale-down-parallelism 1
--provisioning-request-max-backoff-time 2m0s
--max-inactivity 3m0s
--scale-down-delay-after-add 2m0s
--max-node-provision-time 10m0s
--scan-interval 2m0s
--scale-up-from-zero=true
--scale-down-unready-enabled=true
--scale-down-unready-time=30m0s
|
Параметр |
Описание |
|
|
Время, в течение которого нода должна простаивать перед удалением (5 минут). |
|
|
Максимальное количество нод, которые могут быть удалены одновременно (1). |
|
|
Максимальное время ожидания между повторными попытками создания ноды (2 минуты). |
|
|
Максимальное время бездействия кластера перед началом уменьшения количества нод (3 минуты). |
|
|
Минимальное время ожидания после добавления ноды перед возможным уменьшением (2 минуты). |
|
|
Максимальное время, отводимое на создание новой ноды (10 минут). |
|
|
Интервал проверки состояния кластера и необходимости масштабирования (2 минуты). |
|
|
Разрешает масштабирование группы нод с нулевого количества. |
|
|
Разрешает удаление нод, находящихся в состоянии |
|
|
Время, после которого нода в состоянии |
Эти параметры определяют, как быстро добавляются или удаляются ноды в зависимости от текущей нагрузки. Например, если нагрузка снижается и нода простаивает более 5 минут, она может быть удалена. При этом удаление выполняется постепенно, не более одной ноды одновременно, чтобы избежать резкого сокращения ресурсов.
При увеличении нагрузки автоскейлер анализирует состояние кластера с интервалом 2 минуты и может инициировать создание новых нод. На создание ноды отводится до 10 минут, а повторные попытки при ошибках выполняются с увеличивающимся интервалом, но не более 2 минут. Такой подход позволяет поддерживать баланс между доступностью ресурсов и их экономичным использованием.
Требования к кластеру
Максимальное количество нод в группе не может превышать максимально допустимое количество воркер-нод в кластере. Например, если для всего кластера установлено ограничение в 100 нод, а одна из групп уже использует 30 нод, для новой группы можно установить максимум 70 нод.
Настройка ресурсов для подов
Автомасштабирование работает только в том случае, если в деплойменте указаны ресурсы requests и limits. Ниже приведен пример файла деплоймента:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example-container
image: example-image
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "400m"
memory: "512Mi"
Лимиты CPU измеряются в миллиядрах (m), где 1000m равняется одному ядру. Лимиты памяти измеряются в мебибайтах (Mi) или гибибайтах (Gi).
Использование nodeSelector и nodeAffinity
Если в манифесте пода используется nodeSelector или nodeAffinity, Kubernetes размещает под только на тех нодах, которые соответствуют указанным условиям. Это влияет и на автомасштабирование: автоскейлер сможет создать новую ноду только в той группе, где такой под может быть запущен.
Если подходящей группы нод нет, под останется в состоянии Pending, даже если автомасштабирование в кластере включено.
Пример с nodeSelector
nodeSelector подходит для простых случаев, когда нужно запускать поды только на нодах с определенным лейблом. Например, если приложение должно работать только в определенной группе нод, можно использовать такой манифест:
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker-deployment
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
spec:
nodeSelector:
workload-type: background
containers:
- name: worker
image: busybox
command: ["sh", "-c", "sleep infinity"]
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
В этом примере под может быть запущен только на нодах с лейблом workload-type=background. Если в кластере нет подходящих нод, автоскейлер сможет добавить новую ноду только в ту группу, где используется такой лейбл.
Пример с nodeAffinity
nodeAffinity используется, когда требуется более гибко задать условия размещения подов. В отличие от nodeSelector, он позволяет использовать выражения с различными операторами и комбинировать несколько условий.
Ниже приведен пример, эквивалентный предыдущему nodeSelector, но реализованный через nodeAffinity:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: workload-type
operator: In
values:
- api
containers:
- name: api
image: nginx:latest
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "400m"
memory: "512Mi"
В этом случае под будет размещаться только на нодах с лейблом workload-type=api. В этом примере используется оператор In, который позволяет указать одно или несколько допустимых значений для лейбла.
nodeAffinity поддерживает и другие операторы, например:
-
In— значение лейбла должно входить в указанный список; -
NotIn— значение лейбла не должно входить в указанный список; -
Exists— достаточно наличия лейбла на ноде; -
DoesNotExist— лейбл должен отсутствовать; -
Gt— значение лейбла должно быть больше указанного (используется для числовых значений); -
Lt— значение лейбла должно быть меньше указанного (используется для числовых значений).
Операторы позволяют задавать более сложные правила размещения подов, чем при использовании nodeSelector.
Используйте nodeSelector, если достаточно простой привязки по одному или нескольким фиксированным значениям. Если нужны более сложные условия размещения, применяйте nodeAffinity.
Настройка Horizontal Pod Autoscaler (HPA)
Horizontal Pod Autoscaler (HPA) используется для динамического изменения количества подов в зависимости от потребления ресурсов, таких как процессор или память. HPA масштабирует поды, чтобы поддерживать заданный уровень использования ресурсов и адаптироваться к изменяющимся условиям нагрузки. Ниже приведен пример манифеста HPA:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: example-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: example-deployment
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 50
Подробное описание параметров HPA
-
apiVersion: Определяет версию API, используемую для создания ресурса. В данном случае этоautoscaling/v1. -
kind: Тип создаваемого ресурса, здесь —HorizontalPodAutoscaler. -
metadata: Содержит информацию о метаданных, включая имя HPA (example-hpa). -
scaleTargetRef: Указывает объект, который нужно масштабировать. Здесь задаются: -
apiVersion: Версия API ресурса, который будет масштабироваться. -
kind: Тип ресурса, который масштабируется, в данном случае —Deployment. -
name: Имя ресурса, который необходимо масштабировать (example-deployment). -
minReplicas: Минимальное количество реплик подов, которые должны поддерживаться, в данном случае — 1. -
maxReplicas: Максимальное количество реплик подов, до которого можно масштабироваться, здесь — 5. -
targetCPUUtilizationPercentage: Процент загрузки процессора, при котором будет изменяться количество реплик. В этом примере установлено значение 50, что означает, что количество реплик будет изменяться для поддержания среднего использования CPU на уровне 50%.
Практический пример использования автомасштабирования
Для практического примера создадим деплоймент Nginx, который будет служить базой для настройки автомасштабирования:
Файл deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
Этот деплоймент создает под Nginx с установленными ограничениями на использование ресурсов, что необходимо для корректной работы HPA.
Настройка горизонтального автомасштабирования подов на примере Nginx
Для демонстрации автомасштабирования подов на примере Nginx необходимо использовать объект HorizontalPodAutoscaler (HPA). HPA автоматически регулирует количество реплик подов в зависимости от потребления ресурсов. Пример файла HPA:
Файл hpa.yaml:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 1
maxReplicas: 4
targetCPUUtilizationPercentage: 20
В данном примере HPA регулирует количество реплик пода nginx-deployment в зависимости от загрузки процессора, поддерживая ее на уровне 20%.
Настройка балансировщика нагрузки
Для правильного распределения нагрузки между подами рекомендуется использовать объект Service с типом LoadBalancer. Пример файла конфигурации сервиса:
Файл service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Этот сервис обеспечивает доступ к подам, используя балансировку нагрузки по нескольким портам.
Применение настроек
Для применения YAML-файлов необходимо использовать команды:
kubectl apply -f nginx-deployment.yaml kubectl apply -f nginx-hpa.yaml kubectl apply -f nginx-service.yaml
Эти команды применят конфигурации деплоймента, HPA и балансировщика, создавая все необходимые компоненты для работы автомасштабирования.
Демонстрация увеличения количества нод под нагрузкой
Перед тем как приступить к генерации нагрузки, убедитесь, что все ресурсы успешно созданы и находятся в состоянии Running. Чтобы увидеть, как работает автомасштабирование, можно сгенерировать нагрузку на наш сервис. Для этого воспользуемся утилитой hey, которая отправляет HTTP-запросы для тестирования производительности:
Генерируем нагрузку:
hey -z 10m -c 20 http://ip_балансировщика
Этот запрос будет генерировать нагрузку в течение 10 минут с 20 параллельными подключениями к сервису Nginx, что приведет к увеличению использования ресурсов и, как следствие, к масштабированию количества реплик деплоймента и, при необходимости, количества воркер-нод. Спустя некоторое время после запуска утилиты, вы можете увидеть, что количество нод увеличилось. Увидеть это можно в панели управления или выполнив команду:
kubectl get nodes
Также количество подов увеличилось до 4, как описано в hpa.yaml:
kubectl get pods