פתרון בעיות בהגדרות אישיות של ComputeClass

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

המסמך הזה מיועד למפתחי אפליקציות ולאדמינים ומפעילים של פלטפורמות שמשתמשים ב-ComputeClasses בהתאמה אישית כדי לנהל את תזמון עומסי העבודה ואת היצירה האוטומטית של מאגרי צמתים ב-GKE. מידע נוסף על התפקידים הנפוצים ומשימות לדוגמה שמוזכרים ב Cloud de Confiance by S3NS תוכן, זמין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.

מושגים מרכזיים

כדי לעזור לכם לפתור בעיות, חשוב שתכירו את הרכיבים והמנגנונים הבאים של GKE:

  • Custom ComputeClass: משאב ספציפי ל-GKE שמאפשר להגדיר רשימה של תצורות צמתים עם תעדוף לצורך שינוי גודל אוטומטי. מידע נוסף זמין במאמר בנושא מידע על ComputeClasses בהתאמה אישית.

  • Cluster autoscaler: הרכיב שמוסיף או מסיר באופן אוטומטי צמתים באשכול, בהתאם לדרישות של עומס העבודה. מידע נוסף זמין במאמר מידע על שינוי אוטומטי של גודל אשכול GKE.

  • יצירה אוטומטית של מאגר צמתים: המידרוג האוטומטי של אשכול GKE יוצר ומנהל מאגרי צמתים באופן אוטומטי על סמך דרישות עומס העבודה. מידע נוסף מופיע במאמר בנושא יצירה אוטומטית של מאגרי צמתים.

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

פתרון בעיות לפי סימפטומים

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

תיאור הבעיה שלבים לפתרון בעיות
Pod שמבקש ComputeClass בהתאמה אישית נתקע במצב Pending
המידרוג האוטומטי של האשכול לא יוצר צמתים חדשים שתואמים ל-ComputeClass המותאם אישית
המידרוג האוטומטי של האשכול יוצר סוגי מכונות שמוגדרים כברירת מחדל במקום סוגים מיוחדים ניתוח של התנהגות הגיבוי של המידרוג האוטומטי
הפלט מהפקודה kubectl describe computeclass מציג סטטוס לא תקין אימות של הגדרות ComputeClass בהתאמה אישית
עומסי העבודה לא מועברים לצמתים עם עדיפות גבוהה יותר אימות תקינות כללית של המידרוג האוטומטי באשכול
בעיות בתזמון של עומסי עבודה במכונות וירטואליות עם GPU או ב-VM במודל Spot

בעיות שלא נכללות בהיקף התמיכה

המסמך הזה לא מתייחס לבעיות הבאות:

  • בעיות כלליות ברשת של GKE, כמו קישוריות בין Pod ל-Pod או איזון עומסים בשירות.
  • בעיות שקשורות ל-Horizontal Pod Autoscaler‏ (HPA) או ל-Vertical Pod Autoscaler‏ (VPA).
  • בעיות שלא קשורות למנגנון ComputeClass בהתאמה אישית, כמו שגיאות ברמת האפליקציה או בעיות ב-PersistentVolume שלא קשורות למגבלות התזמון.
  • בעיות במכסת המשאבים או בזמינות המשאבים שלא קשורות ישירות ללוגיקת החזרה (fallback) של ComputeClass.

זיהוי משתני פלייסהולדר

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

משתנה תיאור
PROJECT_ID מזהה הפרויקט ב- Cloud de Confiance .
LOCATION האזור או התחום (zone) של Compute Engine שבו נמצא האשכול.
CLUSTER_NAME השם של האשכול.
NODE_POOL_NAME שם מאגר הצמתים שרוצים לבדוק (אם רלוונטי לאשכולות Standard).
CUSTOM_COMPUTECLASS_NAME השם של ComputeClass מותאם אישית שה-Pod מבקש.
NAMESPACE מרחב השמות של ה-Pod שלא ניתן לתזמן.
POD_NAME השם של ה-Pod שלא מצליח לתזמן.

לפני שמתחילים

כדי לקבל את ההרשאות שדרושות לביצוע המשימות שמתוארות במאמר הזה, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט Cloud de Confiance by S3NS :

  • כדי לגשת לאשכולות GKE: צפייה באשכולות של Kubernetes Engine (roles/container.viewer).
  • כדי לצפות ביומנים: מציג היומנים (roles/logging.viewer).
  • כדי לנהל אשכולות GKE: אדמין Kubernetes Engine‏ (roles/container.admin).

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

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

