Zum Inhalt springen
Alle Artikel

Kubernetes-Kosten auf EKS und GKE: dasselbe Playbook, andere Hebel

Mein AKS-Playbook hat einen Produktiv-Cluster von 7 auf 4 Nodes gebracht, indem die Requests nach echter p95-Nutzung dimensioniert wurden und der Autoscaler das Verkleinern übernahm. Die Methode lässt sich unverändert auf Amazon EKS und Google Kubernetes Engine übertragen. Was sich ändert, ist, woher die Rechnung kommt und welche Knöpfe jede Cloud bietet: Karpenter und Split Cost Allocation bei AWS, die Pod-basierte Abrechnung von Autopilot und Cost Allocation bei Google Cloud. Das ist der Begleitartikel für beide.

10 Min. Lesezeit

1. Wissen, woher die Rechnung kommt

Beide Clouds verlangen eine Pauschale für die verwaltete Control Plane: 0,10 Dollar pro Cluster und Stunde bei Amazon EKS und gleich viel bei GKE, wo das Free Tier jeden Monat einen Autopilot- oder zonalen Standard-Cluster pro Rechnungskonto gutschreibt. Das sind rund 73 Dollar pro Cluster und Monat, und selten das, was weh tut. Die eigentliche Rechnung ist die Rechenleistung darunter: EC2-Instanzen oder Fargate-Pods bei AWS, und bei GKE entweder die Nodes eines Standard-Clusters oder, bei Autopilot, die Ressourcen, die Ihre Pods anfordern.

Eine Position verdient eine Kalendererinnerung. Läuft ein EKS-Cluster mit einer Kubernetes-Version jenseits des Standard-Supports, rutscht er in den Extended Support, und die Cluster-Gebühr steigt auf 0,60 Dollar pro Stunde. Versionen aktuell halten ist günstiger, als für die Verzögerung zu zahlen.

Wohin das Geld auf EKS und GKE fliesst und welche Hebel es bewegen. Der Kreislauf selbst ist auf jeder Cloud derselbe.
Kostenhebel für Kubernetes auf EKS und GKE nebeneinander: bei AWS die EKS-Control-Plane zu 0,10 Dollar pro Stunde, Karpenter, der EC2-Nodes mit Spot und On-Demand konsolidiert, Fargate mit Abrechnung pro Pod, Split Cost Allocation Data im Cost and Usage Report und Compute Savings Plans; bei Google Cloud die GKE-Verwaltungsgebühr zu 0,10 Dollar pro Stunde mit einem Free-Tier-Cluster, Autopilot mit Abrechnung nach Pod-Requests, Standard mit dem Autoscaler-Profil optimize-utilization und Spot VMs, Cost Allocation in BigQuery und Committed Use Discounts.

2. Jedem Namespace einen Preis geben

Ohne Zuordnung ist ein geteilter Cluster eine grosse Zahl, die niemandem gehört. AWS löst das mit Split Cost Allocation Data: Der Cost and Usage Report enthält dann Zeilen auf Container-Ebene, und EKS-Pods bekommen ihren Anteil an der Instanz, auf der sie liefen, nach CPU und Speicher. Bei Google Cloud ergänzt GKE Cost Allocation den Cloud-Billing-Export um Namespace und Kubernetes-Labels Ihrer Workloads, und eine Abfrage in BigQuery zeigt die Kosten pro Team oder pro Dienst.

Das einschalten, bevor sich irgendetwas ändert, und sich auf zwei oder drei Labels einigen, die alle nutzen, etwa team und service. Der erste Report fördert fast immer einen Namespace zutage, an dessen Erstellung sich niemand erinnert.

bash
# GKE: namespace and label breakdown in the Cloud Billing export (BigQuery)
gcloud container clusters update prod-cluster \
  --location=europe-west6 --enable-cost-allocation

# EKS: enable split cost allocation data in the Billing and Cost Management
# preferences; the CUR then has pod-level rows you can sum per namespace and label

3. Requests nach p95 dimensionieren, genau wie bei AKS

Dieser Schritt ist Cloud-neutral. CPU und Speicher pro Container über zwei bis vier Wochen mit einer echten Spitze aus Prometheus ziehen, CPU-Requests etwa auf p95 plus Reserve setzen und Memory-Requests auf das gemessene Maximum plus Puffer, und Namespace für Namespace über Git ändern. Bei EKS sammelt Amazon Managed Service for Prometheus die Metriken, bei GKE Google Cloud Managed Service for Prometheus. Die Abfragen sind dieselben wie in meinem AKS-Artikel.

Der Rechner unten zeigt, wie viele Nodes Sie brauchen, sobald die Requests der echten Nutzung folgen statt Schätzungen. Diese Zahl ist das Ziel für die nächsten zwei Schritte.

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 Checklisten

4. EKS: Karpenter die Nodes wählen und packen lassen

Auf EKS ersetzt Karpenter feste Node-Gruppen durch NodePools, die beschreiben, was erlaubt ist: Instanzfamilien, Architekturen, Spot oder On-Demand. Er startet die Instanz, die zu den wartenden Pods passt, und entfernt oder ersetzt mit der Standard-Konsolidierungsregel WhenEmptyOrUnderutilized Nodes, wenn ihre Pods anderswo oder auf einer günstigeren Maschine Platz haben. Das ist der Moment, in dem ehrliche Requests zu weniger Nodes werden.

