Timeouts für Exec-Probes konfigurieren, bevor Sie ein Upgrade auf GKE-Version 1.35 durchführen


Auf dieser Seite wird beschrieben, wie Sie Ihre Liveness-, Readiness- und Startup-Probes vorbereiten, bevor Sie Ihre Google Kubernetes Engine-Cluster (GKE) auf Version 1.35 und höher aktualisieren. Dazu legen Sie Zeitüberschreitungen für Befehle in diesen Probes fest.

Zeitlimits für Exec-Prüfungen

Ab GKE-Version 1.35 erzwingt Kubernetes Zeitüberschreitungen für Befehle im Feld exec von Aktivitäts-, Bereitschafts- und Startprüfungen. Das Feld timeoutSeconds in der Spezifikation einer Probe definiert, wie lange Kubernetes wartet, bis eine Probe alle Aktionen abgeschlossen hat. Wenn Sie dieses Feld weglassen, ist der Standardwert 1. Das bedeutet, dass für alle Aktionen eine Sekunde Zeit ist.

In GKE-Versionen vor 1.35 ignoriert Kubernetes den Wert im Feld timeoutSeconds für exec-Probe-Befehle. Betrachten Sie beispielsweise einen Liveness-Probe mit den folgenden Eigenschaften:

  • Ein Wert von 5 im Feld timeoutSeconds.
  • Ein Befehl im Feld exec.command, der 10 Sekunden dauert.

In Versionen vor 1.35 ignoriert Kubernetes dieses Zeitlimit von fünf Sekunden und meldet die Probe fälschlicherweise als erfolgreich. In Version 1.35 und höher schlägt der Probe nach fünf Sekunden fehl.

Dieses Verhalten, bei dem Kubernetes Zeitüberschreitungen für Exec-Probes ignoriert, kann dazu führen, dass Probes unbegrenzt ausgeführt werden. Dadurch werden möglicherweise Probleme mit Ihren Anwendungen verborgen oder es kann zu unvorhersehbarem Verhalten kommen. In GKE-Version 1.35 und höher erzwingt Kubernetes Zeitüberschreitungen für Befehle korrekt. Dies führt zu einem konsistenten, vorhersagbaren Probeverhalten, das mit Open-Source-Kubernetes übereinstimmt.

Auswirkungen der Erzwingung von Zeitlimits für Exec-Prüfungen

Dies ist eine wichtige Änderung in GKE-Version 1.35 und höher, die für die Stabilität und Zuverlässigkeit von Arbeitslasten, die in GKE ausgeführt werden, erforderlich ist. Wenn Sie Ihre Cluster auf Version 1.35 und höher aktualisieren, kann es zu unerwartetem Arbeitslastverhalten kommen, wenn die Arbeitslasten Ausführungstests mit einer der folgenden Eigenschaften haben:

  • Feld timeoutSeconds weglassen: In Version 1.35 und höher haben diese Probes eine Sekunde Zeit, um Befehle erfolgreich auszuführen. Wenn der Befehl nicht innerhalb einer Sekunde erfolgreich abgeschlossen wird, melden die Probes Fehler.
  • Kurze Zeitüberschreitungen angeben: In Version 1.35 und höher werden Fehler bei Tests mit einer kürzeren Zeitüberschreitung als die Zeit für den Abschluss des Befehls korrekt gemeldet.

In GKE-Version 1.34 und früher meldet Kubernetes einen Fehler in Exec-Probes, die eine dieser Bedingungen erfüllen. Die Befehle in diesen Exec-Probes können jedoch weiterhin vollständig ausgeführt werden, da der Probe-Fehler kein Probe-Fehler ist.

Wenn Sie keine genauere Zeitüberschreitungsdauer angeben und die Ausführung der Befehle länger dauert als der vorhandene Zeitraum für Zeitüberschreitungen, werden in Version 1.35 und höher Fehler für Ihre Tests gemeldet. Je nach Art der Prüfung gilt das folgende Verhalten, wenn eine Prüfung fehlschlägt:

  • Aktivitätsprüfungen: Wenn eine Aktivitätsprüfung fehlschlägt, weil für einen Befehl das Zeitlimit überschritten wurde, geht Kubernetes davon aus, dass die Anwendung fehlgeschlagen ist, und startet den Container neu. Wenn die Prüfung wiederholt fehlschlägt, bleiben Ihre Pods möglicherweise in einer Absturzschleife mit dem Pod-Status CrashLoopBackOff hängen.
  • Bereitschaftsprüfungen: Wenn eine Bereitschaftsprüfung fehlschlägt, weil ein Befehl das Zeitlimit überschritten hat, aktualisiert Kubernetes die Pod-Bedingung Ready mit dem Status False. Kubernetes sendet erst dann Traffic an den Pod, wenn die Prüfung erfolgreich ist. Wenn alle Pods, die einen Dienst unterstützen, für die Bedingung Ready den Status False haben, kann es zu Unterbrechungen des Dienstes kommen.
  • Startprüfungen: Wenn eine Startprüfung fehlschlägt, geht Kubernetes davon aus, dass die Anwendung nicht gestartet werden konnte, und startet den Container neu. Wenn die Probe wiederholt fehlschlägt, bleiben Ihre Pods möglicherweise in einer Absturzschleife mit dem Pod-Status CrashLoopBackOff hängen.

