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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

שימוש בהמלצות ובתובנות של GKE

‫GKE מנטר את האשכולות ומשתמש בשירות ההמלצות כדי לזהות אשכולות שהושפעו מהאכיפה של פסק זמן ל-exec probe. אם GKE מזהה שלקלאסטר יש עומסי עבודה עם בדיקות exec שעשויות להגיע לזמן קצוב לתפוגה, המלצה בשם Configure your workload exec probe timeouts מוצגת במסוףGoogle Cloud .

קבלת תובנות והמלצות

פועלים לפי ההוראות כדי לראות תובנות והמלצות. אפשר לקבל תובנות באמצעות מסוף Google Cloud . אפשר גם להשתמש ב-Google Cloud CLI או ב-Recommender API, ולסנן לפי סוג המשנה הבא:

  • EXEC_PROBE_TIMEOUT: פסק זמן של בדיקת הפעלה

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

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

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

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

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

הסקריפט הבא של bash מבצע איטרציה על כל האשכולות שנמצאים בקובץ kubeconfig כדי למצוא עומסי עבודה מושפעים. הסקריפט הזה בודק אם יש שגיאות של פסק זמן של בדיקת הפעלה (exec probe) בכל ההקשרים הקיימים והנגישים של 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. בודקים את בדיקות החיות, המוכנות וההפעלה של כל Pod מושפע וקובעים ערך מתאים ל-timeoutSeconds. הערך הזה צריך להיות ארוך מספיק כדי שהפקודה תפעל בהצלחה בתנאים רגילים. מידע נוסף זמין במאמר בנושא הגדרת בדיקות פעילות, בדיקות מוכנות ובדיקות הפעלה.
  2. פותחים את קובץ המניפסט של עומס העבודה המושפע ומוסיפים או משנים את השדה timeoutSeconds של בדיקות הפעילות, המוכנות או ההפעלה. לדוגמה, בדיקת החיות הבאה כוללת את הערך 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.