HorizontalPodAutoscaler
Как HPA считает нужное число реплик, почему без resources.requests он молчит и что делает блок behavior.
Что такое HPA
HorizontalPodAutoscaler (HPA) - контроллер, который автоматически меняет число реплик Deployment по нагрузке. Deployment - объект, который держит нужное число одинаковых Pod. Pod - наименьшая единица запуска, внутри неё работает контейнер. Реплика - один из одинаковых Pod в наборе.
Цель HPA - держать среднее потребление ресурсов рядом с заданным процентом. Если каждая реплика ест 90% CPU при target 50%, HPA добавит реплики. Если потребление упало до 10%, убавит.
HPA живёт внутри kube-controller-manager. Раз в 15 секунд он
опрашивает metrics-server, считает текущее потребление и сравнивает
с целью. metrics-server - компонент, который собирает текущие
метрики ресурсов. После расчёта HPA меняет spec.replicas у
целевого Deployment, дальше работает обычный механизм выкатки.
Если metrics-server отвалился, HPA замирает на текущем числе реплик: метрики не приходят, считать не из чего.
HPA меняет только число реплик одного приложения (workload). Менять requests у существующих Pod умеет VerticalPodAutoscaler. Добавлять и убирать ноды умеет Cluster Autoscaler. HPA - самый частый из трёх.
Минимальный YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: cpu-burner
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: cpu-burner
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Та же настройка одной командой:
kubectl autoscale deploy cpu-burner --min=1 --max=5 --cpu-percent=50
Разбор полей
scaleTargetRef: объект, которым управляет HPA. Чаще Deployment,
бывает StatefulSet. Указывают именно контроллер, не Pod.
minReplicas и maxReplicas: нижняя и верхняя границы числа
реплик. Без maxReplicas HPA может раскатать слишком много Pod и
положить кластер.
metrics: список метрик для решения. Метрик может быть несколько,
HPA берёт максимум числа реплик по каждой.
target.type: Utilization задаёт цель в процентах от requests.
requests: объём ресурсов, который Pod запрашивает при старте.
Тип AverageValue задаёт цель в абсолютных значениях, например
200m CPU на Pod.
Формула решения
desiredReplicas = ceil(currentReplicas * currentMetricValue / targetMetricValue)
Один Pod ест 100% от requests, цель 50%. Получается ceil(1 * 100 / 50) = 2. HPA ставит 2 реплики. Если оба Pod дальше едят 100%, на
следующем тике выйдет ceil(2 * 100 / 50) = 4. Потом HPA упрётся в
maxReplicas и остановится.
Пересчёт идёт не строго каждые 15 секунд. У алгоритма есть окно стабилизации: HPA сглаживает колебания, чтобы не реагировать на кратковременные пики. От появления нагрузки до нового числа реплик обычно проходит около минуты.
behavior: разная скорость вверх и вниз
В autoscaling/v2 есть блок behavior:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
По умолчанию вверх HPA скейлит быстро, а вниз медленно. После спада нагрузки он ждёт около 5 минут и только потом убавляет реплики. Это защита от лишних движений при коротких провалах нагрузки. Лучше подержать лишний Pod, чем дёргать пользователей пересборкой.
requests обязательны
Без resources.requests HPA не работает. В колонке Targets будет
стоять <unknown>/50%, и автоскейл просто молчит. Причина в том,
что averageUtilization - это процент от requests, и без них делить
не на что.
Связанные команды
kubectl autoscale deploy <name> --min=1 --max=5 --cpu-percent=50
kubectl get hpa
kubectl describe hpa <name> # events с причинами решений
kubectl get hpa -A # все HPA в кластере
kubectl explain hpa.spec.behavior
Что часто ломается
- Нет
requests. В Targets стоит<unknown>/50%, HPA бездействует. - Слишком высокий
maxReplicasпри утечке памяти в приложении. HPA добивает до maxReplicas, и кластер встаёт. Разумный max обязателен. - HPA конфликтует с ручным
kubectl scale. При активном HPA ручное число реплик переживёт только до следующей синхронизации HPA, не дольше 15 секунд.
Домашка
Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-hpa # развернуть стартовое состояние
./run.sh verify k8s-hpa # проверить текущий шаг
Коротко
- HPA правит
spec.replicasу Deployment, опираясь на метрики от metrics-server. - Формула:
ceil(текущие реплики * текущее значение / целевое). - Без
resources.requestsцель в процентах посчитать не из чего, HPA показывает<unknown>. - Вверх скейлит быстро, вниз ждёт окно стабилизации около 5 минут.
behaviorвautoscaling/v2позволяет задать свои скорости и окна.- Ручной
kubectl scaleпри живом HPA держится до следующего тика.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс