הגדרה של פסק זמן ל-exec probe לפני שמשדרגים ל-GKE גרסה 1.35

בדף הזה מוסבר איך להכין את בדיקות הפעילות, המוכנות וההפעלה לפני שמשדרגים את אשכולות Google Kubernetes Engine‏ (GKE) לגרסה 1.35 ואילך, על ידי הגדרת פסק זמן לפקודות בבדיקות האלה.

מידע על פסק זמן לבדיקות הפעלה

החל מגרסה 1.35 של GKE,‏ Kubernetes אוכף זמני קצובים לתפוגה לפקודות בשדה exec של בדיקות מצב הפעילות, המוכנות וההפעלה. השדה timeoutSeconds במפרט של בדיקה מגדיר כמה זמן מערכת Kubernetes מחכה עד שבדיקה תסיים את הפעולות שלה. אם לא משמיטים את השדה הזה, ערך ברירת המחדל הוא 1, כלומר, לכל הפעולות יש שנייה אחת להשלמה.

בגרסאות GKE קודמות ל-1.35, ‏ Kubernetes מתעלם מהערך בשדה timeoutSeconds עבור פקודות בדיקה של exec. לדוגמה, נניח שיש בדיקת מצב פעילות (liveness) עם המאפיינים הבאים:

  • הערך 5 בשדה timeoutSeconds.
  • פקודה בשדה exec.command שנמשכת 10 שניות.

בגרסאות קודמות ל-1.35, ‏ Kubernetes מתעלם מהזמן הקצוב לתפוגה של חמש שניות ומדווח באופן שגוי שהבדיקה הצליחה. בגרסה 1.35 ואילך, Kubernetes מחזירה תשובה שלילית לבדיקה אחרי חמש שניות.

ההתנהגות הזו, שבה Kubernetes מתעלם מפרקי הזמן הקצובים לתפוגה של בדיקות exec, עלולה לגרום לבדיקות לפעול ללא הגבלת זמן. כך יכול להיות שבעיות באפליקציות שלכם לא יזוהו, או שיווצר מצב של התנהגות בלתי צפויה. ב-GKE בגרסה 1.35 ואילך, Kubernetes אוכף את פסק הזמן של הפקודה בצורה נכונה, וכתוצאה מכך התנהגות הבדיקה עקבית וניתנת לחיזוי, בהתאם ל-Kubernetes בקוד פתוח.

ההשפעה של אכיפת פסק זמן לבדיקות תקינות מסוג exec

זהו שינוי שעלול לגרום לבעיות ב-GKE מגרסה 1.35 ואילך, והוא נחוץ ליציבות ולמהימנות של עומסי עבודה שפועלים ב-GKE. כשמשדרגים את האשכולות לגרסה 1.35 ואילך, יכול להיות שתבחינו בהתנהגות לא צפויה של עומסי עבודה אם יש לעומסי העבודה בדיקות exec עם אחת מהמאפיינים הבאים:

  • השמטה של השדה timeoutSeconds: בגרסה 1.35 ואילך, לבדיקות האלה יש שנייה אחת להשלמת הפקודות בהצלחה. אם הפקודה לא תושלם בהצלחה תוך שנייה אחת, הבדיקות ידווחו על כשלים.
  • מציינים תקופות קצרות של זמן קצוב לתפוגה: בגרסה 1.35 ואילך, בקשות לבדיקת תקינות (probe) עם תקופת זמן קצוב לתפוגה קצרה יותר מזמן השלמת הפקודה ידווחו ככשלים.

בגרסה 1.34 של GKE ובגרסאות קודמות, Kubernetes מדווח על שגיאה בבדיקות exec שעומדות באחד מהתנאים הבאים. עם זאת, הפקודות בבדיקות הפעלה האלה עדיין יכולות לפעול עד הסוף, כי השגיאה בבדיקה היא לא כשל בבדיקה.

אם לא מציינים משך זמן מדויק יותר להמתנה עד לזמן קצוב לתפוגה, והפקודות נמשכות יותר מהזמן הקצוב לתפוגה הקיים, הבדיקות ידווחו על כשלים בגרסה 1.35 ואילך. בהתאם לסוג הבקשה לבדיקת תקינות (probe), ההתנהגות הבאה חלה כשהבקשה לבדיקת תקינות (probe) נכשלת:

  • בדיקות מצב פעילות (liveness): אם בדיקת מצב פעילות (liveness) נכשלת כי פקודה הגיעה לזמן קצוב לתפוגה, מערכת Kubernetes מניחה שהאפליקציה נכשלה ומפעילה מחדש את הקונטיינר. בגרסאות קודמות לגרסה 1.35, יכול להיות שפסק זמן ייצור רק אירוע אזהרה בלי להפעיל מחדש את מאגר התגים. אם הבדיקה נכשלת שוב ושוב, יכול להיות שה-Pods שלכם ייתקעו בלולאת קריסה עם CrashLoopBackOff סטטוס Pod.
  • בדיקות מוכנות: אם בדיקת מוכנות נכשלת כי פג הזמן הקצוב לתגובה של פקודה, Kubernetes מעדכן את Ready מצב ה-Pod בסטטוס False. כלומר, Kubernetes לא שולח תנועה ל-Pod עד שהבדיקה מצליחה. ב-GKE מגרסה 1.35 ואילך, ה-Pod מוסר מנקודות הקצה של השירות. בגרסאות קודמות ל-1.35, יכול להיות שזמן קצוב לתפוגה ייצור רק אירוע אזהרה בלי להסיר את ה-Pod מהשירות. אם כל ה-Pods שמגבים שירות מסוים הם בעלי סטטוס False בתנאי Ready, יכול להיות שתבחינו בשיבושים בשירות.
  • בדיקות אתחול: אם בדיקת אתחול נכשלת, Kubernetes מניח שהאפליקציה לא הופעלה ומפעיל מחדש את הקונטיינר. אם הבדיקה נכשלת שוב ושוב, יכול להיות שה-Pods שלכם ייתקעו בלולאת קריסה עם CrashLoopBackOff סטטוס Pod.

