GKE 버전 1.35로 업그레이드하기 전에 실행 프로브 시간 제한 구성


이 페이지에서는 Google Kubernetes Engine (GKE) 클러스터를 버전 1.35 이상으로 업그레이드하기 전에 활성, 준비, 시작 프로브를 준비하는 방법을 설명합니다. 이러한 프로브에서 명령의 시간 제한을 설정하면 됩니다.

실행 프로브의 제한 시간 정보

GKE 버전 1.35부터 Kubernetes는 활성, 준비, 시작 프로브의 exec 필드에 있는 명령어의 시간 제한을 적용합니다. 프로브 사양의 timeoutSeconds 필드는 Kubernetes가 프로브가 작업을 완료할 때까지 대기하는 시간을 정의합니다. 이 필드를 생략하면 기본값은 1이며, 이는 모든 작업이 완료되는 데 1초가 걸린다는 의미입니다.

1.35 이전 GKE 버전에서는 Kubernetes가 실행 프로브 명령어의 timeoutSeconds 필드 값을 무시합니다. 예를 들어 다음 속성이 있는 활성 상태 프로브를 고려해 보세요.

  • timeoutSeconds 필드의 5
  • 완료하는 데 10초가 걸리는 exec.command 필드의 명령어

1.35 이전 버전에서는 Kubernetes가 이 5초 제한 시간을 무시하고 프로브가 성공한 것으로 잘못 보고합니다. 버전 1.35 이상에서는 Kubernetes가 5초 후에 프로브를 올바르게 실패합니다.

Kubernetes가 실행 프로브 시간 제한을 무시하는 이 동작으로 인해 프로브가 무기한 실행될 수 있으며, 이로 인해 애플리케이션 문제가 숨겨지거나 예측할 수 없는 동작이 발생할 수 있습니다. GKE 버전 1.35 이상에서는 Kubernetes가 명령 시간 제한을 올바르게 적용하므로 오픈소스 Kubernetes와 일치하는 일관되고 예측 가능한 프로브 동작이 발생합니다.

실행 프로브의 제한 시간 적용의 영향

이는 GKE에서 실행되는 워크로드의 안정성과 신뢰성에 필요한 GKE 버전 1.35 이상의 호환성이 깨지는 변경사항입니다. 클러스터를 1.35 이상으로 업그레이드할 때 워크로드에 다음 속성 중 하나가 있는 실행 프로브가 있으면 예기치 않은 워크로드 동작이 발생할 수 있습니다.

  • timeoutSeconds 필드 생략: 버전 1.35 이상에서 이러한 프로브는 명령어를 성공적으로 완료하는 데 1초가 걸립니다. 명령어가 1초 내에 성공적으로 완료되지 않으면 프로브에서 실패를 올바르게 보고합니다.
  • 짧은 제한 시간 지정: 버전 1.35 이상에서는 명령 완료 시간보다 짧은 제한 시간이 있는 프로브가 실패를 올바르게 보고합니다.

GKE 버전 1.34 이하에서는 이러한 조건 중 하나를 충족하는 실행 프로브에서 Kubernetes가 오류를 보고합니다. 하지만 이러한 exec 프로브의 명령어는 프로브 오류가 프로브 실패가 아니므로 완료될 때까지 실행될 수 있습니다.

더 정확한 제한 시간을 지정하지 않고 명령어를 완료하는 데 기존 제한 시간보다 오래 걸리면 프로브가 버전 1.35 이상에서 실패를 보고합니다. 프로브 유형에 따라 프로브가 실패할 때 다음 동작이 적용됩니다.

  • 활성 여부 프로브: 명령어가 시간 초과되어 활성 여부 프로브가 실패하면 Kubernetes는 애플리케이션이 실패한 것으로 간주하고 컨테이너를 다시 시작합니다. 프로브가 반복적으로 실패하면 포드가 CrashLoopBackOff 포드 상태로 비정상 종료 루프에 갇힐 수 있습니다.
  • 준비 여부 프로브: 명령어가 시간 초과되어 준비 여부 프로브가 실패하면 Kubernetes는 False 상태로 Ready 포드 조건을 업데이트합니다. 프로브가 성공할 때까지 Kubernetes는 포드에 트래픽을 전송하지 않습니다. 서비스를 지원하는 모든 포드의 Ready 조건에 대한 상태가 False이면 서비스가 중단될 수 있습니다.
  • 시작 프로브: 시작 프로브가 실패하면 Kubernetes는 애플리케이션이 시작되지 않은 것으로 간주하고 컨테이너를 다시 시작합니다. 프로브가 반복적으로 실패하면 포드가 CrashLoopBackOff 포드 상태로 비정상 종료 루프에 갇힐 수 있습니다.

자동 업그레이드 일시중지됨