Pausierte automatische Upgrades

GKE pausiert automatische Upgrades auf Version 1.35, wenn erkannt wird, dass die Arbeitslasten in einem Cluster von dieser Änderung betroffen sein könnten. GKE setzt automatische Upgrades fort, wenn Version 1.35 ein Ziel für automatische Upgrades für Ihre Steuerungsebene und Knoten ist und eine der folgenden Bedingungen erfüllt ist:

  • Sie haben Ihre Arbeitslast-Probes mit Zeitüberschreitungswerten aktualisiert und GKE hat seit sieben Tagen keine potenziellen Probleme erkannt.
  • Version 1.34 erreicht das Ende des Supports in Ihrem Release Channel.

Betroffene Cluster oder Arbeitslasten identifizieren

In den folgenden Abschnitten erfahren Sie, wie Sie Cluster oder Arbeitslasten identifizieren, die von dieser Änderung betroffen sein könnten.

Kubernetes-Ereignisse über die Befehlszeile prüfen

In GKE-Version 1.34 und früher können Sie die Kubernetes-Ereignisse in Ihren Clustern manuell prüfen, um exec-Probes zu finden, deren Ausführung länger dauert als der vorhandene Zeitüberschreitungszeitraum. Kubernetes fügt für diese Prüfungen ein Ereignis mit einer command timed out-Meldung hinzu. Diese Methode ist nützlich, um Arbeitslasten zu identifizieren, bei denen aufgrund kurzer Zeitüberschreitungswerte bereits Probleme auftreten.

Führen Sie einen der folgenden Schritte aus, um betroffene Arbeitslasten zu finden:

Arbeitslasten in mehreren Clustern mithilfe eines Skripts finden

Das folgende Bash-Skript durchläuft alle Cluster in Ihrer kubeconfig-Datei, um betroffene Arbeitslasten zu finden. Dieses Skript sucht in allen vorhandenen und erreichbaren Kubernetes-Kontexten nach Zeitüberschreitungsfehlern bei Exec-Probes und schreibt die Ergebnisse in eine Textdatei mit dem Namen affected_workloads_report.txt. So führen Sie dieses Skript aus:

  1. Speichern Sie das folgende Skript als execprobe-timeouts.sh:

    #!/bin/bash
    
    # This script checks for exec probe timeouts across all existing and reachable
    # Kubernetes contexts and writes the findings to a text file, with one
    # row for each affected workload, including its cluster name.
    
    # --- Configuration ---
    OUTPUT_FILE="affected_workloads_report.txt"
    # -------------------
    
    # Check if kubectl and jq are installed
    if ! command -v kubectl &> /dev/null || ! command -v jq &> /dev/null; then
        echo "Error: kubectl and jq are required to run this script." >&2
        exit 1
    fi
    
    echo "Fetching all contexts from your kubeconfig..."
    
    # Initialize the report file with a formatted header
    printf "%-40s | %s\n" "Cluster Context" "Impacted Workload" > "$OUTPUT_FILE"
    
    # Get all context names from the kubeconfig file
    CONTEXTS=$(kubectl config get-contexts -o name)
    
    if [[ -z "$CONTEXTS" ]]; then
      echo "No Kubernetes contexts found in your kubeconfig file."
      exit 0
    fi
    
    echo "Verifying each context and checking for probe timeouts..."
    echo "=================================================="
    
    # Loop through each context
    for CONTEXT in $CONTEXTS; do
      echo "--- Checking context: $CONTEXT ---"
    
      # Check if the cluster is reachable by running a lightweight command
      if kubectl --context="$CONTEXT" get ns --request-timeout=1s > /dev/null 2>&1; then
        echo "Context '$CONTEXT' is reachable. Checking for timeouts..."
    
        # Find timeout events based on the logic from the documentation
        AFFECTED_WORKLOADS_LIST=$(kubectl --context="$CONTEXT" get events --all-namespaces -o json | jq -r '.items[] | select((.involvedObject.namespace | type == "string") and (.involvedObject.namespace | endswith("-system") | not) and (.message | test("^(Liveness|Readiness|Startup) probe errored(.*): command timed out(.*)|^ * probe errored and resulted in .* state: command timed out.*"))) | .involvedObject.kind + "/" + .involvedObject.name' | uniq)
    
        if [[ -n "$AFFECTED_WORKLOADS_LIST" ]]; then
          echo "Found potentially affected workloads in context '$CONTEXT'."
    
          # Loop through each affected workload and write a new row to the report
          # pairing the context with the workload.
          while IFS= read -r WORKLOAD; do
            printf "%-40s | %s\n" "$CONTEXT" "$WORKLOAD" >> "$OUTPUT_FILE"
          done <<< "$AFFECTED_WORKLOADS_LIST"
        else
          echo "No workloads with exec probe timeouts found in context '$CONTEXT'."
        fi
      else
        echo "Context '$CONTEXT' is not reachable or the cluster does not exist. Skipping."
      fi
      echo "--------------------------------------------------"
    done
    
    echo "=================================================="
    echo "Script finished."
    echo "A detailed report of affected workloads has been saved to: $OUTPUT_FILE"
    
  2. Führen Sie das Skript aus:

    bash execprobe-timeouts.sh
    
  3. Lesen Sie den Inhalt der Datei affected_workloads_report.txt:

    cat affected_workloads_report.txt
    

    Die Ausgabe sieht etwa so aus:

    Cluster Context                   | Impacted Workload
    -----------------------------------------|----------------------------
    gke_my-project_us-central1-c_cluster-1   | Pod/liveness1-exec
    gke_my-project_us-central1-c_cluster-1   | Deployment/another-buggy-app
    gke_my-project_us-east1-b_cluster-2      | Pod/startup-probe-test
    

