Как работает горизонтальное масштабирование (HPA)
Horizontal Pod Autoscaler (HPA) — это механизм автоматического изменения (вверх или вниз) количества реплик подов (в Deployments или StatefulSets) на основе метрик, полученных через Kubernetes API. HPA следит за уровнем нагрузки на приложение, проверяя актуальные метрики (например, CPU, память или дополнительные из Prometheus), и при необходимости изменяет количество реплик для поддержания заданного уровня производительности или экономии ресурсов.
Доступные типы метрик для HPA
Горизонтальное масштабирование в DKP может выполняться по любым доступным метрикам, например:
- По потреблению CPU и памяти подов.
- Настраивается с помощью ресурса HorizontalPodAutoscaler.
Например, можно указать метрику типа Resource сaverageUtilization = 70
для CPU, чтобы при среднем использовании 70% масштабировать приложение вверх.
- Настраивается с помощью ресурса HorizontalPodAutoscaler.
- По метрикам объектов DKP (Ingress, Service) или по метрикам самих подов (сумма или среднее по всем подам одного контроллера).
- Позволяют масштабироваться на основе метрик, привязанных к объектам DKP (например, Ingress, Service), или рассчитанных на под (сумма или среднее по всем подам контроллера). Используются ресурсы ServiceMetric для сервисов и IngressMetric для Ingress.
- По любым другим метрикам, включая внешние данные (метрики Amazon SQS, облачных балансировщиков, SaaS-сервисов и т. п.).
- Используются, когда источник метрик вне кластера (Amazon SQS, облачный Load Balancer, SaaS-сервисы). Настраивается с помощью ресурса CustomPrometheusRules.
Рекомендации HPA
При колебаниях метрик оберните метрику в агрегирующую функцию (например, avg_over_time()
) или увеличьте время стабилизации (spec.behavior.scaleUp.stabilizationWindowSeconds
), чтобы избежать резкого увеличения количества подов.
Ограничения HPA
-
По умолчанию HPA по-разному обрабатывает масштабирование вверх и вниз:
- Масштабирование вверх:
- Происходит незамедлительно (
spec.behavior.scaleUp.stabilizationWindowSeconds = 0
). - Ограничение — за 15 секунд число подов может удвоиться. Если подов было меньше 4, то добавятся 4 новых пода.
- Происходит незамедлительно (
- Масштабирование вниз:
- Происходит в течение 5 минут (
spec.behavior.scaleUp.stabilizationWindowSeconds = 300
). - Собираются «предложения» о новом количестве реплик, и выбирается самое большое, чтобы не было слишком частого уменьшения.
- Нет ограничений на количество убираемых подов.
- Происходит в течение 5 минут (
- Масштабирование вверх:
-
Масштабирование только одного контроллера. Нельзя настроить несколько HPA, нацеленных на один и тот же Deployment (или StatefulSet), иначе они будут конфликтовать.
Как включить или отключить HPA
HPA не требует отдельного включения в DKP. Но, если необходимо маштабирование не только по метрикам по потреблению CPU и памяти подов, то необходимо включить модуль prometheus-metrics-adapter
. Как включить модуль см. в документации.
Настройка HPA
Для настройки HPA необходимо:
-
Определить контроллер (Deployment или StatefulSet), который будет масштабироваться.
-
Указать пределы масштабирования (
minReplicas
иmaxReplicas
):minReplicas: 1 maxReplicas: 10
-
Сконфигурировать метрики:
metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
-
При необходимости, в параметре
stabilizationWindowSeconds
контроллера настроить время, в течение которого масштабирование может быть отменено, чтобы ограничить скорость прироста подов:behavior: scaleUp: stabilizationWindowSeconds: 300 # Позволяет отложить принятие решения о масштабировании вверх и ограничить скорость прироста подов.
Примеры настройки HPA
Масштабирование по CPU и памяти
Масштабирование происходит, если среднее использование CPU/памяти всех подов превышает указанный процент:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
namespace: app-prod
spec:
# Указывается контроллер, который нужно масштабировать (ссылка на deployment или statefulset).
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app
# Границы масштабирования контроллера.
minReplicas: 1
maxReplicas: 10
# Если для приложения характерны кратковременные скачки потребления CPU,
# можно отложить принятие решения о масштабировании, чтобы убедиться, что оно необходимо.
# По умолчанию масштабирование вверх происходит немедленно.
behavior:
scaleUp:
stabilizationWindowSeconds: 300
metrics:
# Масштабирование по CPU и памяти.
- type: Resource
resource:
name: cpu
target:
# Масштабирование, когда среднее использование CPU всех подов в scaleTargetRef превышает заданное значение.
# Для метрики с type: Resource доступен только type: Utilization.
type: Utilization
# Масштабирование, если для всех подов из Deployment запрошено по 1 ядру и в среднем уже используется более 700m.
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
# Пример масштабирования, когда среднее использование памяти всех подов в scaleTargetRef превышает заданное значение.
type: Utilization
# Масштабирование, если для подов запрошено по 1 ГБ памяти и в среднем использовано уже более 800 МБ.
averageUtilization: 80
Масштабирование по метрикам объектов
Если метрика rmq-queue-forum-messages
(количество сообщений в RabbitMQ) превышает 42, HPA увеличивает число реплик Deployment myconsumer:
apiVersion: deckhouse.io/v1beta1
kind: ServiceMetric
metadata:
name: rmq-queue-forum-messages
namespace: mynamespace
spec:
query: sum (rabbitmq_queue_messages{<<.LabelMatchers>>,queue=~"send_forum_message",vhost="/"}) by (<<.GroupBy>>)
---
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2
metadata:
name: myhpa
namespace: mynamespace
spec:
# Указывается контроллер, который нужно масштабировать (ссылка на deployment или statefulset).
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myconsumer
minReplicas: 1
maxReplicas: 5
metrics:
- type: Object
object:
describedObject:
apiVersion: v1
kind: Service
name: rmq
metric:
name: rmq-queue-forum-messages
target:
type: Value
value: 42
Масштабирование на основе внешних данных
Используется метрика mymetric
, получаемая из внешнего источника (например, SQS). Масштабирование происходит, если значение превышает 100:
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2
metadata:
name: myhpa
namespace: mynamespace
spec:
# Указывается контроллер, который нужно масштабировать (ссылка на deployment или statefulset).
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 2
metrics:
# Используем внешние метрики для масштабирования.
- type: External
external:
metric:
# Метрика, которую мы зарегистрировали с помощью создания метрики в Prometheus kube_adapter_metric_mymetric, но без префикса 'kube_adapter_metric_'.
name: mymetric
selector:
# Для внешних метрик можно и нужно уточнять запрос с помощью лейблов.
matchLabels:
namespace: mynamespace
ingress: myingress
target:
# Для метрик типа External можно использовать только `type: Value`.
type: Value
# Масштабирование, если значение нашей метрики больше 10.
value: 10