„Autoscaling“ bezeichnet in Kubernetes drei verschiedene Mechanismen, und deren Verwechslung ist der häufigste Grund, warum ein Cluster, der skalieren sollte, es nicht tut. Pods skalieren mit einem HorizontalPodAutoscaler, Nodes skalieren mit den Grenzen der Worker-Pools, und das Control Plane skaliert mit der Last auf der API. Dieser Artikel erklärt jeden einzelnen und führt dann durch einen echten Test auf einem Kube-DC Managed Cluster, mit den Manifesten, damit Sie ihn wiederholen können.
Drei Dinge können skalieren
| Ebene | Was skaliert | Auf einem Kube-DC Managed Cluster |
|---|---|---|
| Pods | Die Anzahl der Replikate eines Deployments oder StatefulSets, gesteuert durch eine Metrik wie die CPU | Standard-HorizontalPodAutoscaler, mit bereits installiertem metrics-server. In diesem Artikel getestet |
| Nodes | Die Anzahl der Worker-Maschinen, die zum Betrieb dieser Pods zur Verfügung stehen | Worker-Pools mit Minimal- und Maximalgrenzen pro Pool, wie für die Plattform dokumentiert. Nicht Teil unseres Tests |
| Control Plane | Die Ressourcen von API-Server und etcd, wenn die Cluster-Last wächst | Vertikale Autoskalierung beider, standardmäßig aktiv und innerhalb konfigurierter Grenzen, wie dokumentiert. Nicht Teil unseres Tests |
Wir kennzeichnen jede Ebene danach, was wir getestet haben und was wir nur aus der Dokumentation kennen, denn der Unterschied zählt bei der Kapazitätsplanung.
Was der HorizontalPodAutoscaler tatsächlich tut
Der HorizontalPodAutoscaler (HPA) ist eine Kontrollschleife, die innerhalb des Kubernetes-Control-Plane läuft. Standardmäßig wacht er alle 15 Sekunden auf, liest die Metriken der Pods, auf die er zielt, und passt die Replikatzahl des Deployments an. Vier Details zu verstehen erklärt fast jede Überraschung:
- Die Auslastung ist relativ zum Request. Ein Ziel von 50 % CPU bedeutet 50 % der von den Containern des Pods angeforderten CPU, nicht 50 % des Nodes. Hat ein Container keinen CPU-Request, ist die Auslastung nicht definiert, und der Autoscaler unternimmt für diese Metrik nichts.
- Er braucht die Metrics-API. Die metrics.k8s.io-API wird normalerweise vom Metrics-Server-Add-on bereitgestellt, das auf einem selbst verwalteten Cluster separat installiert werden muss.
- Die Rechnung ist ein Verhältnis. Die gewünschte Replikatzahl entspricht der aktuellen Replikatzahl, multipliziert mit dem Verhältnis der aktuellen Metrik zum Ziel, aufgerundet. Liegt das Verhältnis innerhalb einer Toleranz von 0,1 um 1,0, passiert nichts.
- Das Herunterskalieren ist bewusst langsam. Der Controller merkt sich aktuelle Empfehlungen und handelt nach der höchsten in einem Fenster, das standardmäßig fünf Minuten beträgt, was schwankende Metriken glättet und Flattern verhindert.
Ein Beispiel: Ein Replikat, das mit 57 % CPU gegen ein Ziel von 50 % läuft, ergibt ein Verhältnis von 1,14, und das Aufrunden von 1 × 1,14 ergibt 2 Replikate. Genau das war der erste Schritt, den wir im folgenden Test beobachtet haben.
Der Test: Skalieren eines Managed Clusters unter echter Last
In unserem End-to-End-Test vom August 2026 haben wir einen Managed Cluster namens test2 mit zwei Worker-Nodes erstellt, jeweils mit 1 vCPU und 2 GB Arbeitsspeicher dimensioniert, um in die im Kontingent des Pakets verbliebene Reserve zu passen. Der API-Endpunkt des Clusters ist standardmäßig privat, daher haben wir ihn aus der integrierten Cloud Shell des Projekts über die interne Service-Adresse des Clusters erreicht, nicht aus dem Internet. Beide Worker waren Ready, und metrics-server war bereits installiert und funktionierte, was der HPA voraussetzt.
Wir haben eine kleine Webanwendung mit einem HPA bereitgestellt, der 50 % CPU anstrebt und einen Bereich von 1 bis 6 Replikaten hat. Dies sind Beispielmanifeste in derselben Form wie im Test; die CPU-Request-Werte sind illustrativ:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: nginxdemos/hello
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
ports:
- port: 80
targetPort: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hello
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hello
minReplicas: 1
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Um dauerhafte Last zu erzeugen, haben wir mehrere Wegwerf-Pods im Cluster gestartet, die jeweils in einer Schleife HTTP-Anfragen an den Service senden. Führen Sie den ersten Befehl in zwei oder drei Shells mit unterschiedlichen Namen aus und beobachten Sie den Autoscaler in einer weiteren:
kubectl run load-1 --image=busybox:1.36 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://hello > /dev/null; done"
kubectl get hpa hello --watch
Zwei ehrliche Anmerkungen zu diesem Ergebnis. Wir haben das Herunterskalieren nicht zeitlich gemessen, und das standardmäßige Stabilisierungsfenster von fünf Minuten ist der Grund, warum es dem Hochskalieren hinterherhinkt. Und der Test belegt nur die Pod-Ebene: Er zeigt, dass HPA, Metrics-API und die Einplanung des Clusters auf einem Kube-DC Managed Cluster zusammenarbeiten, nicht, wie sich die Worker-Pools bei Skalierung auf Node-Ebene verhalten.
Wenn Sie fertig sind, entfernen Sie die Last mit kubectl delete pod load-1 (und allen weiteren gestarteten Generatoren) und danach die Test-Workload mit kubectl delete hpa,svc,deploy hello.
Was Pods allein nicht leisten können: Kapazität
Der HPA fügt Pods hinzu, und Pods brauchen einen Ort zum Laufen. Sind die Worker voll, bleiben die zusätzlichen Replikate im Status Pending, bis Kapazität verfügbar wird – das maxReplicas des HPA ist also nur sinnvoll, wenn der darunterliegende Pool so viele Pods aufnehmen kann. Multiplizieren Sie die maximale Replikatzahl mit den Requests jedes Pods und vergleichen Sie das Ergebnis mit der freien Kapazität Ihres Worker-Pools.
Auf Kube-DC werden Worker-Pools pro Pool definiert (CPU, Arbeitsspeicher, Datenträger und Image), mit Autoscaling-Grenzen pro Pool, und der Pool bezieht seine Ressourcen aus dem Kontingent Ihres Pakets. Dieses Kontingent ist über alles gepoolt, was Sie betreiben: Container, virtuelle Maschinen und Managed Cluster teilen sich dasselbe vCPU- und Arbeitsspeicher-Budget. Die Folge haben wir in unserem Test gesehen: Ein bestehender Managed Cluster und eine virtuelle Maschine nutzten etwa 7,5 der 8 vCPU eines Pro-Pakets und ließen keinen Platz für einen GPU-Pod. Deshalb haben wir die Test-Worker mit 1 vCPU und 2 GB dimensioniert. Betrachten Sie Ihr Paket als Obergrenze für jede Skalierungsebene und prüfen Sie die verbleibende Reserve, bevor Sie ein Maximum erhöhen.
Das Control Plane skaliert ebenfalls
Ein Cluster mit vielen Pods und häufiger Skalierung belastet den API-Server und etcd. Die Kube-DC-Dokumentation gibt an, dass Ressourcen von Control Plane und etcd bei wachsender Cluster-Last innerhalb konfigurierter Grenzen automatisch passend dimensioniert werden, mit standardmäßig aktivierter vertikaler Autoskalierung. In einem selbst verwalteten Cluster ist es Ihre Aufgabe, diese Komponenten korrekt zu dimensionieren, und etcd reagiert empfindlich auf Ressourcenmangel, wie wir in unserem Artikel zu Managed vs. Self-Hosted Kubernetes erklären.
Häufige Fehler
- Keine Resource-Requests. Ohne CPU-Request lässt sich ein Auslastungsziel nicht berechnen, und der HPA unternimmt für diese Metrik nichts.
- Das Startverhalten ignorieren. Ein Pod, der beim Initialisieren viel CPU verbraucht, kann zusätzliche Hochskalierungen auslösen. Die Kubernetes-Dokumentation empfiehlt eine Startup-Probe oder eine Readiness-Probe, die erst nach der Spitze erfolgreich ist, und der Controller ignoriert CPU-Messwerte eines Pods während dessen Initialisierungsphase.
- Auf CPU skalieren, wenn CPU nicht der Engpass ist. Die autoscaling/v2-API unterstützt auch Speicher und benutzerdefinierte Metriken, die besser zu Workloads passen, die von Warteschlangen oder I/O bestimmt werden.
- Das Maximum setzen, ohne die Kapazität zu prüfen. Wie oben warten Replikate jenseits dessen, was der Pool aufnehmen kann, einfach im Status Pending.
- Ein einzelnes Replikat in der Produktion betreiben. Ein Minimum von eins bedeutet einen Pod, solange die Last niedrig ist. Verwenden Sie für alles, was den Verlust eines Nodes überstehen muss, ein höheres Minimum.
Quellen
- Kubernetes: Horizontal Pod Autoscaling
- Kube-DC platform datasheet: managed Kubernetes clusters
- Kube-DC: provisioning a Managed Cluster
Weiterführende Lektüre
- Managed vs. Self-Hosted Kubernetes: Die technische Realität
- So bewerten Sie einen Managed-Kubernetes-Anbieter in Europa
- Geteilte GPU auf Kubernetes: Was Sie tatsächlich bekommen
Führen Sie diesen Test auf Ihrem eigenen Cluster durch
Jedes Kube-DC-Paket enthält verschachtelte Kubernetes-Cluster, die Sie in einem Self-Service-Portal aus Ihrem Projekt erstellen, mit einsatzbereitem metrics-server und sichtbarem Kontingent, damit Sie die Kapazität planen können. Dahinter stehen dedizierte vCPU, Ceph-basierter NVMe-Speicher, eine dedizierte öffentliche IPv4 und S3-kompatibler Objektspeicher, mit 24/7-Support per E-Mail und Ticket und einem Lösungsziel von 4 Stunden. Wiederholen Sie die obige Anleitung und sehen Sie selbst, wie sich die Replikate bewegen.
Kube-DC Kubernetes entdecken