Configurar tempos limite da sondagem exec antes de fazer upgrade para a versão 1.35 do GKE


Nesta página, descrevemos como preparar as probes de atividade, prontidão e inicialização antes de fazer upgrade dos clusters do Google Kubernetes Engine (GKE) para a versão 1.35 e mais recentes definindo tempos limite para comandos nessas probes.

Sobre os tempos limite para sondagens exec

A partir da versão 1.35 do GKE, o Kubernetes aplica tempos limite para comandos no campo exec das sondagens de atividade, prontidão e inicialização. O campo timeoutSeconds na especificação de uma sondagem define por quanto tempo o Kubernetes aguarda a conclusão de ações. Se você omitir esse campo, o valor padrão será 1, o que significa que todas as ações têm um segundo para serem concluídas.

Em versões do GKE anteriores à 1.35, o Kubernetes ignora o valor no campo timeoutSeconds para comandos de sondagem exec. Por exemplo, considere uma sondagem de atividade com as seguintes propriedades:

  • Um valor de 5 no campo timeoutSeconds.
  • Um comando no campo exec.command que leva 10 segundos para ser concluído.

Em versões anteriores à 1.35, o Kubernetes ignora esse tempo limite de cinco segundos e informa incorretamente que a sondagem foi bem-sucedida. Na versão 1.35 e mais recentes, o Kubernetes falha na sondagem corretamente após cinco segundos.

Esse comportamento, em que o Kubernetes ignora os tempos limite da sondagem de execução, pode resultar em sondagens que são executadas indefinidamente, o que pode ocultar problemas com seus aplicativos ou causar um comportamento imprevisível. No GKE versão 1.35 e mais recente, o Kubernetes aplica corretamente os tempos limite de comando, o que resulta em um comportamento de sondagem consistente e previsível que se alinha ao Kubernetes de código aberto.

Impacto da aplicação de tempos limite para sondagens exec

Essa é uma mudança incompatível na versão 1.35 e mais recentes do GKE, necessária para a estabilidade e a confiabilidade das cargas de trabalho executadas no GKE. Ao fazer upgrade dos clusters para a versão 1.35 e mais recentes, você pode notar um comportamento inesperado da carga de trabalho se ela tiver sondagens exec com uma das seguintes propriedades:

  • Omitir o campo timeoutSeconds: na versão 1.35 e mais recentes, essas sondagens têm um segundo para concluir os comandos. Se o comando não for concluído em um segundo, as sondagens vão informar falhas corretamente.
  • Especifique períodos de tempo limite curtos: na versão 1.35 e mais recentes, sondagens com um período de tempo limite menor que o tempo de conclusão do comando vão informar falhas corretamente.

No GKE versão 1.34 e anteriores, o Kubernetes informa um erro em sondagens exec que atendem a uma destas condições. No entanto, os comandos nessas sondagens de execução ainda podem ser concluídos, porque o erro não é uma falha de sondagem.

Se você não especificar uma duração de tempo limite mais precisa e os comandos levarem mais tempo do que o período de tempo limite atual para serem concluídos, suas sondagens vão relatar falhas na versão 1.35 e mais recentes. Dependendo do tipo de sondagem, o comportamento a seguir se aplica quando uma sondagem falha:

  • Sondagens de atividade: se uma sondagem de atividade falhar porque um comando atingiu o tempo limite, o Kubernetes vai presumir que o aplicativo falhou e vai reiniciar o contêiner. Se a sondagem falhar repetidamente, seus pods poderão ficar presos em um loop de falha com um status de pod CrashLoopBackOff.
  • Sondagens de atividade: se uma sondagem de atividade falhar porque um comando atingiu o tempo limite, o Kubernetes vai atualizar a condição do pod Ready com um status False. O Kubernetes não envia tráfego para o pod até que a sondagem seja bem-sucedida. Se todos os pods que dão suporte a um serviço tiverem um status False para a condição Ready, você poderá notar interrupções no serviço.
  • Sondagens de inicialização: se uma sondagem de inicialização falhar, o Kubernetes vai presumir que o aplicativo não foi iniciado e vai reiniciar o contêiner. Se a sondagem falhar repetidamente, os pods poderão ficar presos em um loop de falha com um status CrashLoopBackOff.

Upgrades automáticos pausados

