Veröffentlicht am

Spot Instances für Kubernetes: Kosten um 70% senken

Teilen:
Authors

TL;DR

Spot Instances kosten 60-90% weniger als On-Demand, können aber jederzeit terminiert werden. Mit Taints, Node Affinity und PodDisruptionBudgets lässt sich Kubernetes so konfigurieren, dass nur geeignete Workloads auf Spot-Nodes laufen — und bei Terminierung sauber migriert werden.


Spot Instances in Kubernetes: Strategie und Setup

Cloud-Kosten sind der größte Posten beim Kubernetes-Betrieb, und Compute macht davon 70-80% aus. Spot Instances (AWS), Preemptible VMs (GCP) und Spot VMs (Azure) bieten dieselbe Hardware für einen Bruchteil des Preises — mit einem Haken: Der Cloud-Provider kann sie mit 30 Sekunden bis 2 Minuten Vorwarnung entziehen.

Die richtige Strategie: Mischbetrieb aus On-Demand und Spot.

# Aktuelle Node-Typen und Labels prüfen
kubectl get nodes --show-labels | grep -E "instance-type|node.kubernetes.io"

# Kapazität und Auslastung pro Node
kubectl top nodes

Node Pool Architektur

Die Basis: Mindestens zwei Node Pools. On-Demand für kritische Workloads, Spot für alles andere.

EKS: Spot Managed Node Group

# eks-spot-nodegroup.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: production-cluster
  region: eu-central-1

managedNodeGroups:
  # On-Demand Pool für kritische Workloads
  - name: on-demand-pool
    instanceType: m5.xlarge
    desiredCapacity: 3
    minSize: 2
    maxSize: 5
    labels:
      node-type: on-demand
    tags:
      Environment: production

  # Spot Pool für tolerante Workloads
  - name: spot-pool
    instanceTypes:
      - m5.xlarge
      - m5a.xlarge
      - m5d.xlarge
      - m4.xlarge
    spot: true
    desiredCapacity: 5
    minSize: 0
    maxSize: 15
    labels:
      node-type: spot
    taints:
      - key: spot-instance
        value: "true"
        effect: NoSchedule

Wichtig: Immer mehrere Instance-Typen angeben. Spot-Kapazität variiert pro Typ — mit vier Optionen sinkt die Wahrscheinlichkeit, dass alle gleichzeitig unavailable sind.

GKE: Preemptible Node Pool

# On-Demand Pool (existiert bereits)
# Spot Pool hinzufügen
gcloud container node-pools create spot-pool \
  --cluster=production-cluster \
  --zone=europe-west3-a \
  --machine-type=e2-standard-4 \
  --spot \
  --num-nodes=5 \
  --min-nodes=0 \
  --max-nodes=15 \
  --enable-autoscaling \
  --node-labels=node-type=spot \
  --node-taints=spot-instance=true:NoSchedule

Taints und Tolerations

Der Taint spot-instance=true:NoSchedule verhindert, dass normale Pods auf Spot-Nodes landen. Nur Pods mit passender Toleration werden dort gescheduled.

# Deployment für Spot-Nodes
apiVersion: apps/v1
kind: Deployment
metadata:
  name: batch-processor
spec:
  replicas: 8
  template:
    spec:
      tolerations:
        - key: spot-instance
          operator: Equal
          value: "true"
          effect: NoSchedule
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 90
              preference:
                matchExpressions:
                  - key: node-type
                    operator: In
                    values:
                      - spot
          # Pods über Nodes verteilen
          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 50
                podAffinityTerm:
                  labelSelector:
                    matchLabels:
                      app: batch-processor
                  topologyKey: kubernetes.io/hostname
      terminationGracePeriodSeconds: 120
      containers:
        - name: processor
          image: batch-processor:v2.1
          resources:
            requests:
              cpu: 500m
              memory: 512Mi

Der preferredDuringScheduling-Ansatz ist bewusst gewählt: Wenn keine Spot-Nodes verfügbar sind, kann der Pod auf On-Demand ausweichen, statt pending zu bleiben.

PodDisruptionBudgets: Verfügbarkeit absichern

PDBs stellen sicher, dass bei Node-Terminierung nicht alle Pods gleichzeitig verschwinden.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: batch-processor-pdb
spec:
  minAvailable: 3    # Mindestens 3 Pods müssen laufen
  selector:
    matchLabels:
      app: batch-processor
