Configurer les délais d'expiration des sondes exec avant la mise à niveau vers la version 1.35 de GKE


Cette page explique comment préparer vos sondes de liveness, de readiness et de démarrage avant de mettre à niveau vos clusters Google Kubernetes Engine (GKE) vers la version 1.35 ou ultérieure en définissant des délais d'attente pour les commandes de ces sondes.

À propos des délais d'expiration pour les vérifications d'exécution

À partir de la version 1.35 de GKE, Kubernetes applique des délais avant expiration aux commandes du champ exec des vérifications d'activité, d'aptitude et de démarrage. Le champ timeoutSeconds de la spécification d'une vérification définit la durée pendant laquelle Kubernetes attend qu'une vérification termine ses actions. Si vous omettez ce champ, la valeur par défaut est 1, ce qui signifie que toutes les actions ont une seconde pour se terminer.

Dans les versions de GKE antérieures à la version 1.35, Kubernetes ignore la valeur du champ timeoutSeconds pour les commandes de sonde d'exécution. Prenons l'exemple d'une vérification de l'état qui présente les propriétés suivantes :

  • Une valeur de 5 dans le champ timeoutSeconds.
  • Une commande dans le champ exec.command qui prend 10 secondes à s'exécuter.

Dans les versions antérieures à 1.35, Kubernetes ignore ce délai de cinq secondes et signale à tort que le test a réussi. Dans la version 1.35 et les versions ultérieures, Kubernetes échoue correctement la vérification après cinq secondes.

Ce comportement, dans lequel Kubernetes ignore les délais d'expiration des sondes d'exécution, peut entraîner des sondes qui s'exécutent indéfiniment, ce qui peut masquer des problèmes avec vos applications ou entraîner un comportement imprévisible. Dans GKE version 1.35 et ultérieures, Kubernetes applique correctement les délais d'expiration des commandes, ce qui entraîne un comportement cohérent et prévisible des sondes, conforme à Kubernetes Open Source.

Impact de l'application des délais avant expiration pour les vérifications d'exécution

Il s'agit d'un changement incompatible dans GKE 1.35 et versions ultérieures, nécessaire à la stabilité et à la fiabilité des charges de travail exécutées sur GKE. Lorsque vous mettez à niveau vos clusters vers la version 1.35 ou ultérieure, vous pouvez constater un comportement inattendu des charges de travail si elles comportent des sondes d'exécution avec l'une des propriétés suivantes :

  • Omettez le champ timeoutSeconds : dans la version 1.35 et les versions ultérieures, ces vérifications disposent d'une seconde pour exécuter les commandes. Si la commande ne s'exécute pas correctement en une seconde, les vérifications signaleront correctement les échecs.
  • Spécifiez des délais d'attente courts : dans la version 1.35 et les versions ultérieures, les vérifications avec un délai d'attente plus court que le temps d'exécution de la commande signaleront correctement les échecs.

Dans la version 1.34 de GKE et les versions antérieures, Kubernetes signale une erreur dans les vérifications exec qui remplissent l'une de ces conditions. Toutefois, les commandes de ces sondes d'exécution peuvent toujours s'exécuter jusqu'à la fin, car l'erreur de sonde n'est pas un échec de sonde.

Si vous ne spécifiez pas de délai avant expiration plus précis et que les commandes mettent plus de temps que le délai avant expiration existant pour s'exécuter, vos vérifications signaleront des échecs dans la version 1.35 et les versions ultérieures. Selon le type de vérification, le comportement suivant s'applique en cas d'échec :

  • Vérifications d'activité : si une vérification d'activité échoue en raison d'un délai d'attente dépassé pour une commande, Kubernetes suppose que l'application a échoué et redémarre le conteneur. Si la sonde échoue à plusieurs reprises, vos pods peuvent se retrouver bloqués dans une boucle de plantage avec un état de pod CrashLoopBackOff.
  • Vérifications d'aptitude : si une vérification d'aptitude échoue en raison d'un délai d'attente dépassé pour une commande, Kubernetes met à jour la condition du pod Ready avec un état False. Kubernetes n'envoie aucun trafic au pod tant que la vérification n'a pas réussi. Si tous les pods qui soutiennent un service ont un état False pour la condition Ready, vous pouvez remarquer des perturbations du service.
  • Vérifications de démarrage : si une vérification de démarrage échoue, Kubernetes suppose que l'application n'a pas démarré et redémarre le conteneur. Si la sonde échoue à plusieurs reprises, vos pods peuvent se retrouver bloqués dans une boucle de plantage avec un état de pod CrashLoopBackOff.

Mises à niveau automatiques suspendues