כדי להגדיר את kubectl לתקשורת עם האשכול, מריצים את הפקודה הבאה:

  gcloud container clusters get-credentials CLUSTER_NAME
      --location LOCATION
      --project PROJECT_ID

ביצוע בדיקות אבחון בסיסיות

מוודאים שרכיבי הליבה מוגדרים בצורה נכונה ושהאשכול תומך ב-ComputeClasses בהתאמה אישית.

אימות הסטטוס והסלקטור של ה-Pod

מוודאים שה-Pod נמצא במצב Pending ומבקש בצורה נכונה את ה-ComputeClass בהתאמה אישית.

  1. רשימת ה-Pods במצב Pending:

    kubectl get pods --all-namespaces -o wide | grep Pending
    
  2. בודקים את המפרט של ה-Pod בשדה nodeSelector:

    kubectl get pod POD_NAME
        -n NAMESPACE
        -o jsonpath='{.spec.nodeSelector}'
    

הערכת התוצאה

  • התווית מוצגת בפלט: השדה nodeSelector מוגדר בצורה נכונה עם התווית cloud.google.com/compute-class.
  • התווית לא מופיעה בפלט:
    • הסבר: יכול להיות ששדה nodeSelector שגוי או חסר בתווית cloud.google.com/compute-class בהגדרות הפריסה של עומס העבודה.
    • פתרון: משנים את קובץ ה-YAML של עומס העבודה, כמו Deployment או Job, כך שיכלול את השדה nodeSelector בקטע spec.template.spec.

אימות התאימות של גרסת האשכול

כדי להשתמש ב-ComputeClasses בהתאמה אישית, צריך את גרסה 1.30.3-gke.1451000 ומעלה של GKE. מוודאים שהגרסה של האשכול תומכת ב-ComputeClasses בהתאמה אישית.

בודקים את גרסת האשכול:

gcloud container clusters describe CLUSTER_NAME
    --location LOCATION
    --format="value(currentMasterVersion)"

הערכת התוצאה

  • ‫גרסה 1.30.3-gke.1451000 ואילך: גרסת האשכול תומכת ב-ComputeClasses בהתאמה אישית.
  • גרסה מוקדמת יותר מ-1.30.3-gke.1451000:
    • הסבר: האשכול לא שודרג לגרסה שתומכת ב-ComputeClasses בהתאמה אישית.
    • פתרון: כדי להשתמש ב-ComputeClasses בהתאמה אישית, צריך לשדרג את האשכול.

אימות הצמתים שהוקצו ל-ComputeClass בהתאמה אישית

כדי לבדוק אם יש צמתים באשכול שמשויכים ל-ComputeClass, מציגים את רשימת הצמתים שתואמים לתווית ComputeClass:

kubectl get nodes -l cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME

אם הפלט הוא No resources found, אין צמתים שמשויכים ל-ComputeClass. מוודאים שעומסי העבודה באמת בחרו את ComputeClass הזה, ובודקים אם יש שגיאות בהגדלת הקיבולת באירועים של שינוי הגודל האוטומטי.

אימות ההגדרות האישיות של ComputeClass

הגדרות שגויות במשאב ComputeClass בהתאמה אישית יכולות למנוע תזמון של Pods או למנוע הקצאה של צמתים ב-GKE בצורה תקינה.

בדיקת התקינות והסטטוס של ComputeClass

מוודאים ש-GKE מדווח על ComputeClass בהתאמה אישית כעל תקין.

  1. הצגת רשימה של כל המשאבים של ComputeClass:

    kubectl get computeclass
    
  2. תארו את משאב ComputeClass הספציפי:

    kubectl describe computeclass CUSTOM_COMPUTECLASS_NAME
    

הערכת התוצאה

  • סטטוס התקינות הוא True: ה-ComputeClass בהתאמה אישית תקין. הדוגמה הבאה מציגה ComputeClass תקין בהתאמה אישית:

    Status:
      Conditions:
        Last Transition Time:  2024-01-19T17:18:48Z
        Message:               CCC is healthy.
        Reason:                Health
        Status:                True
        Type:                  Health
    
  • בסטטוס התקינות מוצג הערך False:

    • פירוש: ה-ComputeClass המותאם אישית לא תקין. בודקים את השדות Message ו-Reason בפלט כדי לזהות את הבעיה.
    • פתרון: מבצעים את הפעולה שמתאימה לשדה Reason בפלט:
      • ‫NodePoolNotExist: מוודאים שמאגר הצמתים שאליו מתבצעת ההפניה קיים, או מעדכנים את ComputeClass כך שיפנה למאגר צמתים קיים.
      • ‫ReservationUnusable: בדיקה של התצורה והשימוש בהזמנה שאליה יש הפניה.
      • ‫Invalid machine type: צריך לעדכן את ComputeClass כדי להשתמש בסוג מכונה שנתמך באזור או באזור הזמינות של האשכול.