GKE는 클러스터의 워크로드가 이 변경사항의 영향을 받을 수 있다고 감지되면 버전 1.35로의 자동 업그레이드를 일시중지합니다. 버전 1.35가 컨트롤 플레인 및 노드의 자동 업그레이드 대상인 경우 다음 조건 중 하나가 충족되면 GKE가 자동 업그레이드를 재개합니다.

  • 시간 제한 값으로 워크로드 프로브를 업데이트했으며 GKE에서 7일 동안 잠재적인 문제를 감지하지 못했습니다.
  • 버전 1.34가 출시 채널에서 지원 종료됩니다.

영향을 받는 클러스터 또는 워크로드 식별

다음 섹션에서는 이 변경사항의 영향을 받을 수 있는 클러스터 또는 워크로드를 식별하는 방법을 보여줍니다.

명령줄을 사용하여 Kubernetes 이벤트 확인

GKE 버전 1.34 이하에서는 클러스터의 Kubernetes 이벤트를 수동으로 검사하여 기존 제한 시간보다 완료하는 데 시간이 더 오래 걸리는 exec 프로브를 찾을 수 있습니다. Kubernetes는 이러한 프로브에 command timed out 메시지가 포함된 이벤트를 추가합니다. 이 메서드는 짧은 제한 시간 값으로 인해 이미 문제가 발생하고 있는 워크로드를 식별하는 데 유용합니다.

영향을 받는 워크로드를 찾으려면 다음 중 하나를 수행하세요.

스크립트를 사용하여 여러 클러스터에서 워크로드 찾기

다음 bash 스크립트는 kubeconfig 파일에 있는 모든 클러스터를 반복하여 영향을 받는 워크로드를 찾습니다. 이 스크립트는 기존의 도달 가능한 모든 Kubernetes 컨텍스트에서 exec 프로브 타임아웃 오류를 확인하고 결과를 affected_workloads_report.txt라는 텍스트 파일에 씁니다. 이 스크립트를 실행하려면 다음 단계를 따르세요.

  1. 다음 스크립트를 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. 스크립트를 실행합니다.

    bash execprobe-timeouts.sh
    
  3. affected_workloads_report.txt 파일의 콘텐츠를 읽습니다.

    cat affected_workloads_report.txt
    

    출력은 다음과 비슷합니다.

    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
    

명령줄을 사용하여 특정 클러스터에서 워크로드 찾기

특정 클러스터에서 영향을 받는 워크로드를 식별하려면 kubectl 도구를 사용하여 exec 프로브 시간 초과 오류를 확인하면 됩니다. 버전 1.34 이하를 실행하는 모든 GKE 클러스터에 대해 다음 단계를 따르세요.

  1. 클러스터에 연결합니다.

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

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • LOCATION: 클러스터 컨트롤 플레인의 위치입니다(예: us-central1).
  2. 실행 프로브에 시간 제한 오류가 있음을 나타내는 이벤트를 확인합니다.

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

    이 명령어는 여러 시스템 네임스페이스의 워크로드를 무시합니다. 영향을 받는 워크로드가 있으면 출력은 다음과 비슷합니다.

    Pod/liveness1-exec      Namespace: default
    
  3. GKE 1.35 이전 버전을 실행하는 모든 클러스터에 대해 이전 단계를 반복합니다.

Cloud Logging에서 영향을 받는 클러스터 및 워크로드 찾기

  1. Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

    로그 탐색기로 이동

  2. 쿼리 편집기를 열려면 쿼리 표시 전환 버튼을 클릭합니다.

  3. 다음 쿼리를 실행합니다.

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

    출력은 구성된 제한 시간보다 완료하는 데 더 오래 걸린 명령어로 인해 발생한 프로브 오류 목록입니다.

1.35로 업그레이드하기 전에 영향을 받는 워크로드 업데이트

영향을 받는 워크로드를 식별한 후에는 영향을 받는 프로브를 업데이트해야 합니다.

  1. 영향을 받는 각 포드의 활성, 준비, 시작 프로브를 검토하고 적절한 timeoutSeconds 값을 결정합니다. 이 값은 정상적인 조건에서 명령어가 성공적으로 실행될 수 있을 만큼 충분히 길어야 합니다. 자세한 내용은 활성, 준비 상태, 시작 프로브 구성을 참고하세요.
  2. 영향을 받는 워크로드의 매니페스트 파일을 열고 활성, 준비 또는 시작 프로브의 timeoutSeconds 필드를 추가하거나 수정합니다. 예를 들어 다음 활성 프로브의 timeoutSeconds 필드에는 10 값이 있습니다.

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. 업데이트된 매니페스트를 클러스터에 적용합니다.

  4. 명령줄을 사용하여 Kubernetes 이벤트 확인의 단계를 따라 업데이트된 프로브의 오류를 확인합니다.

영향을 받는 모든 워크로드를 업데이트하고 테스트한 후 클러스터를 GKE 버전 1.35로 업그레이드할 수 있습니다.