Spot-Kapazität für Workloads erlauben, die Unterbrechungen vertragen, etwa zustandslose Web-Schichten, Worker und CI-Runner, und Datenbanken sowie alles mit langem Herunterfahren auf On-Demand lassen. Bauen Ihre Images für beide Architekturen, arm64 aufnehmen, damit Graviton-Instanzen dabei sind. Kleine, sprunghafte Jobs können auf Fargate laufen, das pro Pod statt pro Node abrechnet.

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general
spec:
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]   # spot only where interruptions are fine
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
  limits:
    cpu: "200"                            # a ceiling, so a bug can't scale the bill
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m

Tipp aus der Praxis

Auf jedem NodePool limits setzen. Karpenter startet bereitwillig, was die wartenden Pods verlangen, auch das Ergebnis eines Deployments, das versehentlich 64 Replikas anfordert.

5. GKE: Autopilot wählen oder Standard abstimmen

GKE bietet zwei Abrechnungsmodelle, und sie belohnen verschiedene Dinge. Bei Autopilot werden allgemeine Workloads nach den Ressourcen abgerechnet, die ihre Pods anfordern. Es gibt keine Nodes zu packen; jedes Millicore, das aus einem Request verschwindet, fällt direkt aus der Rechnung. Damit ist Autopilot der Ort, an dem sich Right-Sizing am schnellsten auszahlt, und an dem aufgeblähte Requests am meisten schmerzen.

Im Standard-Modus zahlen Sie für die Nodes, wie bei AKS, also zählt das Packen wieder. Der Cluster Autoscaler hat ein Profil optimize-utilization, das volle Auslastung der Nodes vor freie Reserve stellt und Nodes schneller entfernt. Spot VMs für tolerante Workloads in einem eigenen Node-Pool ergänzen und den Standard-Pool für alles andere auf regulären VMs lassen.

bash
# GKE Standard: pack nodes tighter, scale down sooner
gcloud container clusters update prod-cluster \
  --location=europe-west6 --autoscaling-profile optimize-utilization

# A separate Spot pool for workloads that tolerate interruptions
gcloud container node-pools create spot-pool --cluster=prod-cluster \
  --location=europe-west6 --spot --enable-autoscaling --min-nodes=0 --max-nodes=5

6. Zuletzt verpflichten, auf beiden Clouds

Erst wenn der Fussabdruck geschrumpft ist, ergeben Verpflichtungen Sinn. Bei AWS decken Compute Savings Plans EC2, Fargate und Lambda mit einer Verpflichtung über ein oder drei Jahre ab, gemessen in Dollar pro Stunde, und funktionieren deshalb weiter, wenn Karpenter die Instanzfamilie wechselt. Bei Google Cloud gibt es Committed Use Discounts ressourcen- oder ausgabenbasiert. Die stabile Grundlast abdecken, die nach dem Right-Sizing übrig ist, Spitzen und Spot bleiben bei On-Demand-Preisen.

Die Reihenfolge zählt mehr als der Rabatt: Eine Verpflichtung, die vor dem Aufräumen gekauft wird, bindet Kapazität, die gerade wegfällt, und die Rückgaberegeln für Verpflichtungen sind auf jeder Cloud streng.

7. Auf beiden klein bleiben

Cluster wachsen auf jeder Cloud gleich zurück: kopierte Requests, vergessene Test-Namespaces, ein hochskalierter Pool nach einem Lasttest. Die Routine ist ebenfalls dieselbe. Ein kurzer täglicher Kostenreport pro Namespace im Team-Chat, gebaut aus dem CUR bei AWS oder dem Billing-Export bei Google Cloud. Budgets mit Prognose-Alerts. Eine ResourceQuota pro Namespace, damit Requests nicht unbemerkt wachsen. Und eine Kalendererinnerung für Kubernetes-Upgrades, damit kein EKS-Cluster in den Extended Support rutscht.

Die Methode ist auf AKS, EKS und GKE dieselbe: p95 messen, über Git ändern, die Nodes folgen lassen, zuletzt verpflichten, täglich berichten. Nur die Knöpfe heissen anders.

Fazit

EKS und GKE brauchen dieselbe Disziplin wie AKS: pro Namespace zuordnen, Requests nach p95 dimensionieren, Karpenter oder den Autoscaler verkleinern lassen und sich nur auf das verpflichten, was übrig bleibt.

Weitere Artikel

    Kontakt aufnehmen

    Erzählen Sie mir von Ihrem Projekt, ich antworte innerhalb von 1–2 Werktagen.

    Dominik Heinrich
    Unternehmen
    MADO Consulting

    Weltweit verfügbar, remote. Vor Ort auf Anfrage, je nach Land.

    Ich antworte innerhalb von 1–2 Werktagen. Freie Termine: siehe Kalender

    Öffnet hier den Buchungskalender von Calendly. Beim Laden werden Daten an Calendly übertragen (siehe Impressum).