אימות המדיניות של unsatisfiable

השדה whenUnsatisfiable קובע את ההתנהגות כשאי אפשר לעמוד בכללי העדיפות.

בודקים את המדיניות:

kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml

בודקים את השדה spec.whenUnsatisfiable בפלט. השדה הזה יכול לקבל אחד מהערכים הבאים:

  • ‫DoNotScaleUp: רצפים נשארים במצב Pending אם אי אפשר ליצור צמתים מועדפים.
  • ‫ScaleUpAnyway: יכול להיות שפודים יפעלו על סוגי צמתים שמוגדרים כברירת מחדל (כמו סדרת E2) אם הצמתים המועדפים לא זמינים.

הערכת התוצאה

ההשפעה של המדיניות whenUnsatisfiable תלויה בערך שלה:

  • אם הערך הוא DoNotScaleUp:
    • הסבר: זו התנהגות צפויה כשאין כללי עדיפות שאפשר לעמוד בהם, יכול להיות בגלל חוסר זמינות של משאבים או מגבלות מכסה. אם חבילות ה-Pods צריכות לחכות לחומרה ספציפית, הערך הזה נכון.
    • פתרון: אם הפעלת עומס העבודה קריטית יותר מהפעלה בחומרה ספציפית, משנים את המדיניות ל-ScaleUpAnyway.
  • אם הערך הוא ScaleUpAnyway:
    • הסבר: זו התנהגות צפויה. ‫GKE חוזר לסוגי הצמתים שמוגדרים כברירת מחדל כי הצמתים המועדפים לא זמינים.
    • פתרון: אם אסור להפעיל Pods בסוגי צמתים שמוגדרים כברירת מחדל, צריך לשנות את המדיניות ל-DoNotScaleUp.
  • התנהגות ברירת המחדל: אם לא ציינתם ערך לשדה whenUnsatisfiable ואתם משתמשים בגרסה של GKE מוקדמת יותר מ-1.33, ערך ברירת המחדל של המדיניות הוא ScaleUpAnyway.

בדוגמה הבאה מוסבר איך לעדכן את המדיניות על ידי עריכת השדה whenUnsatisfiable במניפסט של ComputeClass:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: CUSTOM_COMPUTECLASS_NAME
spec:
  # ... other fields
  whenUnsatisfiable: DoNotScaleUp # or ScaleUpAnyway

בדיקת אילוצים לתזמון של Pod

מוודאים שמפרט ה-Pod תואם למאפיינים של הצמתים שהוקצו על ידי ComputeClass בהתאמה אישית.

אימות בקשות למשאבי Pod

בודקים אם אפשר לספק את הבקשות של ה-Pod למעבד, לזיכרון ול-GPU לפחות על ידי אחד מסוגי המכונות שמוגדרים בשדה priorities של ה-ComputeClass המותאם אישית.

  1. קבלת בקשות למשאבי Pod:

    kubectl get pod POD_NAME
        -n NAMESPACE
        -o jsonpath='{.spec.containers[*].resources.requests}'
    

    בודקים את הפלט של בקשות cpu, memory ו-GPU, כמו nvidia.com/gpu.

  2. משווים את הבקשות האלה לסוגי המכונות שמוגדרים בשדה priorities של ComputeClass בהתאמה אישית:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME
        -o jsonpath='{.spec.priorities}'
    

    בודקים את השדות machineType או machineFamily בפלט. לכל סוג מכונה ב-ComputeClass המותאם אישית, בודקים את המפרטים שלו במסמכי העזרה של סוגי המכונות ומוודאים שהמשאבים שניתן להקצות לו גדולים מהבקשות של ה-Pod.

