Veröffentlicht am

Kubernetes Probes Best Practices und häufige Fehler

Teilen:
Authors

Kubernetes Health Checks: Probes richtig setzen

Ein falsch konfigurierter Liveness Probe ist schlimmer als gar kein Probe. Klingt uebertrieben? Ist es nicht. Ein zu aggressiver Liveness Probe toetet gesunde Container unter Last. Ein fehlender Readiness Probe schickt Traffic an Pods, die noch nicht bereit sind. Dieser Artikel zeigt, wie Sie alle drei Probe-Typen richtig einsetzen.

TL;DR

  • Readiness Probes steuern, ob ein Pod Traffic bekommt. Immer setzen, wenn der Pod hinter einem Service steht.
  • Liveness Probes starten den Container neu, wenn er haengt. Nur einsetzen, wenn Ihre Anwendung in einen unwiederherstellbaren Zustand geraten kann.
  • Startup Probes schuetzen langsam startende Container vor zu fruehen Liveness-Checks. Pflicht fuer Java-Anwendungen und aehnliche Workloads.
  • Fehler Nummer 1: Den gleichen Endpoint fuer Liveness und Readiness verwenden.

Pruefen Sie den aktuellen Probe-Status eines Pods:

# Events zeigen Probe-Fehler
kubectl describe pod web-app -n production | grep -A 3 "Liveness\|Readiness\|Startup"

# Alle Pods mit fehlgeschlagenen Probes
kubectl get events -n production --field-selector reason=Unhealthy

Die drei Probe-Typen im Ueberblick

ProbeFrageAktion bei FehlerWann setzen?
ReadinessKann der Pod Traffic verarbeiten?Pod wird aus Service Endpoints entferntImmer (bei Services)
LivenessLebt der Container noch?Container wird neugestartetNur bei Deadlock-Gefahr
StartupHat der Container erfolgreich gestartet?Container wird neugestartetBei langsamem Start (>5s)

Die Reihenfolge beim Pod-Start: Zuerst muss der Startup Probe erfolgreich sein. Erst dann werden Liveness und Readiness Probe aktiv.

Readiness Probe: Traffic-Steuerung

Der Readiness Probe bestimmt, ob ein Pod in die Endpoints eines Services aufgenommen wird. Solange der Probe fehlschlaegt, bekommt der Pod keinen Traffic.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-api
  template:
    metadata:
      labels:
        app: web-api
    spec:
      containers:
      - name: api
        image: myapi:3.2
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /healthz/ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 3

Was der /healthz/ready Endpoint pruefen sollte:

  • Datenbankverbindung verfuegbar
  • Cache aufgewaermt (falls noetig)
  • Abhaengige Services erreichbar

Was er nicht pruefen sollte:

  • Komplexe Business-Logik
  • Externe APIs, die ausfallen koennen (sonst kaskadieren Ausfaelle)

Liveness Probe: Neustart bei Deadlock

Der Liveness Probe erkennt, ob ein Container in einem unwiederherstellbaren Zustand feststeckt -- etwa ein Deadlock oder eine blockierte Event-Loop. Bei Fehlschlag startet Kubernetes den Container neu.

        livenessProbe:
          httpGet:
            path: /healthz/live
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
          timeoutSeconds: 5
          failureThreshold: 3

Entscheidend: Der Liveness Endpoint sollte nur pruefen, ob der Prozess grundsaetzlich reagiert -- nicht, ob Abhaengigkeiten verfuegbar sind. Ein Liveness Probe, der die Datenbank prueft, startet den Container bei jedem DB-Ausfall neu. Das macht alles schlimmer.

# Guter Liveness Endpoint (Python/Flask)
@app.route('/healthz/live')
def liveness():
    return 'ok', 200

# Guter Readiness Endpoint
@app.route('/healthz/ready')
def readiness():
    if not db.is_connected():
        return 'database unavailable', 503
    return 'ok', 200

Startup Probe: Schutz beim Hochfahren

Java-Anwendungen, .NET-Services oder Anwendungen mit grossen Caches brauchen beim Start oft 30-120 Sekunden. Ohne Startup Probe muessten Sie initialDelaySeconds beim Liveness Probe sehr hoch setzen -- was die Erkennung von Deadlocks im laufenden Betrieb verzoegert.

Der Startup Probe loest dieses Problem elegant:

        startupProbe:
          httpGet:
            path: /healthz/live
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
          failureThreshold: 30    # 30 x 10s = 300s maximale Startzeit

Solange der Startup Probe laeuft, sind Liveness und Readiness Probe deaktiviert. Sobald der Startup Probe einmal erfolgreich ist, wird er deaktiviert und die anderen Probes uebernehmen.