O GKE pausa os upgrades automáticos para a versão 1.35 quando detecta que as cargas de trabalho em um cluster podem ser afetadas por essa mudança. O GKE retoma os upgrades automáticos se a versão 1.35 for um destino de upgrade automático para seu plano de controle e nós, e se uma das seguintes condições for atendida:

  • Você atualizou as sondagens de carga de trabalho com valores de tempo limite, e o GKE não detectou possíveis problemas por sete dias.
  • A versão 1.34 vai atingir o fim do suporte no seu canal de lançamento.

Identificar clusters ou cargas de trabalho afetados

As seções a seguir mostram como identificar clusters ou cargas de trabalho que podem ser afetados por essa mudança.

Verificar eventos do Kubernetes usando a linha de comando

No GKE versão 1.34 e anteriores, é possível inspecionar manualmente os eventos do Kubernetes nos clusters para encontrar sondagens de execução que levam mais tempo para serem concluídas do que o período de tempo limite atual. O Kubernetes adiciona um evento com uma mensagem command timed out para essas sondagens. Esse método é útil para identificar cargas de trabalho que já estão apresentando problemas devido a valores de tempo limite curtos.

Para encontrar cargas de trabalho afetadas, faça o seguinte:

Encontrar cargas de trabalho em vários clusters usando um script

O script bash a seguir faz iterações em todos os clusters no seu arquivo kubeconfig para encontrar cargas de trabalho afetadas. Esse script verifica erros de tempo limite da sondagem de execução em todos os contextos do Kubernetes existentes e acessíveis e grava as descobertas em um arquivo de texto chamado affected_workloads_report.txt. Para executar esse script, siga estas etapas:

  1. Salve o script a seguir 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. Execute o script:

    bash execprobe-timeouts.sh
    
  3. Leia o conteúdo do arquivo affected_workloads_report.txt:

    cat affected_workloads_report.txt
    

    O resultado será assim:

    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
    

Encontrar cargas de trabalho em clusters específicos usando a linha de comando

Para identificar cargas de trabalho afetadas em clusters específicos, use a ferramenta kubectl para verificar erros de tempo limite da sondagem de execução. Siga estas etapas para cada cluster do GKE que executa a versão 1.34 ou anterior:

  1. Conecte-se ao cluster:

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

    Substitua:

    • CLUSTER_NAME: o nome do cluster.
    • LOCATION: o local do plano de controle do cluster, como us-central1.
  2. Verifique se há eventos que indicam que uma sondagem de execução tem um erro de tempo limite:

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

    Esse comando ignora cargas de trabalho em muitos namespaces do sistema. Se houver cargas de trabalho afetadas, a saída será semelhante a esta:

    Pod/liveness1-exec      Namespace: default
    
  3. Repita as etapas anteriores para cada cluster que executa versões do GKE anteriores à 1.35.

Encontrar clusters e cargas de trabalho afetados no Cloud Logging

  1. No console do Google Cloud , acesse a página Análise de registros.

    Acessar o Explorador de registros

  2. Para abrir o editor de consultas, clique no botão Mostrar consulta.

  3. Execute a seguinte consulta:

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

    A saída é uma lista de erros de sondagem causados por comandos que levaram mais tempo para serem concluídos do que o período de tempo limite configurado.

Atualizar as cargas de trabalho afetadas antes de fazer upgrade para a versão 1.35

Depois de identificar as cargas de trabalho afetadas, atualize as sondagens afetadas.

  1. Revise as sondagens de atividade, prontidão e inicialização de cada pod afetado e determine um valor timeoutSeconds adequado. Esse valor precisa ser longo o suficiente para que o comando seja executado com êxito em condições normais. Para mais informações, consulte Configurar sondagens de atividade, prontidão e inicialização.
  2. Abra o arquivo de manifesto da carga de trabalho afetada e adicione ou modifique o campo timeoutSeconds para sondagens de atividade, prontidão ou inicialização. Por exemplo, a seguinte sondagem de atividade tem um valor de 10 no campo timeoutSeconds:

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. Aplique o manifesto atualizado ao cluster.

  4. Para verificar se há erros nas sondagens atualizadas, siga as etapas em Verificar eventos do Kubernetes usando a linha de comando.

Depois de atualizar e testar todas as cargas de trabalho afetadas, faça upgrade do cluster para a versão 1.35 do GKE.