הערכת התוצאה

  • משאבים תואמים: בקשות המשאבים של ה-Pod קטנות או שוות למשאבים שניתנים להקצאה של לפחות סוג מכונה אחד ב-ComputeClass.
  • המשאבים חורגים מהקיבולת:

    • הסבר: אי אפשר לתזמן את ה-Pod כי אף סוג מכונה ב-ComputeClass לא מספק מספיק CPU, זיכרון או GPU. זה יכול לקרות גם אם השדה nodePoolAutoCreation מוגדר לערך true ובקשת הזיכרון של ה-Pod חורגת מהמגבלות של מאגרי הצמתים שנוצרו באופן אוטומטי.
    • פתרון: משנים את בקשות המשאבים של ה-Pod או את סוגי המכונות של ה-ComputeClass בהתאמה אישית:
      • הפחתת בקשות המשאבים של Pod: אם בקשות המשאבים גבוהות, צריך להפחית את הערכים של cpu, memory או gpu בקובץ ה-YAML של עומס העבודה.
      • מעבר לסוגי מכונות גדולים יותר: אם הבקשות של ה-Pod מוצדקות, משנים את השדה spec.priorities במניפסט של ComputeClass המותאם אישית כך שיכלול אפשרויות גדולות יותר של machineType או machineFamily שיכולות לענות על הדרישות של ה-Pod. לדוגמה:
    spec:
      priorities:
      - machineType: n2d-highmem-96 # A larger machine type
        spot: true
      # ... other priorities
    

בדיקה אם יש taints ו-tolerations שמתנגשים

לצמתים שנוצרו בשביל ComputeClass בהתאמה אישית יש את ה-taint cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule. ‫GKE מוסיף את הסבילות הזו ל-Pods באופן אוטומטי.

עם זאת, לחומרה מיוחדת כמו מעבדי GPU יש טיינטים נוספים, כמו הטיינט nvidia.com/gpu=present:NoSchedule. אם ה-ComputeClass שלכם משתמש בצמתים עם חומרה ייעודית, ל-Pods חייבת להיות סבילות ל-taints האלה כדי לתזמן אותם בצמתים האלה.

בודקים את השדה tolerations של ה-Pod:

kubectl get pod POD_NAME
    -n NAMESPACE
    -o jsonpath='{.spec.tolerations}'

הערכת התוצאה

  • סובלנויות נכונות: פגמים וסובלנויות מוגדרים בצורה נכונה.
  • טולרנטיות חסרות:

    • הסבר: חוסר סבילות מונע את התזמון של ה-Pod בצמתים עם כתמי חומרה מיוחדים. לדוגמה, אם ComputeClass משתמש בצמתי GPU, יכול להיות שחסר ל-Pod את nvidia.com/gpu=present:NoSchedule toleration. לדרישות ספציפיות ל-GPU, אפשר לעיין במאמר בנושא אימות הגדרת ה-GPU.
    • פתרון: בשדה tolerations במפרט ה-Pod, מוסיפים את ההגדרות הנדרשות של tolerations כדי להתאים ל-taints בצמתים שמוגדרים על ידי ComputeClass. לדוגמה, כדי להוסיף טולרנס ל-taint‏ nvidia.com/gpu=present:NoSchedule בצמתי GPU, צריך להוסיף את השורה הבאה:

      spec:
      template:
      spec:
      tolerations:
      - key: "nvidia.com/gpu"
      operator: "Exists"
      effect: "NoSchedule"
      # ... other tolerations and Pod spec
      

הגדרת מאגר צמתים (אשכולות רגילים)

באשכולות GKE Standard, מאגרי צמתים שנוצרו באופן ידני צריכים להיות מסומנים בתוויות ומוכתמים כדי לעבוד עם ComputeClass בהתאמה אישית.

אימות של תוויות וכתמים של מאגר צמתים

  1. מזהים את מאגרי הצמתים ב-ComputeClass המותאם אישית. אם ה-ComputeClass בהתאמה אישית משתמש בשדה nodePools, צריך לשים לב לשמות של מאגרי הצמתים שמופיעים ברשימה:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    
  2. לכל מאגר צמתים שזיהיתם, בודקים את ההגדרה שלו:

    gcloud container node-pools describe NODE_POOL_NAME
        --cluster CLUSTER_NAME
        --location LOCATION
        --format="yaml(config.labels, config.taints)"
    

הערכת התוצאה

  • מאגר הצמתים מוגדר בצורה נכונה: למאגר הצמתים יש את התווית cloud.google.com/compute-class: CUSTOM_COMPUTECLASS_NAME ואת ה-taint‏ cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule.
  • ההגדרה של מאגר הצמתים שגויה:

    • הסבר: מאגר הצמתים לא הוגדר עם התווית וההכתמה שנדרשות כדי לשייך אותו ל-ComputeClass המותאם אישית.
    • פתרון: מעדכנים את מאגר הצמתים כדי להוסיף את התווית וההכתמה:

      1. הוספה או עדכון של תווית צומת:

        gcloud container node-pools update NODE_POOL_NAME \
            --cluster=CLUSTER_NAME --location=LOCATION \
            --node-labels=cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME
        
      2. הוספה או עדכון של כתם בצומת:

        gcloud container node-pools update NODE_POOL_NAME \
            --cluster=CLUSTER_NAME --location=LOCATION \
            --node-taints=cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule
        

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

