Kubernetes richtig dimensionieren: das Playbook, mit dem ein Cluster von 7 auf 4 Nodes kam
Die meisten Cluster laufen auf Schätzungen: Requests aus einem Tutorial kopiert, Node-Pools für einen Launch dimensioniert, der zwei Jahre zurückliegt, und eine Cloud-Rechnung, die niemand Zeile für Zeile erklären kann. Jeden Monat zahlen Sie für Kapazität, die leer steht, und jeden Monat fühlt es sich zu riskant an, etwas anzufassen. Right-Sizing behebt das, ohne etwas zu verändern, das Ihre Kunden sehen. Das ist genau die Reihenfolge, die ich nutze, mit Queries, Manifesten und Befehlen, und so kam ein Produktiv-Cluster von 7 auf 4 Nodes, ohne dass ein Kunde etwas merkte.
Aktualisiert 11 Min. Lesezeit
1. Eine Basis schaffen, der man trauen kann
Bevor sich etwas ändert, muss klar sein, was jeder Node-Pool kostet und wem er gehört. Die FinOps Foundation nennt das die Inform-Phase, und die Kostensäule des Azure Well-Architected Framework beginnt am selben Punkt: Was man nicht zuordnen kann, kann man nicht optimieren. In Azure zeigt Cost Management mit amortisierten Kosten den echten Preis pro Node-Pool, Reservierungen eingerechnet. Jeden Namespace mit Team und Produkt labeln, damit sich ein geteilter Cluster fair aufteilen lässt und jeder Euro einen Owner hat.
Dann pro Namespace drei Zahlen vergleichen: was angefordert ist, was tatsächlich genutzt wird und was die Nodes bereitstellen. Requests reserviert der Scheduler, und genau die bezahlen Sie; die Nutzung ist das, was die Container wirklich verbrauchen. In vielen Clustern liegen die Requests weit über der echten Nutzung, und genau diese Lücke bezahlen Sie. Die drei Zahlen pro Namespace in eine einfache Tabelle schreiben. Sie wird Ihr Vorher-Bild und später der Beweis, dass die Änderung gewirkt hat.
Tipp aus der Praxis
Amortisierte Kosten nutzen, nicht tatsächliche. Sonst sieht der Januar mit einer dort gekauften Reservierung teuer aus und der Rest des Jahres billig.
2. p95 über echte Wochen messen
CPU und Speicher pro Container über zwei bis vier Wochen aus Prometheus ziehen, und sicherstellen, dass das Fenster einen Monatsabschluss, eine Kampagne oder den sonst stärksten Tag enthält. Auf AKS sammelt der von Azure Monitor verwaltete Prometheus-Dienst diese Metriken, ohne dass Sie Prometheus selbst betreiben. Nach dem 95. Perzentil dimensionieren, nicht nach dem Durchschnitt: Der Durchschnitt versteckt genau die Spitzen, die Throttling und Out-of-Memory-Kills auslösen.
CPU und Speicher unterschiedlich behandeln, denn Kubernetes tut das auch. CPU ist komprimierbar: Ein Container, der mehr als seinen Anteil will, läuft einfach langsamer. Speicher nicht: Ein Container über seinem Memory-Limit wird beendet, und der Pod startet neu. Beim Speicher deshalb zusätzlich das Maximum des Working Sets ansehen, nicht nur p95. Die Queries pro Container laufen lassen, das Ergebnis in eine Tabelle exportieren und nach der Lücke zwischen Request und p95 sortieren. Die grössten Lücken oben sind der Startpunkt.
# p95 CPU (cores) per container over the last 14 days
quantile_over_time(0.95,
sum by (namespace, pod, container) (
rate(container_cpu_usage_seconds_total{container!="", container!="POD"}[5m])
)[14d:5m]
)
# Peak working-set memory (bytes) per container over the last 14 days
max_over_time(
container_memory_working_set_bytes{container!="", container!="POD"}[14d]
)Tipp aus der Praxis
Speicher über lange Zeiträume nicht über Pods hinweg summieren. Bei Rollouts überlappen alte und neue Pods, und die Summe zeigt eine Nutzung, die es nie gab. Stattdessen das Maximum pro Container nehmen.
3. Requests und Limits aus den Daten ableiten
CPU-Requests auf etwa p95 plus 10 bis 20 Prozent Reserve setzen, Memory-Requests auf das gemessene Maximum plus einen ähnlichen Puffer. Memory-Limits gleich oder nahe am Request halten, damit ein Pod mit Speicherleck seine Nachbarn auf demselben Node nicht aushungert. Bei CPU verzichten viele Teams ganz auf das Limit und verlassen sich für faire Verteilung auf die Requests, das vermeidet Throttling bei latenzkritischen Diensten; ein CPU-Limit bleibt dort, wo harte Isolation nötig ist, etwa bei Batch-Jobs neben einer API.
Die Änderung wie jede andere Code-Änderung ausliefern. Die neuen Werte in die Helm-Values oder Kustomize-Overlays in Git schreiben und das GitOps-Tool, FluxCD oder Argo CD, ausrollen lassen. Namespace für Namespace vorgehen, mit internen Tools und Staging beginnen, und einen Tag lang Latenz, Fehlerraten und Neustarts beobachten, bevor der nächste dran ist. Sieht etwas komisch aus, ist der Rückweg ein Revert eines einzigen Commits. Dieser ruhige, umkehrbare Rhythmus sorgt dafür, dass die Leute dem Vorgehen vertrauen.
# Helm values for one service, derived from 14-day p95 and max
resources:
requests:
cpu: 250m # p95 was ~210m
memory: 512Mi # max working set was ~430Mi
limits:
memory: 512Mi # equal to the request: no noisy neighbours
# no CPU limit: avoids throttling, requests keep sharing fairTipp aus der Praxis
Der Vertical Pod Autoscaler im Empfehlungsmodus (updateMode: Off) liefert pro Workload eine zweite Meinung, ohne einen einzigen Pod zu verändern.
Interaktiv
Wie viele Nodes brauchen Ihre Requests wirklich?
Schieben Sie die Regler auf Ihre Werte. Requests entscheiden, wo Pods Platz finden, zu grosse Requests kaufen also Nodes, die niemand nutzt.
Node-Grösse
5
Nodes heute
2
Nodes nach Right-Sizing (200m)
60%
weniger Node-Kapazität
Nur CPU, rund 90 % eines Nodes sind allokierbar, mindestens 2 Nodes für Verfügbarkeit. Speicher genauso prüfen, bevor ein Node wegfällt.
Alle Rechner und Checklisten4. Node-Pools wählen, die zu den Pods passen
Mit ehrlichen Requests sieht man endlich die echte Form des Workloads, und diese Form bestimmt die Node-Grössen. Zu klein, und der Overhead von System-Pods, DaemonSets und der Kubelet-Reservierung frisst einen grossen Teil jeder Maschine. Zu gross, und ein halb leerer Node kostet viel, während der Autoscaler ihn nicht entfernen kann. Eine nützliche Prüfung: Wie viele typische Pods passen auf einen Node, und wie viel bleibt übrig? Die AKS-Kosten-Best-Practices empfehlen genau diese Übung, bevor man VM-Grössen wählt.
Die Arbeit danach trennen, wie sie sich verhält. Einen kleinen System-Node-Pool für Cluster-Komponenten, einen User-Pool für Produktion und einen Spot-Node-Pool mit Taint für unterbrechbare Arbeit wie Batch-Jobs, CI-Runner und Dev-Umgebungen. Spot-Kapazität kann kurzfristig zurückgeholt werden, also landen dort nur Workloads, die das vertragen. Auf AKS kann zudem Node Auto-Provisioning, das auf Karpenter basiert, die VM-Grössen anhand der wartenden Pods selbst wählen.
5. Den Autoscaler verkleinern lassen
Sind die Requests ehrlich und die Pools passend, packt der Scheduler die Pods dichter, und einige Nodes sind danach weitgehend leer. Der Cluster Autoscaler erkennt das und entfernt sie, solange die Pods darauf anderswo laufen können. Das ist der Moment, in dem die Rechnung tatsächlich sinkt, also sicherstellen, dass der Autoscaler handeln darf: ein sinnvolles Minimum und Maximum pro Pool und nichts, was Pods ohne Grund an bestimmte Nodes bindet.
Auf die klassischen Blocker achten. Pods mit lokalem Speicher, Pods ohne Controller und strenge PodDisruptionBudgets können verhindern, dass ein Node entfernt wird. Die Autoscaler-Logs zeigen, welcher Pod welchen Node blockiert hat, und diese wenigen Fälle zu beheben, bringt oft mehr als eine weitere Runde Request-Tuning. Ein paar Tage Geduld, und die Node-Anzahl pendelt sich auf einem neuen, tieferen Niveau ein.
Tipp aus der Praxis
Bewegt sich die Node-Anzahl nach einer Woche nicht, zuerst die Scale-down-Events des Autoscalers lesen. Fast immer nennen sie genau den einen Pod, der im Weg steht.
6. Nodes sicher entfernen
Manchmal will man schneller sein und Nodes selbst herausnehmen, etwa beim Wechsel auf eine neue VM-Grösse. Bevor Nodes wegfallen, prüfen, ob jeder wichtige Workload mindestens zwei Replikas, ein PodDisruptionBudget und sinnvolle Anti-Affinity hat, sonst kann ein Drain einen Dienst lahmlegen. Dann Kapazität Node für Node abbauen: cordon, drain, Fehlerraten und Latenz beobachten, warten, wiederholen.
Die alte Mindestanzahl an Nodes als Rückweg notieren und die Untergrenze des Autoscalers erst senken, wenn der Cluster eine Weile ruhig mit weniger Nodes gelaufen ist. In einem Produktiv-Cluster kamen wir so von 7 auf 4 Nodes, und kein Kunde hat etwas bemerkt. Die Arbeit selbst war unspektakulär, und genau darum geht es: kleine Schritte, klare Signale und ein Rückweg griffbereit.
# Which workloads would block or break a drain?
kubectl get pdb -A
# One node at a time; check dashboards before the next one
kubectl cordon aks-userpool-12345678-vmss000003
kubectl drain aks-userpool-12345678-vmss000003 \
--ignore-daemonsets --delete-emptydir-data --timeout=10m
# After a calm week on fewer nodes, lower the autoscaler floor
az aks nodepool update -g rg-platform --cluster-name aks-prod -n userpool \
--update-cluster-autoscaler --min-count 2 --max-count 6Tipp aus der Praxis
Während der Arbeitszeit drainen, mit Leuten vor den Dashboards, nicht um 3 Uhr nachts. Wenn sich etwas Unerwartetes bewegt, sollen Augen auf den Grafiken sein.
7. Sich erst auf die kleinere Grösse verpflichten
Erst jetzt Reservierungen oder Savings Plans kaufen, passend zum Cluster, der am Ende übrig ist, nicht zu dem vom Anfang. Die Kostensäulen der Well-Architected Frameworks von Azure und AWS sagen dasselbe mit anderen Worten: erst die Nutzung optimieren, dann den Preis, den man dafür zahlt. Die stabile Grundlast mit ein- oder dreijährigen Verpflichtungen abdecken, Spitzen bleiben Pay-as-you-go oder Spot.
Wer schon Reservierungen für VM-Grössen hält, die nicht mehr laufen, tauscht sie sofort um oder gibt sie zurück, wo der Anbieter das erlaubt, statt sie leer laufen zu lassen. Zuletzt verpflichten, nicht zuerst: In dem Projekt hinter diesem Playbook kamen die Reservierungen als letzter Schritt nach Right-Sizing und Aufräumen, und zusammen sanken die Azure-Kosten in fünf Wochen um 48 %.
8. Klein bleiben: eine Routine daraus machen
Cluster wachsen leise zurück: Ein neuer Dienst kopiert grosszügige Requests von einem alten, ein Lasttest lässt einen Node-Pool hochskaliert zurück, ein Debug-Flag verdoppelt die Logs. Die Operate-Phase der FinOps Foundation dreht sich genau darum: aus einem einmaligen Aufräumen eine Gewohnheit zu machen. Einen kurzen täglichen Kostenreport in den Team-Chat schicken, Budgets mit Prognose-Alerts setzen und pro Namespace eine ResourceQuota anlegen, damit Requests nicht unbemerkt wandern.
Dann den p95-Review jedes Quartal in den Kalender setzen. Wenn die Queries einmal existieren, dauert er etwa eine Stunde und findet meist ein, zwei Dienste, die seit dem letzten Mal gewachsen sind. Die Teams, die ihre Einsparungen behalten, haben nicht das cleverste Tooling; sie schauen jeden Tag auf die Zahlen und behandeln Kosten wie Latenz oder Fehler, als ein weiteres Signal einer gesunden Plattform.
Fazit
Right-Sizing ist ein Kreislauf, kein Projekt: p95 messen, einen Namespace ändern, beobachten, die Nodes folgen lassen, dann verpflichten. In dieser Reihenfolge bleiben die Einsparungen.
Echte Projekte dazu
Selbst ausprobieren
Quellen und offizielle Leitfäden
- Azure Well-Architected Framework: Cost Optimization pillar
- AKS: Best practices for cost optimization
- FinOps Foundation: FinOps Framework (Inform, Optimize, Operate)
- AWS Well-Architected: Cost Optimization pillar
- Kubernetes: Resource management for pods and containers
- Azure Monitor managed service for Prometheus
- AKS: Cluster autoscaler
- Kubernetes: Specifying a PodDisruptionBudget
Weitere Artikel
- 3'025 Pull Requests in zehn Monaten: ein KI-gestützter Delivery-Prozess von innen
- Der EU AI Act für den Mittelstand: was für Sie gilt, und ab wann
- FinOps für KI-Kosten: Tokens, Caching, Routing und Budgets, die halten
- Ein Restaurant-Netzwerk in KI-Antworten sichtbar machen: ein GEO-Projekt Schritt für Schritt
- Wie diese Website gebaut ist: statisch, wo es geht, streamend, wo es muss
- Kubernetes-Kosten auf EKS und GKE: dasselbe Playbook, andere Hebel
- Eine Landing Zone für den Mittelstand, in Terraform oder Bicep: die Teile, die zählen
- Das Playbook für Legacy-Migrationen: Wellen, Parallelbetrieb und identische Zeilenzahlen und Prüfsummen
- MCP-Sicherheit im Detail: KI-Assistenten ins Produkt lassen, ohne die Türen zu öffnen
- Monitoring auf Geschäftsergebnisse: grüne Dashboards, leere Kasse
- KI-Agenten am Telefon: die Architektur, und die Stolperfallen, die keine Demo zeigt
- Restore-Tests: Ein Backup, das nie wiederhergestellt wurde, ist nur eine Hoffnung
- KI-Antworten auf Azure Static Web Apps streamen: der eine Header, der alles zurückhielt
- Einen KI-Assistenten für WhatsApp bauen, von Anfang bis Ende: was es über die Demo hinaus braucht
- Air-gapped-Systeme: kritische Software ganz ohne Internet betreiben
- Produktive KI auf AWS: Amazon Bedrock und AgentCore in einem privaten Setup
- Produktive KI auf Microsoft Foundry: ein privates Referenz-Setup für Agenten
- /goal, /loop oder Routines: Hören Sie auf, Ihren Coding-Agenten zu babysitten
- Claudes neue Pläne: Max, Ultra und was sie für Teams bedeuten
- OpenAI Codex Ende 2026: Goal Mode, Dots und wie man es absichert
- GitHub Copilot, Claude Code oder Codex? So würde ich für ein Unternehmen entscheiden
- GEO-Grundlagen: So erscheinen Sie in KI-Antworten
- Produktive KI auf Google Cloud: von Vertex AI zur Gemini Enterprise Agent Platform
- Lokale LLMs im Air-Gap-Netz: KI für Ihre sensibelsten Daten
- Ich will ein lokales LLM betreiben: Welchen Server soll ich kaufen?
- MiniMax M3: ein offenes Spitzenmodell zum Selbstbetreiben?
- Prompt-Research im grossen Stil mit einem offenen Modell
- SEO und GEO zusammen: ein praktisches Audit in 6 Schritten
- Private KI für sensible Daten: ein lokales LLM-Setup, das durch die Sicherheitsprüfung kommt
- Vom KI-Prototyp zur Produktion: die acht Schichten, die ich ergänze, in dieser Reihenfolge