GKE suspend les mises à niveau automatiques vers la version 1.35 lorsqu'il détecte que les charges de travail d'un cluster peuvent être affectées par ce changement. GKE reprend les mises à niveau automatiques si la version 1.35 est une cible de mise à niveau automatique pour votre plan de contrôle et vos nœuds, et si l'une des conditions suivantes est remplie :

  • Vous avez mis à jour les vérifications de votre charge de travail avec des valeurs de délai avant expiration et GKE n'a détecté aucun problème potentiel depuis sept jours.
  • La version 1.34 arrive en fin de vie dans votre canal de publication.

Identifier les clusters ou charges de travail concernés

Les sections suivantes vous expliquent comment identifier les clusters ou les charges de travail qui pourraient être affectés par ce changement.

Vérifier les événements Kubernetes à l'aide de la ligne de commande

Dans GKE 1.34 et versions antérieures, vous pouvez inspecter manuellement les événements Kubernetes dans vos clusters pour trouver les sondes d'exécution qui mettent plus de temps à se terminer que le délai d'attente existant. Kubernetes ajoute un événement avec un message command timed out pour ces vérifications. Cette méthode est utile pour identifier les charges de travail qui rencontrent déjà des problèmes en raison de valeurs de délai d'attente courtes.

Pour trouver les charges de travail concernées, effectuez l'une des opérations suivantes :

Rechercher des charges de travail dans plusieurs clusters à l'aide d'un script

Le script bash suivant effectue une itération sur tous les clusters de votre fichier kubeconfig pour trouver les charges de travail concernées. Ce script recherche les erreurs de délai avant expiration de la sonde d'exécution dans tous les contextes Kubernetes existants et accessibles, et écrit les résultats dans un fichier texte nommé affected_workloads_report.txt. Pour exécuter ce script, procédez comme suit :

  1. Enregistrez le script suivant sous le nom 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. Exécutez le script :

    bash execprobe-timeouts.sh
    
  3. Lisez le contenu du fichier affected_workloads_report.txt :

    cat affected_workloads_report.txt
    

    Le résultat ressemble à ce qui suit :

    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
    

Rechercher des charges de travail dans des clusters spécifiques à l'aide de la ligne de commande

Pour identifier les charges de travail concernées dans des clusters spécifiques, vous pouvez utiliser l'outil kubectl pour rechercher les erreurs de délai avant expiration de la sonde d'exécution. Procédez comme suit pour chaque cluster GKE exécutant la version 1.34 ou antérieure :

  1. Connectez-vous au cluster :

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

    Remplacez les éléments suivants :

    • CLUSTER_NAME : nom du cluster.
    • LOCATION : emplacement du plan de contrôle du cluster, tel que us-central1.
  2. Recherchez les événements indiquant qu'une sonde d'exécution a rencontré une erreur de délai d'attente :

    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)"'
    

    Cette commande ignore les charges de travail dans de nombreux espaces de noms système. Si des charges de travail concernées existent, le résultat est semblable à ce qui suit :

    Pod/liveness1-exec      Namespace: default
    
  3. Répétez les étapes précédentes pour chaque cluster exécutant des versions de GKE antérieures à 1.35.

Identifier les clusters et les charges de travail concernés dans Cloud Logging

  1. Dans la console Google Cloud , accédez à la page Explorateur de journaux.

    Accéder à l'explorateur de journaux

  2. Pour ouvrir l'éditeur de requête, cliquez sur le bouton Afficher la requête.

  3. Exécutez la requête suivante :

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

    La sortie est une liste des erreurs de sonde causées par des commandes qui ont mis plus de temps à s'exécuter que la période de délai avant expiration configurée.

Mettre à jour les charges de travail concernées avant de passer à la version 1.35

Après avoir identifié les charges de travail concernées, vous devez mettre à jour les sondes concernées.

  1. Examinez les vérifications d'activité, d'aptitude et de démarrage pour chaque pod concerné, puis déterminez une valeur timeoutSeconds appropriée. Cette valeur doit être suffisamment longue pour que la commande s'exécute correctement dans des conditions normales. Pour en savoir plus, consultez Configurer des vérifications d'activité, d'aptitude et de démarrage.
  2. Ouvrez le fichier manifeste de la charge de travail concernée, puis ajoutez ou modifiez le champ timeoutSeconds pour les sondes de vivacité, de disponibilité ou de démarrage. Par exemple, la sonde de vivacité suivante a la valeur 10 dans le champ timeoutSeconds :

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. Appliquez le fichier manifeste mis à jour à votre cluster.

  4. Recherchez les erreurs dans les sondes mises à jour en suivant la procédure décrite dans Vérifier les événements Kubernetes à l'aide de la ligne de commande.

Une fois que vous avez mis à jour et testé toutes les charges de travail concernées, vous pouvez mettre à niveau votre cluster vers la version 1.35 de GKE.