גם באשכולות במצב Autopilot וגם באשכולות רגילים עם nodePoolAutoCreation שמוגדר ל-true, צריך להגדיר בצורה נכונה את היצירה האוטומטית של מאגר הצמתים.

איך מוודאים שהיצירה האוטומטית של מאגרי צמתים מופעלת

  1. בודקים אם השדה nodePoolAutoCreation.enabled ב-ComputeClass המותאם אישית מוגדר ל-true:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    
  2. בודקים אם ההגדרה 'יצירה אוטומטית של מאגר צמתים' מופעלת באשכול:

    gcloud container clusters describe CLUSTER_NAME
        --location LOCATION
        --format="value(autoscaling.enableNodeAutoprovisioning)"
    

אם אחד מהם מושבת, יצירה אוטומטית של מאגר צמתים לא תיצור מאגרי צמתים חדשים עבור ComputeClass בהתאמה אישית.

הערכת התוצאה

  • היצירה האוטומטית של מאגר הצמתים מופעלת: ב-ComputeClass, השדה nodePoolAutoCreation.enabled מוגדר ל-true, והקצאת צמתים אוטומטית (NAP) מופעלת ברמת האשכול.
  • היצירה האוטומטית של מאגר הצמתים מושבתת:

    • הסבר: יצירה אוטומטית של מאגר צמתים מושבתת אם הערך של השדה nodePoolAutoCreation.enabled הוא false או שהוא חסר ב-ComputeClass, או אם הקצאת משאבים אוטומטית של צמתים ברמת האשכול מושבתת.
    • פתרון: הפעלה של יצירה אוטומטית של מאגר צמתים:

      1. עורכים את קובץ ה-YAML של ComputeClass בהתאמה אישית כדי לכלול את nodePoolAutoCreation: enabled: true:

        spec:
          # ... priorities
          nodePoolAutoCreation:
            enabled: true
        
      2. הפעלת יצירה אוטומטית של מאגר צמתים ברמת האשכול והגדרת מגבלות משאבים:

        gcloud container clusters update CLUSTER_NAME --location LOCATION \
          --enable-autoprovisioning \
          --autoprovisioning-min-cpu=MIN_CPU \
          --autoprovisioning-max-cpu=MAX_CPU \
          --autoprovisioning-min-memory=MIN_MEMORY \
          --autoprovisioning-max-memory=MAX_MEMORY
        

בדיקת מגבלות המשאבים ליצירה אוטומטית של מאגרי צמתים

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

  1. כדי לראות את מגבלות המשאבים:

    gcloud container clusters describe CLUSTER_NAME
        --location LOCATION
    --format="value(autoscaling.resourceLimits)"
    

    הפלט מציג את השדות resourceType,‏ minimum ו-maximum של המעבד (CPU) והזיכרון (ב-GB).

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

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

הערכת התוצאה

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

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

      1. קובעים מגבלות מקסימליות חדשות שמתחשבות בשימוש הנוכחי ובצמיחה העתידית, כולל סוגי המכונות הגדולים ביותר ב-ComputeClass המותאם אישית.

      2. עדכון מגבלות המשאבים ליצירה אוטומטית של מאגר צמתים אפשר להגדיר כמה משאבים בפקודה אחת:

        gcloud container clusters update CLUSTER_NAME --location LOCATION \
          --set-nap-resource-limits resourceType=cpu,maximum=NEW_MAX_CPU \
          --set-nap-resource-limits resourceType=memory,maximum=NEW_MAX_GB
        

ניתוח התנהגות של מעבר לגיבוי אוטומטי

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

ב-ComputeClasses בהתאמה אישית נעשה שימוש בלוגיקה חלופית לפי סדר עדיפות. אם לא מתבצע תזמון של Pod בצמתים שתואמים לכלל עם העדיפות הכי גבוהה, לרוב זה קורה בגלל מגבלות כמו חוסר זמינות של משאבים או מכסות בפרויקט. אם GKE לא מצליח להקצות צמתים שתואמים לכלל עדיפות ספציפי, למשל בגלל שגיאה מסוג ZONE_RESOURCE_POOL_EXHAUSTED או QUOTA_EXCEEDED מ-Compute Engine, המידרוג האוטומטי של האשכול ינסה מיד את הכלל הבא ברשימה priorities. אין תקופת המתנה לפני ש-GKE עובר לעדיפות הבאה, אלא אם משתמשים ב-TPU או במודל ההקצאה Flex Start, שתומכים בהשהיה שניתנת להגדרה.

