Ein durchschnittlicher Kubernetes-Cluster nutzt 20–30% seiner bereitgestellten Kapazität. Das heißt, 70–80% liegen brach — und auf der Cloud-Rechnung sind das bis zu 35% vermeidbarer Verschwendung. Bei einer Jahresrechnung von 1 Mio. $ sind das 350.000 $, die nicht in Ausfallsicherheit fließen, sondern in Angst.
Die Ursache ist keine Nachlässigkeit, sondern defensives Overprovisioning. Ein Dienst ist einmal per OOM abgestürzt, ein Entwickler hat den Memory-Request verdoppelt — lokal rational, global verschwenderisch. Den Menschen die Schuld zu geben bringt nichts: Solange die Baseline im Template überhöht ist, erbt jeder neue Dienst die Mehrkosten. Die Lösung ist systemisch und hat drei Hebel. Keiner verlangt, die Anwendungen neu zu schreiben.
Hebel 1. Right-Sizing: Requests auf die Realität bringen
Überhöhte Requests sind der Haupttreiber der Verschwendung. Der Scheduler packt Pods nach Requests, nicht nach tatsächlichem Verbrauch: Ein Dienst fordert 500m CPU, verbraucht 95m — und der Cluster-Autoscaler startet zusätzliche Nodes für Luft. Die meisten Dienste tragen CPU-Limits, die 3–5× über dem echten p99 liegen, das Ergebnis von Copy-Paste aus einem Template ohne Review.
Die Grundregel: 30 Tage Verbrauchsperzentile sammeln und neu berechnen: neues CPU-Limit = max(p99 × 1,5; max × 1,1; floor), neues Memory-Limit = max(p99 × 1,3; max × 1,1).
Die entscheidende Asymmetrie: CPU aggressiv kürzen (Throttling ist reversibel — der Pod wird nur langsamer), Memory vorsichtig (ein OOMKill schickt den Pod in eine Restart-Schleife). Der CPU-floor liegt bei etwa 100m für GC-Spitzen und Start; der Memory-Floor hängt von der Runtime ab (JVM ~256Mi, Go ~32Mi). Perzentile rechnet man nicht von Hand: Robusta KRR zieht die Daten direkt aus Prometheus und unterscheidet bursty Batch-Jobs von Steady-State-Diensten, um den Konservatismus der Empfehlungen anzupassen. Gemeldete Einsparung: 35–50% Compute in 60 Tagen.
Hebel 2. Scale-to-Zero: nicht für Leerlauf zahlen
Right-Sizing verkleinert einen laufenden Pod; Scale-to-Zero entfernt den Pod ganz, wenn keine Arbeit anliegt. Drei typische Ziele:
- Async-Worker. CPU-basiertes HPA ist hier nutzlos: Ein Idle-Worker verbraucht keine CPU und skaliert nie herunter. Man muss nach Demand skalieren — der Queue-Tiefe. KEDA bringt Pods von 0 auf N nach SQS-/Kafka-/RabbitMQ-Länge, und
cooldownPerioddämpft das Flattern. - Preview-/PR-Umgebungen. Scale-to-Zero nach Rate eingehender Requests bringt rund 60% Einsparung bei kurzlebigen Umgebungen. Nachts kostet ein Feature-Namespace ehrlich null.
- Geplantes Non-Prod. Stage/Demo im 24/7-Betrieb gegenüber 8/5 ist ein 4-facher Unterschied auf der Rechnung. Das Werkzeug ist kube-downscaler (der gepflegte Fork heißt py-kube-downscaler): die Annotation
downscaler/uptime="Mon-Fri 08:00-20:00 UTC"am Namespace fährt Umgebungen außerhalb der Arbeitszeit herunter,downscaler/excludelässt stehen, was bleiben muss — etwa eine Datenbank für Nachttests. Reales Ergebnis: 168 → 60 Compute-Stunden pro Woche und 2.700 $ Ersparnis im Monat mit einer einzigen Änderung; das morgendliche Scale-up dauert unter drei Minuten. KEDA skaliert nach Events, hier zählt der reine Zeitplan — für Non-Prod reicht das.
Der Einstiegspreis ist der Cold Start (~30 Sekunden bis zur ersten Antwort). Für latenzempfindliche Queues hält man einen warmen Pod (paused-replicas: "1"); für schwere, lang laufende Aufgaben nimmt man einen ScaledJob statt eines langlebigen Workers. In Kubernetes 1.36 kam Scale-to-Zero für External-/Object-Metriken auch ins native HPA (Alpha, Feature Gate HPAScaleToZero), aber KEDA bleibt die Standardwahl: production-ready und mit Dutzenden Scalern out of the box.
Hebel 3. Idle auf Node-Ebene: Bin-Packing, Consolidation, Spot
Selbst mit ehrlichen Requests bleibt Idle-Cost: (Node-Kapazität − Summe der Requests) × Node-Preis. Ein statischer Node-Pool fixiert den Instanztyp und packt schlecht. Karpenter dreht das Modell um: Es provisioniert Nodes passend zu konkreten Pods (Bin-Packing), bewertet das Layout laufend neu und löst unterausgelastete Nodes auf (consolidationPolicy: WhenEmptyOrUnderutilized) und verschiebt zustandslose Workloads mit PDB auf Spot — 60–90% günstiger als On-Demand. Der typische Effekt gegenüber Cluster Autoscaler mit Managed Node Groups ist minus 30–60%.
Spot ist nicht für alles: Datenbanken, Singletons ohne Replikate und Stateful-Workloads ohne Graceful Shutdown bleiben auf On-Demand. Das funktionierende Muster ist eine Baseline auf On-Demand plus Burst auf Spot.
Savings Plans: zuletzt kaufen
Commitment-Rabatte erreichen 66% gegenüber On-Demand — und fixieren die Baseline für ein oder drei Jahre. Vor dem Right-Sizing gekauft, zementieren sie den aufgeblähten Verbrauch: ein Rabatt auf heiße Luft. Die richtige Reihenfolge: zuerst die drei Hebel, dann 30 Tage Stabilisierung, dann ein Commit auf 80% des durchschnittlichen Stundenverbrauchs — der Puffer deckt Wachstum und Saisonalität. No-Upfront kostet 3–5% Rabatt gegenüber Full-Upfront, erhält aber die Liquidität; Compute Savings Plans decken EC2, Fargate und Lambda ohne Bindung an einen Instanztyp.
Den Kreis schließen: ein Prozess, kein einmaliges Setup
Der Kardinalfehler ist „den Autoscaler einrichten und vergessen". Last und Traffic verschieben sich, und Optimierung ohne kontinuierliche Erkennung verrottet. Die Hebel funktionieren also nur auf Basis von zwei Dingen. Erstens Sichtbarkeit: OpenCost verteilt die echten Kosten nach Namespace/Label und macht aus „EC2 = X $" ein „payments-api = Y $". Zweitens Policy: Kyverno oder Gatekeeper blockieren Pods ohne requests, sonst wiederholt sich die Overprovisioning-Geschichte innerhalb eines Monats.
Drei günstige Gewohnheiten halten die Ersparnis: ein wöchentlicher automatischer Namespace-Report in Slack — die Engineers sehen ihren eigenen Trend, ohne eigenes FinOps-Team; Infracost im PR — das Kosten-Delta einer Request-Änderung ist vor dem Merge sichtbar; das Review der VPA-Empfehlungen als Punkt der On-Call-Übergabe. Ein realer Fall nach diesem Schema: 67.000 $ → 31.000 $ im Monat (−54%) in acht Wochen — dieselben Hebel plus Disziplin bei Logging und Data Transfer.
Grundmaßnahmen liefern 15–30% ohne eine einzige architektonische Änderung. Der Rest ist Disziplin, keine Magie.