Що таке HorizontalPodAutoscaler (HPA)?
HPA — як менеджер в ресторані:
Junior рівень
Просте пояснення
HorizontalPodAutoscaler (HPA) — це автоматичний контроллер Kubernetes, який змінює кількість Pod’ів залежно від навантаження. Багато запитів → більше Pod’ів. Мало запитів → менше Pod’ів.
Проста аналогія
HPA — як менеджер в ресторані:
- Багато клієнтів → відкриває додаткові каси
- Клієнтів мало → закриває зайві каси, економить ресурси
Як працює HPA?
- HPA перевіряє завантаження CPU Pod’ів кожні 15 секунд
- Якщо CPU вище цільового значення → додає Pod’и
- Якщо CPU нижче → видаляє Pod’и
- Число Pod’ів залишається в межах min/max
Простий приклад
# Автоматично підтримувати CPU ~50%, від 2 до 10 Pod'ів
kubectl autoscale deployment myapp --cpu-percent=50 --min=2 --max=10
Або через YAML:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Що потрібно для роботи HPA?
- Metrics Server — збирає метрики CPU/Memory
- Requests в Pod’і — HPA рахує відсоток від Request, не від Limit
resources:
requests:
cpu: "500m" # Обов'язково!
Що запам’ятати Junior-розробнику
- HPA автоматично змінює число Pod’ів
- Працює по CPU (або іншим метрикам)
- Вимагає Metrics Server та Resources Requests
- Задавайте min/max репліки для контролю
- HPA не масштабує нижче minReplicas
Middle рівень
Формула HPA
desiredReplicas = ceil[currentReplicas × (currentMetricValue / desiredMetricValue)]
// desiredReplicas = ceil(currentReplicas * (currentMetric / desiredMetric)) // Приклад: ceil(2 * (300m / 200m)) = ceil(2 * 1.5) = ceil(3.0) = 3 Pod’а
Приклад:
- Бажана CPU: 50%
- Поточна CPU: 100%
- Поточні репліки: 2
- Результат: ceil[2 × (100/50)] = 4 репліки
Джерела метрик
| Тип | Звідки | Приклад |
|---|---|---|
| Resource | Metrics Server | CPU, Memory |
| Pods | Prometheus Adapter | RPS, latency |
| Object | Prometheus Adapter | Requests per queue |
| External | Зовнішні системи | AWS SQS queue length |
Memory-based scaling: чому це погана ідея
Java-додатки не завжди повертають пам’ять ОС одразу після GC. Це призводить до:
- HPA бачить високе memory usage
- Додає Pod’и нескінченно
- Ресурси витрачаються марно
Рекомендація: Масштабуйте по CPU або бізнес-метрикам, не по пам’яті.
Behavior: налаштування швидкості масштабування
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120
Scale Down повільніший за Scale Up — це захищає від передчасного видалення Pod’ів.
Конфлікт HPA і VPA
Не використовуйте HPA і VPA одночасно для CPU:
- HPA додає Pod’и при високому CPU
- VPA збільшує CPU на Pod
- Вони “борються” → нестабільність
Що запам’ятати Middle-розробнику
- HPA формула: бажані репліки = поточні × (поточна метрика / бажана)
- Масштабування по пам’яті — антипатерн для Java
- Behavior контролює швидкість scale up/down
- Не використовуйте HPA + VPA для однієї метрики
- maxReplicas захищає бюджет від несподіваних сплесків
Senior рівень
HPA як система управління ємністю
HPA — це не просто “авто скейлінг”, а інструмент балансування між SLA та cost optimization.
Алгоритм HPA v2: детальний аналіз
Цикл прийняття рішень:
Every 15 seconds (syncPeriod):
1. Fetch metrics for all targeted pods
2. Calculate desired replicas per metric
3. Take MAX across all metrics
4. Apply behavior policies (scale up/down limits)
5. Enforce min/max bounds
6. Patch Deployment spec.replicas
Stabilization Window:
- При Scale Up: 60s за замовчуванням (швидка реакція)
- При Scale Down: 300s за замовчуванням (консервативний)
stabilization window — період «остивання» після масштабування. Запобігає flapping (швидкому масштабуванню вгору-вниз при коливаннях навантаження).
Це запобігає “thrashing” — постійному додаванню/видаленню Pod’ів.
Multi-metric HPA
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
HPA обирає MAX з розрахунків по кожній метриці.
Prometheus Adapter для Custom Metrics
# Prometheus rule
- record: http_requests_per_second
expr: rate(http_requests_total[5m])
# Prometheus Adapter config
rules:
- seriesQuery: 'http_requests_per_second{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)"
as: "${1}"
metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)
HPA та Java-додатки: специфіка
JIT Warmup:
- Нові Pod’и мають “холодний” JIT
- Перші запити обробляються повільніше
- CPU може тимчасово підскочити → HPA додасть ще Pod’и (over-shooting)
Рішення:
- Readiness Probe з перевіркою warmup
- Initial delay для HPA (stabilization window)
- Startup Probe для довгого warmup
G1 GC та CPU:
- G1 GC використовує CPU для concurrent marking
- HPA може інтерпретувати це як навантаження
- Налаштуйте
-XX:ConcGCThreadsта-XX:ParallelGCThreads
Scaling на основі черг (KEDA)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: worker-scaling
spec:
scaleTargetRef:
name: worker-deployment
minReplicaCount: 1
maxReplicaCount: 50
triggers:
- type: rabbitmq
metadata:
queueName: tasks
queueLength: "10"
activationQueueLength: "5"
KEDA створює HPA з custom metrics.
Troubleshooting
HPA показує <unknown>:
kubectl get hpa
# NAME REFERENCE TARGETS MINPODS MAXPODS
# myapp-hpa Deployment/myapp <unknown> 2 10
Причини:
- Metrics Server не встановлений
- Немає requests в Pod spec
- Метрики ще не зібрані (зачекайте 1-2 хвилини)
HPA не масштабує:
kubectl describe hpa myapp-hpa
# Warning: FailedGetResourceMetric unable to fetch metrics
Cost optimization через HPA
# Обмеження бюджету
maxReplicas: 20 # не більше 20 Pod'ів = контроль витрат
# Повільний scale down
scaleDown:
stabilizationWindowSeconds: 600 # 10 хвилин
Підсумок для Senior
- HPA — основний інструмент горизонтального масштабування.
- Алгоритм: MAX(desired replicas per metric), з behavior policies.
- Завжди задавайте розумний maxReplicas для контролю бюджету.
- Behavior (stabilization window) запобігає thrashing.
- Базуйте скейлінг на CPU або кастомних бізнес-метриках, не на пам’яті.
- KEDA для event-driven масштабування (черги, стріми).
- Java специфіка: JIT warmup, GC overhead — враховуйте при налаштуванні.
- HPA + VPA конфліктують по CPU — використовуйте окремо.
🎯 Шпаргалка для інтерв’ю
Обов’язково знати:
- HPA автоматично масштабує число Pod’ів по CPU, memory, custom або external метрикам
- Формула:
desiredReplicas = ceil[current × (currentMetric / desiredMetric)] - Вимагає Metrics Server та Resources Requests (рахує % від requests, не limits)
- Behavior: stabilization window (scale up 60s, scale down 300s за замовчуванням)
- HPA обирає MAX з розрахунків по всіх метриках
- Масштабування по пам’яті — антипатерн для Java (JVM GC, lazy memory return)
- KEDA — event-driven HPA (Kafka, RabbitMQ, SQS); scale-to-zero з Knative
Часті уточнюючі запитання:
- «Чому HPA показує
<unknown>?» — Metrics Server не встановлений, немає requests, або метрики ще не зібрані - «Java JIT warmup та HPA?» — Нові Pod’и «холодні», CPU підскакує → HPA over-shooting; використовуйте startupProbe
- «HPA + VPA разом?» — Ні по одній метриці; VPA в режимі
Offдля рекомендацій - «Навіщо maxReplicas?» — Захист бюджету від несподіваних сплесків навантаження
Червоні прапорці (НЕ говорити):
- «Масштабую Java по memory usage» (JVM не повертає пам’ять одразу після GC)
- «HPA без requests» (не працює,
<unknown>) - «Ставлю periodSeconds=1 для швидкої реакції» (thrashing, зайве навантаження)
- «HPA замінює Cluster Autoscaler» (HPA → Pod’и, CA → Node; різні рівні)
Пов’язані теми:
- [[Як відбувається масштабування в Kubernetes]] — усі види масштабування
- [[Навіщо потрібні health checks]] — startupProbe для Java warmup
- [[Як моніторити додатки в Kubernetes]] — custom metrics для HPA