השהיית השדרוגים האוטומטיים

‫GKE משהה שדרוגים אוטומטיים לגרסה 1.35 כשהוא מזהה שעומסי העבודה באשכול עלולים להיות מושפעים מהשינוי הזה. ‫GKE ימשיך בשדרוגים אוטומטיים אם גרסה 1.35 היא יעד לשדרוג אוטומטי של מישור הבקרה והצמתים, ואם אחד מהתנאים הבאים מתקיים:

  • עדכנתם את בדיקות העומס של עומס העבודה עם ערכי זמן קצובים לתפוגה, ו-GKE לא זיהה בעיות פוטנציאליות במשך שבעה ימים.
  • גרסה 1.34 מגיעה לסוף התמיכה בערוץ ההפצה שלכם.

זיהוי של אשכולות או עומסי עבודה מושפעים

בקטעים הבאים מוסבר איך לזהות אשכולות או עומסי עבודה שעשויים להיות מושפעים מהשינוי הזה.

בדיקת אירועים ב-Kubernetes באמצעות שורת הפקודה

ב-GKE בגרסה 1.34 ובגרסאות קודמות, אפשר לבדוק ידנית את אירועי Kubernetes באשכולות כדי למצוא בדיקות exec שלוקח להן יותר זמן להסתיים מאשר פרק הזמן הקיים לתפוגה. ‫Kubernetes מוסיף אירוע עם הודעה command timed out לבדיקות האלה. השיטה הזו שימושית לזיהוי עומסי עבודה שכבר נתקלים בבעיות בגלל ערכי זמן קצוב לתפוגה קצרים.

כדי למצוא את עומסי העבודה המושפעים, אפשר לבצע אחת מהפעולות הבאות:

חיפוש עומסי עבודה בכמה אשכולות באמצעות סקריפט

סקריפט ה-Bash הבא מבצע איטרציה על כל האשכולות שנמצאים בקובץ ה-kubeconfig כדי למצוא עומסי עבודה מושפעים. הסקריפט הזה בודק אם יש שגיאות של פסק זמן של בדיקת exec בכל ההקשרים הקיימים והנגישים של Kubernetes, וכותב את הממצאים לקובץ טקסט בשם 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. צריך לבצע את השלבים הבאים לכל אשכול GKE שפועלת בו גרסה 1.34 או גרסה מוקדמת יותר:

  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. נכנסים לדף Logs Explorer במסוף Google Cloud .

    כניסה לדף Logs Explorer

  2. כדי לפתוח את עורך השאילתות, לוחצים על המתג הצגת שאילתה.

  3. מריצים את השאילתה הבאה:

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

    הפלט הוא רשימה של שגיאות בדיקה שנגרמו כתוצאה מפקודות שהשלמתן ארכה יותר זמן מתקופת הזמן הקצוב לתפוגה שהוגדרה.

עדכון עומסי העבודה המושפעים לפני השדרוג לגרסה 1.35

אחרי שמזהים את עומסי העבודה המושפעים, צריך לעדכן את הבדיקות המושפעות.

  1. בודקים את בדיקות מצב הפעילות (liveness), המוכנות וההפעלה של כל Pod מושפע וקובעים ערך timeoutSeconds מתאים. הערך הזה צריך להיות ארוך מספיק כדי שהפקודה תפעל בהצלחה בתנאים רגילים. מידע נוסף זמין במאמר בנושא הגדרת בדיקות פעילות, בדיקות מוכנות ובדיקות הפעלה.
  2. פותחים את קובץ המניפסט של עומס העבודה המושפע ומוסיפים או משנים את השדה timeoutSeconds של בדיקות הפעילות, המוכנות או ההפעלה. לדוגמה, בקשה לבדיקת תקינות מצב פעילות (liveness probe) הבאה כוללת את הערך 10 בשדה timeoutSeconds:

    spec:
      containers:
      - name: my-container
        image: my-image
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 10
    
  3. מחילים את המניפסט המעודכן על האשכול.

  4. כדי לבדוק אם יש שגיאות בבדיקות המעודכנות, פועלים לפי השלבים במאמר בדיקת אירועים ב-Kubernetes באמצעות שורת הפקודה.

אחרי שתעדכנו את כל עומסי העבודה המושפעים ותבדקו אותם, תוכלו לשדרג את האשכול לגרסה 1.35 של GKE.