Зачем это нужно: реальная ситуация
У вас есть веб-приложение — API на Java, которое отдаёт JSON. Оно крутится в Kubernetes в виде Deployment с 2 репликами.
Понедельник, 3 часа ночи. Нагрузка — 10 запросов в секунду. Каждый Pod ест 5% CPU. Всё спокойно.
Понедельник, 10 утра. Все сотрудники зашли в систему, начали работать. Нагрузка — 300 запросов в секунду. Каждый Pod ест 180% CPU (да, больше 100% — потому что CPU-лимит позволяет использовать несколько ядер). Запросы копятся, latency растёт с 50 мс до 3 секунд. Пользователи жалуются.
Что делать?
Вариант А — вручную: заходите, меняете replicas: 2 на replicas: 10, ждёте. В 11 утра нагрузка спала — забыли вернуть обратно, платите за 10 Pod'ов круглосуточно.
Вариант Б — HPA: вы один раз описываете правило «держи CPU в среднем на 50%», и Kubernetes сам:
- в 10 утра добавляет Pod'ы до 10;
- к обеду, когда нагрузка спала, убирает лишние обратно до 2.
Это и есть горизонтальное автомасштабирование.
Что значит «Horizontal»?
Есть два способа справиться с нагрузкой на Pod:
| Способ | Что делаем | В Kubernetes |
|---|---|---|
| Вертикальный (Vertical) | Даём Pod'у больше CPU/RAM | VPA |
| Горизонтальный (Horizontal) | Добавляем копии Pod'ов | HPA |
HPA — это про количество копий, а не про их «мощность».
Нагрузка низкая: [Pod]
Нагрузка высокая: [Pod][Pod][Pod][Pod] ← это делает HPA
Как это работает (простыми словами)
HPA — это контроллер внутри кластера, который просыпается каждые 15 секунд и делает одно и то же:
1. Спросить метрику → "средний CPU по Pod'ам = 80%"
2. Сравнить с целью → "я хотел 50%"
3. Посчитать реплики → "80 / 50 = 1.6, надо больше"
4. Обновить Deployment → replicas: 2 → 4
5. Поспать 15 сек → и снова с шага 1
Формула, которую HPA использует внутри:
желаемые реплики = текущие реплики × (текущая метрика / целевая метрика)
Пример: 2 Pod'а, средний CPU = 80%, цель = 50%.
2 × (80 / 50) = 3.2 → округляем вверх → 4 Pod'а
Обратный пример: 4 Pod'а, средний CPU = 20%, цель = 50%.
4 × (20 / 50) = 1.6 → округляем вверх → 2 Pod'а (упёрлись в minReplicas)
По каким метрикам можно масштабировать?
От простого к сложному:
- CPU — самый частый вариант. «Держи средний CPU на 50%».
- Память — реже, потому что память плохо освобождается. Приложение может держать её даже под низкой нагрузкой, и HPA будет «залипать» на высоком значении.
- Кастомные метрики Pod'ов — например, количество запросов в секунду (RPS) через Prometheus.
- Внешние метрики — длина очереди в Kafka, число сообщений в RabbitMQ, метрики из облака.
Самое простое — начните с CPU. Это работает «из коробки» и покрывает 80% случаев.
Первый HPA: пошагово
Шаг 0. Что нужно
- Работающий кластер Kubernetes.
- Установленный metrics-server — компонент, который собирает CPU/RAM по Pod'ам.
Проверить:
kubectl top pods
Если видите таблицу с CPU и MEMORY — всё ок. Если ошибка Metrics API not available — HPA работать не будет, сначала ставьте metrics-server.
Шаг 1. Deployment с указанными requests
Критически важно: HPA считает проценты от requests, а не от лимитов и не от реального железа. Если requests не заданы — HPA покажет <unknown> и ничего не сделает.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0
resources:
requests:
cpu: "100m" # ← вот это обязательно
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
Здесь 100m = 0.1 ядра. То есть «этому приложению для нормальной работы нужно минимум 0.1 ядра».
Шаг 2. Сам HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app # ← кого масштабируем
minReplicas: 2 # ← никогда меньше 2
maxReplicas: 10 # ← никогда больше 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # ← цель: средний CPU = 50% от requests
Применить:
kubectl apply -f deployment.yaml
kubectl apply -f hpa.yaml
Шаг 3. Проверить
kubectl get hpa
Вывод:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
my-app-hpa Deployment/my-app 12%/50% 2 10 2 30s
Читается так: «сейчас средний CPU = 12%, цель = 50%, поэтому держим минимум — 2 Pod'а».
Нагрузите приложение — и увидите, как REPLICAS начнёт расти.
Полезная команда для наблюдения в реальном времени:
kubectl get hpa -w
Флаг -w (watch) обновляет вывод при каждом изменении.
Три главные ошибки
1. Не заданы resources.requests
HPA не может посчитать проценты и молча ничего не делает. Всегда проверяйте kubectl describe hpa — там будет строка AbleToScale: False с причиной.
2. Нет metrics-server
kubectl top pods не работает → HPA не работает. Это первое, что нужно проверить при отладке.
3. Слишком агрессивные настройки
minReplicas: 1 + averageUtilization: 10% → приложение будет постоянно скакать вверх-вниз (это называется flapping). Начните с разумных значений: minReplicas: 2, цель 50–70%.
Что запомнить
- HPA = автомат, который добавляет/убирает копии Pod'ов.
- Работает по метрикам: обычно CPU.
- Требует
resources.requestsи metrics-server. - Формула простая: текущие × (факт / цель), округление вверх.
- Начинайте с CPU, цели 50–70%,
minReplicas: 2. - Не путайте с:
- VPA — меняет размер одного Pod'а;
- Cluster Autoscaler — меняет количество узлов в кластере;
- KEDA — масштабирует по событиям из очередей и cron.
Top comments (0)