Kubernetes HPA — automatyczne skalowanie podów
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS / Kubernetes
Ręczne ustawianie liczby replik to anty-pattern w Kubernetes. HPA (Horizontal Pod Autoscaler) automatycznie dostosowuje liczbę podów na podstawie obciążenia — dodaje repliki gdy ruch rośnie, usuwa gdy ruch spada. W efekcie płacisz tylko za zasoby które faktycznie używasz, a aplikacja nie pada pod dużym ruchem. Ten artykuł pokazuje pełną konfigurację: od metrics-server przez CPU/RAM scaling, po zaawansowane custom metrics z Prometheus i KEDA.
Instalacja metrics-server
HPA wymaga metrics-server do odczytu CPU i RAM z podów. W k3s jest on domyślnie zainstalowany. W pełnym Kubernetes (kubeadm) trzeba go dodać:
# Instalacja oficjalnego metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Dla klastrów lokalnych (k3d, minikube) dodaj flage TLS:
kubectl patch deployment metrics-server -n kube-system --type=json \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
# Weryfikacja (po ~60 sek od instalacji)
kubectl top nodes
kubectl top pods --all-namespaces
# Jesli kubectl top nie dziala — sprawdz logi:
kubectl logs -n kube-system deployment/metrics-server Podstawowy HPA — skalowanie po CPU
Zanim stworzysz HPA, Deployment MUSI mieć ustawione resources.requests.cpu — bez
tego HPA nie ma punktu odniesienia i nie będzie działać.
# Deployment z wymaganymi requests (warunek HPA!)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.25
resources:
requests:
cpu: "100m" # WYMAGANE dla HPA CPU
memory: "128Mi" # WYMAGANE dla HPA Memory
limits:
cpu: "500m"
memory: "512Mi" # hpa-cpu.yaml — HPA v2 (Kubernetes 1.23+)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # skaluj gdy srednia CPU > 60% requests
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70 # skaluj gdy RAM > 70% requests
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5 min cooling down
policies:
- type: Pods
value: 1
periodSeconds: 60 # max 1 pod usuniecia na minute
scaleUp:
stabilizationWindowSeconds: 30 # szybki scale-up
policies:
- type: Pods
value: 4
periodSeconds: 60 # max 4 nowe pody na minute kubectl apply -f hpa-cpu.yaml # Monitoring HPA kubectl get hpa web-app-hpa kubectl describe hpa web-app-hpa # Test load (w osobnym terminalu — generuje ruch na pod) kubectl run -i --tty load-generator --rm \ --image=busybox:1.28 \ --restart=Never \ -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://web-app; done" # Obserwuj skalowanie w czasie rzeczywistym watch kubectl get hpa,pods
Custom metrics — Prometheus Adapter
Skalowanie po CPU i RAM nie wystarczy dla wszystkich aplikacji. Prometheus Adapter udostępnia dowolne metryki z Prometheusa przez Kubernetes Custom Metrics API. HPA może wtedy skalować np. po liczbie żądań na sekundę (RPS), długości kolejki, lub niestandardowym wskaźniku biznesowym.
# Instalacja Prometheus Adapter przez Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--set prometheus.url=http://prometheus-server.monitoring.svc.cluster.local \
--namespace monitoring
# Konfiguracja — mapper metryki z Prometheusa do K8s API
# values.yaml (fragment):
rules:
custom:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total"
as: "${1}_per_second"
metricsQuery: 'rate(http_requests_total{{.LabelMatchers}}[2m])'
# HPA uzywajacy custom metric
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-custom-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100" # skaluj gdy >100 RPS per pod KEDA — skalowanie event-driven i do zera
KEDA rozszerza K8s o skalowanie na podstawie 70+ źródeł zdarzeń — kolejki, streamy, bazy danych, cron. Jego największa zaleta: skalowanie do zera replik gdy brak pracy, i back to N gdy pojawi się praca.
# Instalacja KEDA
helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda --namespace keda --create-namespace
# ScaledObject — skalowanie po RabbitMQ (przyklad)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: worker-scaledobject
spec:
scaleTargetRef:
name: message-worker # nazwa Deployment
minReplicaCount: 0 # skalowanie do zera!
maxReplicaCount: 30
cooldownPeriod: 60
triggers:
- type: rabbitmq
metadata:
host: amqp://user:[email protected]
queueName: job-queue
queueLength: "10" # 1 pod per 10 wiadomosci w kolejce Porównanie HPA vs VPA vs KEDA
| Narzędzie | Skaluje | Źródło metryk | Skalowanie do 0 | Kiedy używać |
|---|---|---|---|---|
| HPA | Liczba podów | CPU, RAM, Custom | Nie (min 1) | Bezstanowe API, web serwisy |
| VPA | CPU/RAM per pod | CPU, RAM historyczne | Nie | Optymalizacja requests, bazy |
| KEDA | Liczba podów | 70+ źródeł zdarzeń | Tak (do 0) | Event-driven, kolejki, batch |