Arbeitslasten in bestimmten Clustern über die Befehlszeile finden

Mit dem kubectl-Tool können Sie in bestimmten Clustern nach Zeitüberschreitungsfehlern bei Exec-Probes suchen, um betroffene Arbeitslasten zu identifizieren. Führen Sie die folgenden Schritte für jeden GKE-Cluster mit Version 1.34 oder früher aus:

  1. Als Nächstes stellen Sie die Verbindung zum Cluster her:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    

    Ersetzen Sie Folgendes:

    • CLUSTER_NAME ist der Name des Clusters.
    • LOCATION: Der Standort der Clustersteuerungsebene, z. B. us-central1.
  2. Suchen Sie nach Ereignissen, die darauf hinweisen, dass für eine Ausführungssonde ein Zeitüberschreitungsfehler aufgetreten ist:

    kubectl get events --all-namespaces -o json |
        jq -r '.items[] | select((.involvedObject.namespace | type == "string") and (.involvedObject.namespace | endswith("-system") | not) and (.message | test("^(Liveness|Readiness|Startup) probe errored(.*): command timed out(.*)|^ * probe errored and resulted in .* state: command timed out.*"))) | "\(.involvedObject.kind)/\(.involvedObject.name)        Namespace: \(.involvedObject.namespace)"'
    

    Mit diesem Befehl werden Arbeitslasten in vielen System-Namespaces ignoriert. Wenn betroffene Arbeitslasten vorhanden sind, sieht die Ausgabe in etwa so aus:

    Pod/liveness1-exec      Namespace: default
    
  3. Wiederholen Sie die vorherigen Schritte für jeden Cluster, in dem GKE-Versionen vor 1.35 ausgeführt werden.

Betroffene Cluster und Arbeitslasten in Cloud Logging finden

  1. Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf:

    Zum Log-Explorer

  2. Klicken Sie auf die Ein-/Aus-Schaltfläche Abfrage anzeigen, um den Abfrageeditor zu öffnen.

  3. Führen Sie die folgende Abfrage aus:

    jsonPayload.message=~" probe errored and resulted in .* state: command timed out" OR jsonPayload.message=~" probe errored : command timed out"
    

    Die Ausgabe ist eine Liste von Probe-Fehlern, die durch Befehle verursacht wurden, deren Ausführung länger als der konfigurierte Zeitüberschreitungszeitraum gedauert hat.

Betroffene Arbeitslasten aktualisieren, bevor Sie auf Version 1.35 upgraden

Nachdem Sie die betroffenen Arbeitslasten identifiziert haben, müssen Sie die betroffenen Probes aktualisieren.

  1. Sehen Sie sich die Aktivitäts-, Bereitschafts- und Startprüfungen für jeden betroffenen Pod an und legen Sie einen geeigneten timeoutSeconds-Wert fest. Dieser Wert sollte lang genug sein, damit der Befehl unter normalen Bedingungen erfolgreich ausgeführt werden kann. Weitere Informationen finden Sie unter Aktivitäts-, Bereitschafts- und Startprüfungen konfigurieren.
  2. Öffnen Sie die Manifestdatei für die betroffene Arbeitslast und fügen Sie das Feld timeoutSeconds für Liveness-, Readiness- oder Startup-Probes hinzu oder ändern Sie es. Die folgende Liveness-Probe hat beispielsweise den Wert 10 im Feld timeoutSeconds:

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. Wenden Sie das aktualisierte Manifest auf Ihren Cluster an.

  4. Prüfen Sie die aktualisierten Probes auf Fehler. Folgen Sie dazu der Anleitung unter Kubernetes-Ereignisse über die Befehlszeile prüfen.

Nachdem Sie alle betroffenen Arbeitslasten aktualisiert und getestet haben, können Sie Ihren Cluster auf GKE-Version 1.35 aktualisieren.