בדיקה אם המשאב לא זמין

כדי לבדוק אם משאבים לא זמינים בתחום שצוין, בודקים את היומנים של המידרוג האוטומטי באשכול או את השגיאות של קבוצת מופעי מכונה מנוהלים (MIG) ב-Compute Engine.

אפשרות 1: בדיקת אירועי החשיפה של המידרוג האוטומטי באשכול

במסוף Cloud de Confiance , נכנסים לדף Cloud Logging > Logs Explorer ומריצים את השאילתה הבאה כדי למצוא אירועים של התאמה אוטומטית לעומס (autoscaler) שעשויים להצביע על חוסר זמינות של משאבים:

resource.type="k8s_cluster"
resource.labels.location="LOCATION"
resource.labels.cluster_name="CLUSTER_NAME"
log_id("container.googleapis.com/cluster-autoscaler-visibility")
jsonPayload.noScaleUpReason.messageId="no.scale.up.nap.resource.exhausted"

אפשרות 2: בדיקת שגיאות ב-MIG

אתם יכולים לבדוק אם יש שגיאות ב-MIG במסוף Cloud de Confiance או באמצעות שאילתה ב-Cloud Logging.

  • באמצעות מסוף Cloud de Confiance :

    1. במסוף Cloud de Confiance , עוברים אל Compute Engine > Instance groups.
    2. מוצאים את ה-MIG שמתאים למאגר הצמתים שלא מצליח להתרחב.
    3. לוחצים על שם ה-MIG ועוברים לכרטיסייה שגיאות. מחפשים הודעות שמעידות על מיצוי המשאבים.
  • באמצעות שאילתה ב-Cloud Logging:

    1. במסוף Cloud de Confiance , עוברים אל Cloud Logging > Logs explorer.
    2. מריצים את השאילתה הבאה כדי לבדוק אם יש שגיאות של מיצוי משאבים מה-MIG:
    resource.type="gce_instance"
    log_id("cloudaudit.googleapis.com/activity")
    protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")
    

הערכת התוצאה

  • המשאבים זמינים: אם ההודעות ZONE_RESOURCE_POOL_EXHAUSTED לא מופיעות ביומנים, סביר להניח שחוסר זמינות של משאבים לא גרם לבעיה בהרחבת הקיבולת.
  • מקורות המידע לא זמינים:

    • הסבר: הקצאת הצמתים נכשלת בגלל ביקוש גבוה זמני לסוג מכונה ספציפי (במיוחד VM במודל Spot או יחידות GPU) באותו תחום, או בגלל שה-Pod מוגבל על ידי זיקה של PersistentVolume לתחום שבו המשאבים לא זמינים.
    • פתרון: חוסר הזמינות של המשאב הוא זמני, אבל אפשר לשפר את העמידות על ידי הוספת גמישות להגדרה:

      • מגוון סוגי מכונות: מוודאים שהשדה spec.priorities ב-ComputeClass המותאם אישית מכיל כמה סוגים או משפחות של מכונות כחלופות:

        spec:
          priorities:
          - machineFamily: c3  # Highest priority
          - machineFamily: n2d # Fallback option
          - machineFamily: e2  # Lowest priority
        
      • שימוש באשכולות אזוריים: אם האשכול הוא של תחום מוגדר, הוא פגיע למצב שבו המשאבים לא זמינים בתחום היחיד הזה. שימוש באשכולות אזוריים מאפשר ל-Cluster Autoscaler לנסות להקצות צמתים באזורים אחרים באזור שבו יכול להיות שיש קיבולת זמינה.

      • שימוש במקומות שמורים ב-Compute Engine: לעומסי עבודה קריטיים שלא יכולים לסבול עיכובים, צרו מקומות שמורים ב-Compute Engine כדי להבטיח קיבולת לסוגי מכונות ספציפיים.

