Configurar los tiempos de espera de las sondas de ejecución antes de actualizar a la versión 1.35 de GKE


En esta página se describe cómo preparar las sondas de vivacidad (liveness), preparación (readiness) e inicio (startup) antes de actualizar los clústeres de Google Kubernetes Engine (GKE) a la versión 1.35 o posterior. Para ello, debes definir los tiempos de espera de los comandos de estas sondas.

Acerca de los tiempos de espera de las sondas de ejecución

A partir de la versión 1.35 de GKE, Kubernetes aplica tiempos de espera a los comandos del campo exec de las sondas de vivacidad (liveness), preparación (readiness) e inicio (startup). El campo timeoutSeconds de la especificación de una sonda define cuánto tiempo espera Kubernetes a que una sonda complete las acciones. Si omite este campo, el valor predeterminado es 1, lo que significa que las acciones tienen un segundo para completarse.

En las versiones de GKE anteriores a la 1.35, Kubernetes ignora el valor del campo timeoutSeconds de los comandos de las sondas de ejecución. Por ejemplo, supongamos que tienes una sonda de actividad con las siguientes propiedades:

  • El valor 5 en el campo timeoutSeconds.
  • Un comando en el campo exec.command que tarda 10 segundos en completarse.

En versiones anteriores a la 1.35, Kubernetes ignora este tiempo de espera de cinco segundos e informa incorrectamente de que la sonda se ha completado correctamente. En la versión 1.35 y posteriores, Kubernetes falla correctamente la sonda después de cinco segundos.

Este comportamiento, en el que Kubernetes ignora los tiempos de espera de las comprobaciones de ejecución, puede provocar que las comprobaciones se ejecuten indefinidamente, lo que podría ocultar problemas con tus aplicaciones o provocar un comportamiento impredecible. En GKE 1.35 y versiones posteriores, Kubernetes aplica correctamente los tiempos de espera de los comandos, lo que da como resultado un comportamiento de las sondas coherente y predecible que se ajusta a Kubernetes de código abierto.

Impacto de aplicar tiempos de espera en las sondas de ejecución

Este es un cambio incompatible en la versión 1.35 y posteriores de GKE que es necesario para la estabilidad y fiabilidad de las cargas de trabajo que se ejecutan en GKE. Cuando actualices tus clústeres a la versión 1.35 o posterior, es posible que observes un comportamiento inesperado en las cargas de trabajo si estas tienen sondas de ejecución con una de las siguientes propiedades:

  • Omite el campo timeoutSeconds: en la versión 1.35 y posteriores, estas sondas tienen un segundo para completar los comandos correctamente. Si el comando no se completa correctamente en un segundo, las sondas informarán de los errores correctamente.
  • Especifica periodos de tiempo de espera cortos: en la versión 1.35 y posteriores, las sondas con un periodo de tiempo de espera más corto que el tiempo de finalización del comando informarán correctamente de los fallos.

En GKE 1.34 y versiones anteriores, Kubernetes informa de un error en las sondas de ejecución que cumplen alguna de estas condiciones. Sin embargo, los comandos de estas comprobaciones de ejecución pueden seguir ejecutándose hasta completarse, ya que el error de la comprobación no es un fallo de la comprobación.

Si no especificas una duración de tiempo de espera más precisa y los comandos tardan más en completarse que el periodo de tiempo de espera actual, tus sondas informarán de errores en la versión 1.35 y posteriores. En función del tipo de prueba, se aplicará el siguiente comportamiento cuando falle una prueba:

  • Sondas de vivacidad: si una sonda de vivacidad falla porque se ha agotado el tiempo de espera de un comando, Kubernetes asume que la aplicación ha fallado y reinicia el contenedor. Si la sonda falla repetidamente, es posible que tus pods se queden atascados en un bucle de fallos con el estado CrashLoopBackOff.
  • Comprobaciones de preparación: si una comprobación de preparación falla porque se ha agotado el tiempo de espera de un comando, Kubernetes actualiza la condición Ready del pod con el estado False. Kubernetes no envía tráfico al Pod hasta que la sonda se completa correctamente. Si todos los pods que respaldan un servicio tienen el estado False en la condición Ready, es posible que observes interrupciones en el servicio.
  • Sondas de inicio: si una sonda de inicio falla, Kubernetes asume que la aplicación no se ha iniciado y reinicia el contenedor. Si la sonda falla repetidamente, es posible que tus pods se queden bloqueados en un bucle de fallos con el estado CrashLoopBackOff.

Actualizaciones automáticas pausadas

