Три уровня:
HPA (Horizontal Pod Autoscaler) меняет число реплик у Deployment или StatefulSet. VPA подбирает requests и limits самого пода. Cluster Autoscaler добавляет и убирает ноды, когда подам некуда вставать. Задачи разные: HPA вы будете трогать постоянно, два других скорее настроить и поглядывать.
HPA по CPU:
Метрики CPU и памяти отдает metrics-server. В managed-кластерах (Yandex Cloud, VK Cloud, Selectel) он обычно уже есть, в minikube включается аддоном:
Код: Выделить всё
minikube addons enable metrics-server
kubectl top podsКод: Выделить всё
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orders-api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orders-api
minReplicas: 2
maxReplicas: 12
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60Блок behavior управляет скоростью. Вверх HPA по умолчанию идет быстро, вниз ждет 5 минут стабильно низкой нагрузки (stabilizationWindowSeconds: 300). Здесь мы вдобавок ограничили спуск одной репликой в минуту, сервисам с долгим прогревом это спасает от качелей.
Проверка:
Код: Выделить всё
kubectl get hpa orders-api
kubectl describe hpa orders-apiНе только CPU:
По памяти масштабировать технически можно, но JVM и многие рантаймы память после пика не отдают, и HPA раздует реплики навсегда. Куда полезнее прикладные метрики: длина очереди, лаг консьюмера Kafka, RPS. Штатный путь, custom и external metrics через адаптеры вроде prometheus-adapter, но в 2026 проще взять KEDA: он сам создает HPA под капотом, знает десятки источников и умеет масштабировать в ноль, чего голому HPA не дано (minReplicas ниже 1 без альфа-фичи не бывает).
VPA коротко:
Vertical Pod Autoscaler ставится отдельно (проект kubernetes/autoscaler) и считает рекомендации по фактическому потреблению. Самый полезный режим, Off: ничего не трогает, рекомендации видны в kubectl describe vpa, а манифесты вы правите руками.
Код: Выделить всё
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: orders-api
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: orders-api
updatePolicy:
updateMode: "Off"Cluster Autoscaler:
HPA попросил 12 реплик, ноды кончились, поды повисли в Pending. Cluster Autoscaler видит их, прикидывает по requests, влезут ли они в ноду из настроенной группы, и заказывает ее у облака. В managed Kubernetes включается галочкой на группе нод. Два свойства, которые ломают ожидания: CA смотрит только на Pending поды и их requests, фактическая загрузка нод ему безразлична; и новая нода поднимается одну-три минуты, так что на резких пиках выручает запас через minReplicas или overprovisioning (под-пустышка с отрицательным priorityClass, который вытесняется и освобождает место). Вниз тоже автоматически: ноду, загруженную меньше чем наполовину, CA попробует разгрузить и удалить, уважая PodDisruptionBudget. В AWS и Azure набирает обороты Karpenter, заказывающий ноды нужного размера без заранее нарезанных групп; в облаках СНГ пока классический CA.
Типичные грабли:
spec.replicas в Git поверх HPA: каждый apply сбрасывает реплики на цифру из файла, и на пике сервис схлопывается. Поле надо убрать из манифеста (в Argo CD есть ignoreDifferences, но удалить честнее). maxReplicas от балды: каждая реплика тащит свои коннекты к PostgreSQL, и на сорока подах база умрет раньше, чем кончится CPU, считайте емкость зависимостей. И агрессивная цель вроде 50 процентов на рваном трафике без блока behavior: получите качели, где реплики прыгают каждые две минуты.
Итог:
HPA двигает реплики по метрикам и требует честных requests. VPA в режиме Off подсказывает, какими этим requests быть. Cluster Autoscaler подвозит ноды под Pending поды. Каскад простой: метрика выросла, HPA добавил поды, места не хватило, CA добавил ноды. Тюнить это вслепую невозможно, поэтому в следующей главе займемся наблюдаемостью: логи, events и метрики в Prometheus с Grafana.