אימות מכסות הפרויקט

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

  1. בודקים ביומני המידרוג האוטומטי אם יש שגיאות שקשורות למכסה. משתמשים ב-Cloud Logging כדי לחפש הודעות שגיאה שקשורות למכסות באירועי החשיפה של המידרוג האוטומטי:

    resource.type="k8s_cluster"
    resource.labels.location="LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    log_id("container.googleapis.com/cluster-autoscaler-visibility")
    jsonPayload.noScaleUpReason.messageId="no.scale.up.nap.quota.exceeded"
    

    אפשר גם להשתמש בשאילתת Cloud Logging הבאה כדי לבדוק ביומנים אם יש שגיאות שקשורות למכסת השימוש מ-MIG:

    resource.type="gce_instance"
    protoPayload.methodName:"compute.instances.insert"
    protoPayload.status.message:"QUOTA_EXCEEDED"
    severity=ERROR
    
  2. בדיקת המכסות במסוף Cloud de Confiance :

    1. במסוף Cloud de Confiance , נכנסים אל IAM & Admin > Quotas.
    2. מסננים לפי השירות Compute Engine API.
    3. בודקים את השימוש במדדים רלוונטיים כמו מעבדים (CPU), מעבדים גרפיים (GPU) (מכל הסוגים) וכתובות IP בשימוש באזור שבו נמצא אשכול GKE. בודקים שהשימוש הנוכחי לא הגיע למגבלה.

הערכת התוצאה

  • המכסה נמוכה מהמגבלות: אם השימוש במכסה נמוך ממגבלות המכסה ולא נמצאו שגיאות QUOTA_EXCEEDED ביומנים, מגבלות המכסה לא יחסמו את ההרחבה.
  • חריגה מהמכסה:
    • הסבר: הקצאת הצמתים נכשלת בגלל מכסה לא מספיקה למשאבים כמו מעבדים (CPU), מעבדי GPU, כתובות IP או MIG.
    • פתרון: אם הפרויקט הגיע למגבלת המכסה, בקשו להגדיל את המכסה.

הגדרות מתקדמות

להגדרות כמו יחידות GPU, מכונות וירטואליות מסוג Spot ושמירת מקום ב-Compute Engine יש דרישות ספציפיות משלהן ונקודות כשל פוטנציאליות שצריך לבדוק.

אימות הגדרות ה-GPU

ב-ComputeClasses בהתאמה אישית שמקצים צומתי GPU, מאמתים את הגדרת ה-GPU ב-ComputeClass בהתאמה אישית ומוודאים של-Pod יש את ה-toleration החובה nvidia.com/gpu.

  1. בודקים את ה-YAML של ComputeClass המותאם אישית כדי לראות אם יש בלוק gpu בתוך כלל עדיפות:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    

    בבלוק gpu צריך לציין שדה type ושדה count, לדוגמה:

    priorities:
    - machineType: a2-highgpu-1g
      gpu:
        type: nvidia-tesla-a100
        count: 1
    
  2. בדיקת ה-Pod כדי לראות אם הוא יכול להשתמש ב-GPU. לכל Pod שצריך לתזמן אותו בצומת GPU חייבת להיות סבילות nvidia.com/gpu, גם אם ה-Pod לא מבקש GPU בעצמו.

    kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.tolerations}'
    

    בודקים את הסבילות בשדה spec.tolerations.

הערכת התוצאה

  • ה-GPU מוגדר בצורה נכונה: אם ה-ComputeClass מגדיר את ה-GPU type ו-count, וה-Pods כוללים את ה-toleration nvidia.com/gpu, הגדרת ה-GPU נכונה. בדוגמה הבאה מוצגות ההגדרות הנדרשות של toleration:

    tolerations:
    - key: "nvidia.com/gpu"
      operator: "Exists"
      effect: "NoSchedule"
    
  • הגדרת ה-GPU לא תקינה:

    • הסבר: יכול להיות שחסרה ב-Pod סבילות (Toleration) נדרשת של nvidia.com/gpu, יכול להיות שה-ComputeClass לא תקין בגלל אי התאמות בשדה GPU, או יכול להיות שגרסת GKE לא מטפלת בהגדרת GPU בצורה נכונה.
    • פתרון: מבצעים את אחת מהפעולות הבאות:
      • משנים את קובץ ה-YAML של עומס העבודה כדי לכלול את ההגדרה המנדטורית של סבילות ל-GPU, ומחילים מחדש את קובץ ה-YAML.
      • משדרגים את אשכול GKE. אם ה-ComputeClass בהתאמה אישית לא תקין והבעיה קשורה לשדות GPU, צריך לבדוק אם יש בעיות מוכרות ולשדרג לגרסת GKE עם תיקון, למשל 1.31.8-gke.1045000 ואילך.

אימות ההגדרה של VM במודל Spot