Probe-Methoden: HTTP, TCP, exec, gRPC

Nicht jede Anwendung bietet einen HTTP-Endpoint. Kubernetes unterstuetzt vier Methoden:

HTTP GET (Standard fuer Web-Anwendungen)

readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
    httpHeaders:
    - name: Accept
      value: application/json

TCP Socket (fuer Datenbanken, Message Broker)

readinessProbe:
  tcpSocket:
    port: 5432     # Prüft nur, ob der Port offen ist

exec (fuer CLI-basierte Pruefungen)

readinessProbe:
  exec:
    command:
    - sh
    - -c
    - pg_isready -U postgres -h localhost

gRPC (seit Kubernetes 1.27 stabil)

readinessProbe:
  grpc:
    port: 50051
    service: myservice.health

Die fuenf haeufigsten Fehler

1. Gleicher Endpoint fuer Liveness und Readiness

Das ist der verbreitetste Fehler. Wenn der Readiness-Check eine Datenbankverbindung prueft und Sie denselben Endpoint als Liveness Probe nutzen, wird der Container bei jedem DB-Ausfall neugestartet. Neustarts helfen aber nicht gegen einen Datenbankausfall.

2. Zu aggressive Liveness Probes

# SCHLECHT: Container wird bei kurzer Last getoetet
livenessProbe:
  periodSeconds: 3
  timeoutSeconds: 1
  failureThreshold: 1    # Ein Timeout = Neustart!
# BESSER: Tolerant gegenueber kurzen Lastspitzen
livenessProbe:
  periodSeconds: 15
  timeoutSeconds: 5
  failureThreshold: 3    # 3 Fehlversuche = 45s bis Neustart

3. Kein Startup Probe bei langsam startenden Apps

Ohne Startup Probe und mit niedrigem initialDelaySeconds toetet der Liveness Probe den Container, bevor er fertig gestartet ist. Das erzeugt eine CrashLoopBackOff-Schleife.

4. Readiness Probe prueft externe Abhaengigkeiten

Wenn Ihr Readiness Probe einen externen Service prueft und dieser ausfaellt, werden alle Pods gleichzeitig aus dem Service entfernt. Pruefen Sie nur Abhaengigkeiten, die der Pod tatsaechlich zum Verarbeiten von Requests braucht.

5. initialDelaySeconds statt Startup Probe

initialDelaySeconds ist ein fester Wert. Ihre Anwendung startet mal in 10 Sekunden, mal in 60. Der Startup Probe passt sich an: Er wartet, bis die Anwendung bereit ist, maximal bis zum Timeout.

Vollstaendiges Beispiel: Java Spring Boot

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-api
  template:
    metadata:
      labels:
        app: spring-api
    spec:
      containers:
      - name: api
        image: spring-api:4.1
        ports:
        - containerPort: 8080
        startupProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
          failureThreshold: 36   # Max 3 Minuten Startzeit
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          periodSeconds: 15
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3

Spring Boot bietet seit Version 2.3 native Kubernetes-Health-Groups (/actuator/health/liveness und /actuator/health/readiness), die genau fuer diesen Einsatz konzipiert sind.

FAQ

Braucht jeder Pod alle drei Probes?

Nein. Readiness Probes sind fuer alle Pods sinnvoll, die Traffic von einem Service bekommen. Liveness Probes nur, wenn die Anwendung in Deadlocks geraten kann. Startup Probes nur bei langsamem Start (>5-10 Sekunden).

Was passiert, wenn kein Readiness Probe gesetzt ist?

Kubernetes nimmt an, der Pod ist sofort ready, sobald der Container laeuft. Bei Anwendungen mit Startup-Phase bekommen Clients Fehler, weil Traffic zu einem noch nicht bereiten Pod geroutet wird.

Wie finde ich heraus, ob meine Probes zu aggressiv sind?

Pruefen Sie die Restart-Count Ihrer Pods: kubectl get pods -n production. Viele Restarts bei ansonsten funktionierenden Pods deuten auf zu aggressive Liveness Probes hin. Schauen Sie sich die Events an: kubectl describe pod <name>.

Kann ich Probes zur Laufzeit aendern?

Nein, Probe-Konfigurationen sind Teil der Pod-Spec und unveraenderlich. Sie muessen ein neues Deployment ausrollen, um Probes anzupassen.


Empfehlung: Starten Sie mit einem Readiness Probe fuer alle Services. Fuegen Sie Liveness Probes nur dort hinzu, wo Sie wissen, dass die Anwendung haengen kann. Und setzen Sie Startup Probes fuer alles, was laenger als 5 Sekunden zum Starten braucht.


Weiterführende Artikel:

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