PDB-StrategieEinstellungAnwendungsfall
minAvailable: 1Mind. 1 Pod läuftEinzelne Services mit wenig Replicas
minAvailable: 50%Hälfte läuft immerBatch-Jobs mit vielen Replicas
maxUnavailable: 1Max. 1 Pod gleichzeitig wegStateful-Workloads

Graceful Shutdown: Sauber herunterfahren

Spot-Nodes werden mit SIGTERM terminiert. Dein Container hat terminationGracePeriodSeconds Zeit, laufende Arbeit abzuschließen.

# preStop-Hook für sauberes Herunterfahren
lifecycle:
  preStop:
    exec:
      command:
        - /bin/sh
        - -c
        - |
          # Neue Requests stoppen
          touch /tmp/shutdown
          # Laufende Requests abarbeiten
          sleep 30
          # Graceful exit
          kill -SIGTERM 1

Für AWS-EKS: Der AWS Node Termination Handler fängt die 2-Minuten-Warnung ab und draint den Node automatisch.

# AWS Node Termination Handler installieren
helm repo add eks https://aws.github.io/eks-charts
helm install aws-node-termination-handler eks/aws-node-termination-handler \
  --namespace kube-system \
  --set enableSpotInterruptionDraining=true \
  --set enableScheduledEventDraining=true

Welche Workloads gehören auf Spot?

Geeignet für Spot:

  • Stateless Webserver mit mehreren Replicas
  • Batch-Processing und Datenverarbeitung
  • CI/CD Build-Agents
  • Dev- und Staging-Umgebungen
  • Machine-Learning-Training (mit Checkpointing)

Nicht geeignet:

  • Datenbanken (PostgreSQL, MySQL)
  • Message Broker (Kafka, RabbitMQ) mit wenigen Replicas
  • Singleton-Services ohne Failover
  • Workloads mit langer Startup-Zeit (>5 Min)

Kostenbeispiel

Ein Cluster mit 10 Worker-Nodes (m5.xlarge, eu-central-1):

KonfigurationNodesMonatliche KostenEinsparung
100% On-Demand10x On-Demand~1.400 €
70/30 Mix3x OD + 7x Spot~620 €56%
50/50 Mix5x OD + 5x Spot~840 €40%

Die 70/30-Variante spart über 9.000 € pro Jahr — bei einem einzelnen Cluster.

FAQ

Was passiert, wenn alle Spot-Nodes gleichzeitig terminiert werden?

Theoretisch möglich, praktisch selten bei diversifizierten Instance-Typen. Der Cluster Autoscaler startet neue Spot-Nodes oder fällt auf On-Demand zurück. PDBs verhindern, dass kritische Services komplett ausfallen.

Wie unterscheiden sich Spot-Preise zwischen AWS, GCP und Azure?

AWS: Dynamische Preise, 60-90% Rabatt, 2 Minuten Warnung. GCP: Fester 60-91% Rabatt, 30 Sekunden Warnung. Azure: Dynamisch, bis 90% Rabatt, 30 Sekunden Warnung. GCP Spot VMs haben keine maximale Laufzeitbeschränkung mehr (früher 24h bei Preemptible).

Kann ich Spot Instances mit dem Cluster Autoscaler kombinieren?

Ja, und du solltest es. Der Cluster Autoscaler skaliert Spot-Node-Pools automatisch. Konfiguriere --expander=least-waste und setze Priorities, damit Spot-Pools bevorzugt werden.

Brauche ich Karpenter statt Cluster Autoscaler?

Karpenter (AWS) ist flexibler bei der Instance-Typ-Auswahl und reagiert schneller auf Spot-Unterbrechungen. Für EKS ist Karpenter ab 2025 die empfohlene Lösung. Für GKE und AKS bleibt der Cluster Autoscaler Standard.

Wie überwache ich Spot-Unterbrechungen?

AWS: CloudWatch Events für Spot Interruption Warnings. GKE: Operations Suite Logs. Zusätzlich: Prometheus-Metriken vom Node Termination Handler und Alerts bei erhöhter Unterbrechungsrate.


Kubernetes-Expertise gesucht?

Managed Services, Beratung, Training oder Security – wir unterstützen deutsche Unternehmen bei allen Kubernetes-Themen.

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