אם אתם משתמשים ב-VM במודל Spot, ודאו שההגדרה spot: true נמצאת בכללי העדיפות הנכונים במניפסט של ComputeClass. חשוב גם להבין את לוגיקת התמחור של המידרוג האוטומטי באשכול.

בודקים את המניפסט של ComputeClass:

kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml

בפלט, חפשו את spot: true בשדה spec.priorities, לדוגמה:

priorities:
- machineFamily: n2d
  spot: true

יכול להיות שהמידרוג האוטומטי של אשכולות ישתמש בנתוני תמחור מ-us-central1 כבסיס להשוואה בין העלויות של סוגים שונים של VM במודל Spot, מה שיכול להוביל לבחירות שנראות לא אופטימליות באזורים אחרים. זו התנהגות מוכרת.

הערכת התוצאה

  • VM במודל Spot מוגדרות בצורה נכונה: אם השדה spot: true מצוין והכלי לשינוי גודל האשכול (cluster autoscaler) מקצה VM במודל Spot, ההגדרה פועלת כצפוי.
  • לא ניתן לתזמן מכונות וירטואליות במודל Spot:

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

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

        spec:
          priorities:
          - machineType: t2d-standard-48 # Cheapest in this region
            spot: true
          - machineType: n2d-standard-48 # Fallback Spot option
            spot: true
          - machineType: n2d-standard-48 # On-demand fallback
            spot: false
        

התקינות הכללית של המידרוג האוטומטי של האשכול

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

בדיקה של פעולות בו-זמניות

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

הצגת רשימה של פעולות מתמשכות שלא נמצאות במצב DONE:

gcloud container operations list \
    --location=LOCATION \
    --filter='targetLink~"/clusters/CLUSTER_NAME" AND status!=DONE'

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

הערכת התוצאה

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

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

      gcloud container operations wait OPERATION_ID --location LOCATION
      

      מחליפים את OPERATION_ID במזהה מהפלט של הפקודה list. אחרי שהפעולה של החסימה מסתיימת, כלי הגידול האוטומטי של האשכול אמור לחזור לפעולה רגילה.

בדיקת העברה פעילה

אם אתם רואים שעומסי עבודה נשארים בצמתים בעדיפות נמוכה יותר כשיש צמתים בעדיפות גבוהה יותר, כדאי לוודא שההעברה הפעילה מופעלת. אם השדה activeMigration.optimizeRulePriority מוגדר ל-false או מושמט ב-ComputeClass, ‏ GKE לא יעביר באופן אוטומטי עומסי עבודה לצמתים בעדיפות גבוהה יותר כשהם יהיו זמינים.

  1. כדי לבדוק את ההרשאות של ה-Pod, בודקים את השדה spec.tolerations. אם ל-Pod יש tolerations שתואמים ל-taints בכמה מאגרי צמתים עם עדיפויות שונות, יכול להיות שהמתזמן ימקם אותו בצומת עם עדיפות נמוכה יותר אם הוא יהיה זמין קודם.

    kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.tolerations[*]}{"\n"}'
    
  2. כדי לבדוק אם ההעברה הפעילה מופעלת, בודקים את השדה spec.activeMigration.optimizeRulePriority במניפסט של ComputeClass.

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    

הערכת התוצאה

  • העברה פעילה מופעלת: אם הערך בשדה activeMigration.optimizeRulePriority הוא true, ‏ GKE מנסה להעביר עומסי עבודה לצמתים בעדיפות גבוהה יותר כשהם הופכים לזמינים.
  • העברה פעילה מושבתת או לא יעילה:

    • פרשנות: אם השדה activeMigration.optimizeRulePriority הוא false או מושמט, או אם הסבילות של Pod רחבה מדי, עומסי העבודה נשארים בצמתים בעלי עדיפות נמוכה יותר כשצמתים בעלי עדיפות גבוהה יותר זמינים. הגישה הזו מאפשרת לתזמן עומסי עבודה בצמתים בעדיפות נמוכה יותר שמתפנים ראשונים.
    • פתרון: אם רוצים שהעומסים יועברו לצמתים עם עדיפות גבוהה יותר, מבצעים אחת מהפעולות הבאות:

      • כדי להעדיף מאגרי צמתים בעדיפות גבוהה יותר, אפשר להשתמש באילוצי תזמון ספציפיים יותר כמו nodeAffinity.
      • עורכים את המניפסט של ComputeClass כדי להגדיר את activeMigration.optimizeRulePriority: true ומחילים את קובץ ה-YAML:

        spec:
          activeMigration:
            optimizeRulePriority: true
        

פנייה לתמיכה

המאמרים הבאים