GKE pausa las actualizaciones automáticas a la versión 1.35 cuando detecta que las cargas de trabajo de un clúster pueden verse afectadas por este cambio. GKE reanuda las actualizaciones automáticas si la versión 1.35 es el destino de la actualización automática de tu plano de control y tus nodos, y si se cumple una de las siguientes condiciones:

  • Has actualizado las sondas de carga de trabajo con valores de tiempo de espera y GKE no ha detectado posibles problemas durante siete días.
  • La versión 1.34 llega al final del periodo de asistencia en tu canal de lanzamiento.

Identifica los clústeres o las cargas de trabajo afectados

En las siguientes secciones se explica cómo identificar los clústeres o las cargas de trabajo que podrían verse afectados por este cambio.

Consultar eventos de Kubernetes mediante la línea de comandos

En la versión 1.34 de GKE y versiones anteriores, puedes inspeccionar manualmente los eventos de Kubernetes de tus clústeres para encontrar sondas de ejecución que tarden más en completarse que el periodo de tiempo de espera actual. Kubernetes añade un evento con un mensaje command timed out para estas sondas. Este método es útil para identificar cargas de trabajo que ya tienen problemas debido a valores de tiempo de espera cortos.

Para encontrar las cargas de trabajo afectadas, haz una de las siguientes acciones:

Buscar cargas de trabajo en varios clústeres mediante una secuencia de comandos

La siguiente secuencia de comandos de bash itera en todos los clústeres que se encuentran en tu archivo kubeconfig para encontrar las cargas de trabajo afectadas. Esta secuencia de comandos comprueba si hay errores de tiempo de espera de la comprobación de ejecución en todos los contextos de Kubernetes existentes y accesibles, y escribe los resultados en un archivo de texto llamado affected_workloads_report.txt. Para ejecutar esta secuencia de comandos, sigue estos pasos:

  1. Guarda la siguiente secuencia de comandos como 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. Ejecuta la secuencia de comandos:

    bash execprobe-timeouts.sh
    
  3. Lee el contenido del archivo affected_workloads_report.txt:

    cat affected_workloads_report.txt
    

    El resultado debería ser similar al siguiente:

    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
    

Buscar cargas de trabajo en clústeres específicos mediante la línea de comandos

Para identificar las cargas de trabajo afectadas en clústeres específicos, puedes usar la kubectl herramienta para comprobar si hay errores de tiempo de espera de la sonda de ejecución. Sigue estos pasos en todos los clústeres de GKE que ejecuten la versión 1.34 o una anterior:

  1. Conéctate al clúster:

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

    Haz los cambios siguientes:

    • CLUSTER_NAME: el nombre del clúster.
    • LOCATION: la ubicación del plano de control del clúster, como us-central1.
  2. Busca eventos que indiquen que una sonda de ejecución tiene un error de tiempo de espera:

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

    Este comando ignora las cargas de trabajo de muchos espacios de nombres del sistema. Si hay cargas de trabajo afectadas, el resultado será similar al siguiente:

    Pod/liveness1-exec      Namespace: default
    
  3. Repita los pasos anteriores con cada clúster que ejecute versiones de GKE anteriores a la 1.35.

Buscar clústeres y cargas de trabajo afectados en Cloud Logging

  1. En la Google Cloud consola, ve a la página Explorador de registros.

    Ir a Explorador de registros

  2. Para abrir el editor de consultas, haz clic en el interruptor Mostrar consulta.

  3. Ejecuta la siguiente consulta:

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

    El resultado es una lista de errores de sondeo causados por comandos que han tardado más en completarse que el periodo de tiempo de espera configurado.

Actualizar las cargas de trabajo afectadas antes de actualizar a la versión 1.35

Una vez que haya identificado las cargas de trabajo afectadas, deberá actualizar las sondas afectadas.

  1. Revisa las sondas de vivacidad, preparación e inicio de cada pod afectado y determina un valor de timeoutSeconds adecuado. Este valor debe ser lo suficientemente largo para que el comando se ejecute correctamente en condiciones normales. Para obtener más información, consulta Configurar sondas de vivacidad, preparación e inicio.
  2. Abre el archivo de manifiesto de la carga de trabajo afectada y añade o modifica el campo timeoutSeconds de las sondas de vivacidad, preparación o inicio. Por ejemplo, la siguiente prueba de actividad tiene el valor 10 en el campo timeoutSeconds:

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. Aplica el manifiesto actualizado a tu clúster.

  4. Para comprobar si hay errores en las sondas actualizadas, sigue los pasos que se indican en Comprobar eventos de Kubernetes mediante la línea de comandos.

Una vez que hayas actualizado y probado todas las cargas de trabajo afectadas, podrás actualizar tu clúster a la versión 1.35 de GKE.