- Authors

- Name
- Phillip Pham
- @ddppham
Kubernetes Autoscaling: HPA, VPA und Cluster Autoscaler richtig kombinieren
TL;DR
- HPA skaliert die Anzahl der Pods, VPA passt CPU/Memory-Requests einzelner Pods an, Cluster Autoscaler fuegt Nodes hinzu oder entfernt sie.
- HPA und VPA duerfen nicht gleichzeitig auf dieselbe Metrik (z.B. CPU) fuer denselben Workload reagieren -- das fuehrt zu Skalierungsschleifen.
- VPA im Recommender-Modus ist risikofrei und liefert sofort verwertbare Daten ueber echten Ressourcenbedarf.
- Der Cluster Autoscaler reagiert auf unschedulable Pods, nicht auf Node-Auslastung. Das ist ein entscheidender Unterschied.
- Korrekte Resource Requests sind die Grundlage fuer alles. Ohne sie funktioniert keiner der drei Autoscaler zuverlaessig.
Das Problem: Ueberprovisionierung
Die meisten Kubernetes-Cluster sind massiv ueberprovisioniert. Entwickler setzen CPU- und Memory-Requests konservativ hoch an, weil niemand fuer einen OOM-Kill verantwortlich sein will. Das Ergebnis: 20-30% durchschnittliche CPU-Auslastung bei Nodes, die rund um die Uhr bezahlt werden.
Das ist kein theoretisches Problem. Wer seine Cloud-Rechnung nach Workload aufschluesselt, findet fast immer Deployments, die 500m CPU requesten, aber dauerhaft unter 50m liegen. Hochgerechnet auf dutzende Services und mehrere Environments summiert sich das schnell auf tausende Euro pro Monat.
Autoscaling loest dieses Problem auf drei Ebenen: Pod-Anzahl (HPA), Pod-Groesse (VPA) und Cluster-Kapazitaet (Cluster Autoscaler).
Horizontal Pod Autoscaler (HPA)
Der HPA ist die bekannteste Autoscaling-Komponente. Er skaliert die Anzahl der Pods basierend auf Metriken.
Basis-Konfiguration mit CPU-Metrik
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-api-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-api
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 4
periodSeconds: 60
Die behavior-Section ist wichtig und wird oft weggelassen. Ohne sie skaliert der HPA aggressiv herunter, sobald die Last kurz sinkt, und dann sofort wieder hoch. Das fuehrt zu Flapping.
Das stabilizationWindowSeconds fuer Scale-down (hier 300 Sekunden) sorgt dafuer, dass der HPA mindestens 5 Minuten wartet, bevor er Pods entfernt. Fuer Scale-up ist ein kuerzeres Fenster sinnvoll, damit Lastspitzen schnell abgefangen werden.
Custom Metrics mit Prometheus
CPU-basiertes Scaling reicht fuer viele Workloads, aber nicht fuer alle. Ein API-Gateway ist vielleicht CPU-technisch entspannt, hat aber hunderte offene Connections in der Warteschlange. Hier helfen Custom Metrics:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: queue-worker-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-worker
minReplicas: 1
maxReplicas: 50
metrics:
- type: Pods
pods:
metric:
name: rabbitmq_queue_messages_ready
target:
type: AverageValue
averageValue: "30"
Fuer Custom Metrics braucht es den Prometheus Adapter oder KEDA (Kubernetes Event-Driven Autoscaling). KEDA ist die flexiblere Loesung und unterstuetzt ueber 60 Event-Quellen out of the box -- von RabbitMQ ueber Kafka bis hin zu Cron-Schedules.
Vertical Pod Autoscaler (VPA)
Der VPA analysiert den tatsaechlichen Ressourcenverbrauch von Pods und empfiehlt oder setzt optimale CPU/Memory-Requests.
VPA-Modi im Vergleich
| Modus | Verhalten | Risiko | Empfehlung |
|---|---|---|---|
| Off | Nur Empfehlungen generieren, nichts anwenden | Keins | Fuer den Start |
| Initial | Requests nur bei Pod-Erstellung setzen | Gering | Fuer stateful Workloads |
| Auto | Requests anpassen, Pods werden neugestartet | Mittel | Fuer stateless Workloads |
VPA im Recommender-Modus einrichten
Starten Sie immer im Off-Modus. Das liefert Daten ohne Risiko:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-api-vpa
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-api
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: web-api
minAllowed:
cpu: "50m"
memory: "64Mi"
maxAllowed:
cpu: "2000m"
memory: "2Gi"
Nach ein paar Tagen koennen Sie die Empfehlungen abfragen:
# VPA-Empfehlungen auslesen
kubectl describe vpa web-api-vpa -n production
# Relevante Felder in der Ausgabe:
# Recommendation:
# Container Recommendations:
# Container Name: web-api
# Lower Bound: Cpu: 25m, Memory: 128Mi
# Target: Cpu: 100m, Memory: 256Mi
# Upper Bound: Cpu: 500m, Memory: 512Mi
# Uncapped Target: Cpu: 100m, Memory: 256Mi
Der Target-Wert ist die Empfehlung fuer den Request. Wenn Ihr Deployment aktuell 500m CPU und 1Gi Memory requestet, der VPA aber 100m CPU und 256Mi empfiehlt, verschwenden Sie das Fuenffache an CPU und das Vierfache an Memory.
VPA und HPA gleichzeitig nutzen
Die offizielle Empfehlung: VPA und HPA duerfen nicht auf dieselbe Metrik reagieren. In der Praxis bedeutet das:
- HPA skaliert auf CPU-Auslastung
- VPA optimiert nur Memory-Requests (oder umgekehrt)
Oder besser: VPA im Off-Modus laufen lassen und die Empfehlungen manuell oder per CI/CD in die Deployments uebernehmen. HPA uebernimmt die dynamische Skalierung. Das vermeidet Konflikte zuverlaessig.
Cluster Autoscaler
Der Cluster Autoscaler (CA) arbeitet auf Node-Ebene. Er loest zwei Probleme:
Scale-up: Wenn der Scheduler Pods nicht platzieren kann, weil kein Node genuegend freie Ressourcen hat, fuegt der CA einen neuen Node hinzu.
Scale-down: Wenn ein Node laengere Zeit unter 50% Auslastung liegt und alle seine Pods auf andere Nodes umgezogen werden koennen, entfernt der CA diesen Node.
Wichtiges Detail: Der CA reagiert nicht auf Auslastung
Das ist ein verbreitetes Missverstaendnis. Der CA skaliert nicht hoch, weil Nodes "busy" sind. Er skaliert hoch, weil Pods im Status "Pending" stecken und nicht geplant werden koennen. Deshalb sind korrekte Resource Requests so wichtig: Wenn Pods keine Requests definieren, "sieht" der Scheduler keinen Ressourcenmangel, und der CA wird nie aktiv.
Terraform-Konfiguration fuer AWS EKS
resource "aws_eks_node_group" "production" {
cluster_name = aws_eks_cluster.main.name
node_group_name = "production-nodes"
node_role_arn = aws_iam_role.node.arn
subnet_ids = var.private_subnet_ids
instance_types = ["m6i.xlarge"]
scaling_config {
desired_size = 3
min_size = 2
max_size = 15
}
labels = {
workload-type = "production"
}
tags = {
"k8s.io/cluster-autoscaler/enabled" = "true"
"k8s.io/cluster-autoscaler/${var.cluster_name}" = "owned"
}
}
Die Tags k8s.io/cluster-autoscaler/enabled und k8s.io/cluster-autoscaler/<cluster-name> sind bei EKS zwingend erforderlich, damit der CA die Node Group erkennt.
Scale-down-Verhalten tunen
Der CA wartet standardmaessig 10 Minuten, bevor er einen unterausgelasteten Node entfernt. Das laesst sich anpassen:
# Cluster Autoscaler Deployment patchen
kubectl set env deployment/cluster-autoscaler \
-n kube-system \
SCALE_DOWN_DELAY_AFTER_ADD=5m \
SCALE_DOWN_UNNEEDED_TIME=5m \
SCALE_DOWN_UTILIZATION_THRESHOLD=0.5
Vorsicht mit zu aggressiven Werten. Ein SCALE_DOWN_UNNEEDED_TIME von 1 Minute fuehrt zu staendigem Hinzufuegen und Entfernen von Nodes, was die Cluster-Stabilitaet beeintraechtigt.
Die drei Autoscaler im Zusammenspiel
Das Zusammenspiel funktioniert so:
- Last auf dem Web-API steigt
- HPA erkennt CPU-Auslastung ueber 70% und erstellt neue Pods
- Scheduler versucht, die neuen Pods zu platzieren
- Wenn kein Node genug freie Ressourcen hat, bleiben Pods "Pending"
- Cluster Autoscaler bemerkt die Pending-Pods und fuegt einen Node hinzu
- Neuer Node ist nach 2-5 Minuten ready, Pods werden geplant
- Parallel hat VPA (im Off-Modus) Daten gesammelt und empfiehlt, dass die Requests eigentlich zu hoch sind
Wenn Last sinkt, passiert das Umgekehrte: HPA entfernt Pods, Nodes werden unterausgelastet, CA entfernt Nodes.
Typische Fehler und wie man sie vermeidet
1. Keine Resource Requests definiert: Ohne Requests hat der Scheduler keine Grundlage fuer Entscheidungen. HPA kann die Auslastung nicht berechnen, VPA hat keine Basis fuer Empfehlungen, CA erkennt keinen Ressourcenmangel. Requests sind Pflicht.
2. Requests gleich Limits setzen: Wenn requests und limits identisch sind (Guaranteed QoS), gibt es keinen Spielraum fuer Bursts. Das fuehrt zu unnoetigem Scaling. Besser: Requests auf den Median setzen, Limits auf das 2-3-fache. Mehr dazu in unserem Artikel zu OOM-Kills vermeiden.
3. HPA maxReplicas zu niedrig: Ein maxReplicas: 5 schuetzt zwar vor Kostenexplosion, kann aber bei echten Lastspitzen zu Ausfaellen fuehren. Lieber grosszuegig setzen und ueber Monitoring und Alerts absichern.
4. Cluster Autoscaler mit falschen Node-Typen: Wenn der CA nur eine Node-Groesse kennt (z.B. m6i.2xlarge mit 8 CPUs), aber die meisten Pods nur 100m CPU brauchen, werden Nodes extrem ineffizient gefuellt. Nutzen Sie mehrere Node Groups mit unterschiedlichen Instance-Typen.
5. PodDisruptionBudgets vergessen: Ohne PDBs kann der CA Nodes entfernen, auf denen alle Replicas eines Service laufen. Das fuehrt zu Downtime. Definieren Sie PDBs fuer jeden kritischen Service:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-api-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: web-api
Kosten messen und optimieren
Autoscaling einzurichten ist der erste Schritt. Den Effekt zu messen der zweite. Folgende Metriken sollten Sie tracken:
| Metrik | Ziel | Tool |
|---|---|---|
| Durchschnittliche Node-CPU-Auslastung | 60-75% | Prometheus + node_exporter |
| Durchschnittliche Pod-CPU-Auslastung | 50-70% | Prometheus + cAdvisor |
| Verhaeltnis Requests zu tatsaechlichem Verbrauch | unter 1.5x | VPA Recommender |
| Monatliche Infrastrukturkosten | Sinkend ueber Zeit | Cloud-Provider-Billing |
| Anzahl Pending-Pod-Events | Nahe 0 | kube-state-metrics |
Ein guter Startpunkt ist das Kubernetes Resource Management, um die Grundlagen der Ressourcenzuweisung zu verstehen. Fuer die Gesamtkostenbetrachtung empfiehlt sich unser Artikel zum Kubernetes Hosting Kostenvergleich.
Fortgeschritten: KEDA fuer Event-Driven Autoscaling
Fuer Workloads, die nicht auf CPU oder Memory reagieren sollten, ist KEDA die bessere Wahl. KEDA kann auf externe Events skalieren:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: order-processor
namespace: production
spec:
scaleTargetRef:
name: order-processor
minReplicaCount: 0
maxReplicaCount: 100
triggers:
- type: rabbitmq
metadata:
queueName: orders
host: amqp://rabbitmq.messaging:5672
queueLength: "5"
Beachten Sie minReplicaCount: 0. KEDA kann Workloads komplett auf null skalieren, was fuer Batch-Jobs oder selten genutzte Services erhebliche Kosten spart. Sobald Nachrichten in der Queue eintreffen, werden Pods hochgefahren.
Mehr zum Zusammenspiel von Autoscaling mit anderen Optimierungen finden Sie in unserem Capacity Planning Guide und dem Artikel zur Kubernetes Performance Optimierung.
Fazit
Kubernetes-Autoscaling ist kein Einmal-Setup. Es erfordert initiale Analyse, schrittweise Einfuehrung und kontinuierliches Tuning. Aber der Aufwand lohnt sich: Korrekt konfiguriertes Autoscaling senkt die Infrastrukturkosten erheblich und verbessert gleichzeitig die Verfuegbarkeit.
Der pragmatische Einstieg: VPA im Off-Modus installieren, zwei Wochen Daten sammeln, Requests anpassen. Dann HPA fuer die wichtigsten Services einrichten. Cluster Autoscaler zum Schluss.
Falls Sie Unterstuetzung bei der Autoscaling-Strategie oder der Implementierung brauchen, stehen wir unter /kontakt zur Verfuegung.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Capacity Planning: Kubernetes-Autoscaling richtig nutzen
HPA, VPA, Cluster Autoscaler und KEDA kombinieren für Capacity Planning in Kubernetes. Mit Praxisbeispielen und Entscheidungshilfe.
Kubernetes E-Commerce: Black Friday Autoscaling richtig
Kubernetes für Black Friday konfigurieren: HPA mit Custom Metrics, Scheduled Scaling vor Peak-Events und Kostenoptimierung in der Nebensaison.
Kubernetes Skalierung: HPA, VPA und KEDA kombinieren
Kubernetes Skalierungs-Patterns im Überblick: HPA, VPA, Cluster Autoscaler und KEDA richtig kombinieren für Multi-Dimensional Autoscaling.
Kubernetes HPA konfigurieren: Autoscaling Tutorial
Kubernetes Horizontal Pod Autoscaler (HPA) einrichten und konfigurieren. YAML-Beispiele für CPU-, Memory- und Custom-Metrics-basiertes Autoscaling.
Kubernetes Capacity Planning: HPA, VPA und Kostenoptimierung
Kubernetes Capacity Planning mit HPA und VPA: Ressourcenplanung, Prometheus-Monitoring und konkrete Skalierungsstrategie für Kostensenkung.