במאמר הזה מוסבר איך לפתור בעיות שבהן עומסי עבודה של GKE לא מתוזמנים בצמתים שהוגדרו על ידי ComputeClass מותאם אישית, או כשכלי ההתאמה האוטומטית של האשכול לא מקצה את סוגי המכונות הצפויים.
המסמך הזה מיועד למפתחי אפליקציות ולאדמינים ומפעילים של פלטפורמות שמשתמשים ב-ComputeClasses בהתאמה אישית כדי לנהל את תזמון עומסי העבודה ואת היצירה האוטומטית של מאגרי צמתים ב-GKE. מידע נוסף על התפקידים הנפוצים ומשימות לדוגמה שמוזכרים ב Cloud de Confiance by S3NS תוכן זמין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
מושגים מרכזיים
כדי לעזור לכם לפתור בעיות, חשוב שתכירו את הרכיבים והמנגנונים הבאים של GKE:
Custom ComputeClass: משאב ספציפי ל-GKE שמאפשר להגדיר רשימה מתועדפת של תצורות צמתים להתאמה אוטומטית של גודל האשכול. מידע נוסף זמין במאמר בנושא מחלקות Compute בהתאמה אישית.
Cluster autoscaler: הרכיב שמוסיף או מסיר צמתים באשכול באופן אוטומטי בהתבסס על הביקוש לעומס העבודה. מידע נוסף זמין במאמר מידע על שינוי אוטומטי של גודל אשכול GKE.
יצירה אוטומטית של מאגר צמתים: המידרוג האוטומטי של אשכול GKE יוצר ומנהל מאגרי צמתים באופן אוטומטי על סמך דרישות עומס העבודה. מידע נוסף מופיע במאמר בנושא יצירה אוטומטית של מאגרי צמתים.
לוגיקת חזרה: המנגנון שבו הכלי לשינוי גודל האשכול מנסה להקצות קודם צמתים שתואמים לכלל בעדיפות הגבוהה ביותר. מידע נוסף זמין במאמר בנושא בחירת עדיפויות חלופיות לחישוב.
פתרון בעיות לפי סימפטומים
במסמך הזה מפורטים שלבים לפתרון בעיות לפי סדר, החל מבדיקות בסיסיות ועד להגדרות מתקדמות יותר. כדי לקבל אבחון מקיף יותר, מומלץ לבצע את השלבים האלה לפי הסדר. לחלופין, אם נתקלתם בבעיות ספציפיות, תוכלו להיעזר בקישורים הרלוונטיים בטבלה הבאה:
| תיאור הבעיה | שלבים לפתרון בעיות |
|---|---|
פוד שמבקש ComputeClass בהתאמה אישית תקוע במצב Pending |
|
| המידרוג האוטומטי של האשכול לא יוצר צמתים חדשים שתואמים ל-ComputeClass בהתאמה אישית | |
| המידרוג האוטומטי של האשכול יוצר סוגי מכונות שמוגדרים כברירת מחדל במקום סוגים מיוחדים | ניתוח התנהגות של מעבר לגיבוי אוטומטי של שינוי גודל |
הפלט מהפקודה kubectl describe computeclass מציג סטטוס לא תקין |
אימות של הגדרות מותאמות אישית של ComputeClass |
| עומסי העבודה לא מועברים לצמתים עם עדיפות גבוהה יותר | אימות תקינות כללית של המידרוג האוטומטי באשכול |
| בעיות בתזמון של עומסי עבודה של מכונות וירטואליות עם GPU או מכונות וירטואליות מסוג Spot |
בעיות שלא נכללות בהיקף התמיכה
המסמך הזה לא מתייחס לבעיות הבאות:
- בעיות כלליות ברשת GKE, כמו קישוריות בין Pod ל-Pod או איזון עומסים בשירות.
- בעיות שקשורות ל-Horizontal Pod Autoscaler (HPA) או ל-Vertical Pod Autoscaler (VPA).
- בעיות שלא קשורות למנגנון ComputeClass בהתאמה אישית, כמו שגיאות ברמת האפליקציה או בעיות ב-PersistentVolume שלא קשורות למגבלות התזמון.
- בעיות במכסת המשאבים או בזמינות המשאבים שלא קשורות ישירות ללוגיקת הגיבוי של ComputeClass.
זיהוי משתני placeholder
כדי להתאים אישית את הפקודות במסמך הזה, מזינים את הערכים הספציפיים בעמודה Variable. הערכים שערכתם מסונכרנים אוטומטית בכל בלוקי הקוד והפקודות.
| משתנה | תיאור |
|---|---|
| PROJECT_ID | מזהה הפרויקט Cloud de Confiance . |
| LOCATION | האזור או התחום (zone) של Compute Engine שבו נמצא האשכול. |
| CLUSTER_NAME | השם של האשכול. |
| NODE_POOL_NAME | השם של מאגר הצמתים לבדיקה (אם רלוונטי לאשכולות רגילים). |
| CUSTOM_COMPUTECLASS_NAME | השם של ComputeClass מותאם אישית שה-Pod מבקש. |
| NAMESPACE | מרחב השמות של ה-Pod שלא ניתן לתזמן. |
| POD_NAME | השם של ה-Pod שלא ניתן לתזמן. |
לפני שמתחילים
כדי לקבל את ההרשאות שדרושות לביצוע המשימות שמתוארות במאמר הזה, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט Cloud de Confiance by S3NS :
-
כדי לגשת לאשכולות GKE:
Kubernetes Engine Cluster Viewer (
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 המותאמת אישית מתבצעת בצורה נכונה.
רשימת ה-Pods במצב
Pending:kubectl get pods --all-namespaces -o wide | grep Pendingבודקים את המפרט של ה-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 מותאמים אישית, צריך GKE בגרסה 1.30.3-gke.1451000 ואילך. מוודאים שהגרסה של האשכול תומכת ב-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 בהתאמה אישית יכולות למנוע תזמון של פודים או הקצאה של צמתים ב-GKE.
בדיקת התקינות והסטטוס של ComputeClass
מוודאים ש-GKE מדווח על ComputeClass בהתאמה אישית כעל תקין.
הצגת רשימה של כל המשאבים של
ComputeClass:kubectl get computeclassמתארים את משאב
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 כך שישתמש בסוג מכונה שנתמך באזור או באזור הזמינות של האשכול.
-
- פירוש: ה-ComputeClass המותאם אישית לא תקין. בודקים את השדות
אימות המדיניות של unsatisfiable
השדה whenUnsatisfiable קובע את ההתנהגות כשאי אפשר לעמוד בכללי העדיפות.
בודקים את המדיניות:
kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
בודקים את השדה spec.whenUnsatisfiable בפלט. השדה הזה יכול לקבל אחד מהערכים הבאים:
-
DoNotScaleUp: אם אי אפשר ליצור צמתים מועדפים, הרצפים נשארים במצבPending. -
ScaleUpAnyway: יכול להיות שפודים יפעלו על סוגי צמתים שמוגדרים כברירת מחדל (כמו סדרת E2) אם הצמתים המועדפים לא זמינים.
הערכת התוצאה
ההשפעה של המדיניות whenUnsatisfiable תלויה בערך שלה:
- אם הערך הוא
DoNotScaleUp:- הסבר: זו התנהגות צפויה כשאין כללי עדיפות שאפשר לעמוד בהם, יכול להיות בגלל חוסר זמינות של משאבים או מגבלות מכסה. אם הפודים צריכים לחכות לחומרה ספציפית, הערך הזה נכון.
- פתרון: אם הפעלת עומס העבודה חשובה יותר מהפעלתו בחומרה ספציפית, משנים את המדיניות ל-
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 תואם למאפיינים של הצמתים שהוקצו על ידי ComputeClass מותאם אישית.
אימות בקשות למשאבי Pod
בודקים אם אפשר לספק את בקשות ה-CPU, הזיכרון וה-GPU של ה-Pod לפחות על ידי אחד מסוגי המכונות שמוגדרים בשדה priorities של ה-ComputeClass בהתאמה אישית.
קבלת בקשות למשאבי Pod:
kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.containers[*].resources.requests}'בודקים את הפלט כדי לראות את הבקשות של
cpu,memoryו-GPU, כמוnvidia.com/gpu.משווים את הבקשות האלה לסוגי המכונות שמוגדרים בשדה
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. לדוגמה:
- צמצום בקשות המשאבים של Pod: אם בקשות המשאבים גבוהות, כדאי להקטין את הערכים של
spec: priorities: - machineType: n2d-highmem-96 # A larger machine type spot: true # ... other priorities- הסבר: אי אפשר לתזמן את ה-Pod כי אף סוג מכונה ב-ComputeClass לא מספק מספיק CPU, זיכרון או GPU. מצב כזה יכול לקרות גם אם השדה
בדיקה של 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}'
הערכת התוצאה
- הגדרות נכונות של tolerations: ה-taints וה-tolerations מוגדרים בצורה נכונה.
Missing tolerations:
- הסבר: חוסר סבילות מונע את התזמון של ה-Pod בצמתים עם כתמי חומרה מיוחדים. לדוגמה, אם ComputeClass משתמש בצמתי GPU, יכול להיות שחסר ל-Pod את
nvidia.com/gpu=present:NoScheduletoleration. לדרישות ספציפיות ל-GPU, אפשר לעיין במאמר בנושא אימות הגדרת ה-GPU. פתרון: בשדה
tolerationsבמפרט ה-Pod, מוסיפים את ההגדרות הנדרשות של tolerations כדי להתאים ל-taints בצמתים שמוגדרים על ידי ComputeClass. לדוגמה, עבור צמתי GPU, הוסיפו טולרנטיות לדחיית ה-nvidia.com/gpu=present:NoScheduleבאופן הבא:spec: template: spec: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" # ... other tolerations and Pod spec
- הסבר: חוסר סבילות מונע את התזמון של ה-Pod בצמתים עם כתמי חומרה מיוחדים. לדוגמה, אם ComputeClass משתמש בצמתי GPU, יכול להיות שחסר ל-Pod את
הגדרה של מאגר צמתים (אשכולות רגילים)
ב-GKE, במאגרי צמתים שנוצרו באופן ידני, צריך להוסיף תוויות ו-taints כדי שהם יפעלו עם ComputeClass בהתאמה אישית.
אימות התוויות וההכתמות של מאגר הצמתים
מזהים את מאגרי הצמתים ב-ComputeClass המותאם אישית. אם ה-ComputeClass המותאם אישית משתמש בשדה
nodePools, שימו לב לשמות של מאגרי הצמתים שמופיעים ברשימה:kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yamlלכל מאגר צמתים שזיהיתם, בודקים את ההגדרה שלו:
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ואת הכתםcloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule. מאגר הצמתים הוגדר באופן שגוי:
- הסבר: מאגר הצמתים לא הוגדר עם התווית וההכתמה שנדרשות כדי לשייך אותו ל-ComputeClass המותאם אישית.
פתרון: מעדכנים את מאגר הצמתים כדי להוסיף את התווית וההכתמה:
הוספה או עדכון של תווית צומת:
gcloud container node-pools update NODE_POOL_NAME \ --cluster=CLUSTER_NAME --location=LOCATION \ --node-labels=cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAMEהוספה או עדכון של דחייה בצומת:
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, צריך להגדיר בצורה נכונה את היצירה האוטומטית של מאגר הצמתים.
בדיקה שהיצירה האוטומטית של מאגר הצמתים מופעלת
בודקים אם השדה
nodePoolAutoCreation.enabledב-ComputeClass המותאם אישית מוגדר ל-true:kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yamlבודקים אם יצירה אוטומטית של מאגר צמתים מופעלת באשכול:
gcloud container clusters describe CLUSTER_NAME --location LOCATION --format="value(autoscaling.enableNodeAutoprovisioning)"
אם אחד מהם מושבת, לא ייווצרו מאגרי צמתים חדשים עבור ComputeClass בהתאמה אישית.
הערכת התוצאה
- היצירה האוטומטית של מאגר הצמתים מופעלת: בשדה
nodePoolAutoCreation.enabledשל ComputeClass מוגדר הערךtrue, והקצאת צמתים אוטומטית (NAP) מופעלת ברמת האשכול. היצירה האוטומטית של מאגר הצמתים מושבתת:
- הסבר: יצירה אוטומטית של מאגר צמתים מושבתת אם הערך של השדה
nodePoolAutoCreation.enabledהואfalseאו חסר ב-ComputeClass, או אם הקצאת משאבים אוטומטית של צמתים ברמת האשכול מושבתת. פתרון: מפעילים יצירה אוטומטית של מאגר צמתים:
עורכים את קובץ ה-YAML של ComputeClass בהתאמה אישית כדי לכלול את
nodePoolAutoCreation: enabled: true:spec: # ... priorities nodePoolAutoCreation: enabled: trueהפעלת יצירה אוטומטית של מאגר צמתים ברמת האשכול והגדרת מגבלות משאבים:
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) וזיכרון. אם השימוש הנוכחי באשכול בתוספת המשאבים של צומת חדש חורג מהמגבלות האלה, המערכת לא תקצה צמתים חדשים באמצעות יצירה אוטומטית של מאגר צמתים.
כדי לראות את מגבלות המשאבים:
gcloud container clusters describe CLUSTER_NAME --location LOCATION --format="value(autoscaling.resourceLimits)"בפלט מפורטים השדות
resourceType,minimumו-maximumשל ה-CPU והזיכרון (ב-GB).בודקים את סוגי המכונות בעדיפויות של ComputeClass בהתאמה אישית. כדאי לבדוק את מפרטי המעבד והזיכרון במסמכי התיעוד של סוגי המכונות.
קובעים את הקיבולת הכוללת הנוכחית של המעבד (CPU) והזיכרון של כל הצמתים באשכול. סכום הקיבולת הנוכחית בתוספת המשאבים של צומת חדש פוטנציאלי לא יכול לחרוג מהמגבלה המקסימלית ליצירה אוטומטית של מאגר צמתים.
הערכת התוצאה
- קיבולת מספקת: יש למעבד ולזיכרון של האשכול קיבולת מספקת במסגרת מגבלות המשאבים, כדי שההקצאה האוטומטית של מאגר הצמתים תוכל להקצות צומת חדש.
חריגה מהמגבלות:
- הסבר: אי אפשר להקצות צמתים חדשים למאגר הצמתים כי האשכול הגיע למגבלות של המעבד או הזיכרון, או שהמגבלות שהוגדרו נמוכות מדי לסוגי המכונות ב-ComputeClass.
פתרון: מגדילים את מכסות המשאבים ליצירה אוטומטית של מאגר צמתים:
קובעים מגבלות מקסימליות חדשות שמתחשבות בשימוש הנוכחי ובצמיחה העתידית, כולל סוגי המכונות הגדולים ביותר ב-ComputeClass המותאם אישית.
עדכון מגבלות המשאבים ליצירה אוטומטית של מאגר צמתים אפשר להגדיר כמה משאבים בפקודה אחת:
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
ניתוח התנהגות של חזרה למצב קודם של כלי להתאמה אוטומטית של משאבים
בסעיף הזה מוסבר איך לחקור גורמים חיצוניים כדי להבין למה המידרוג האוטומטי של האשכול עשוי לדלג על אפשרויות מועדפות ולהשתמש בחלופות, או למה הוא לא מצליח לבצע סילומיות אנכית (scale up).
ב-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 ומריצים את השאילתה הבאה כדי למצוא אירועים של שינוי גודל אוטומטי שעשויים להצביע על חוסר זמינות של משאבים:
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 :
- במסוף Cloud de Confiance , עוברים אל Compute Engine > Instance groups.
- מוצאים את ה-MIG שמתאים למאגר הצמתים שלא מצליח להתרחב.
- לוחצים על השם של ה-MIG ועוברים לכרטיסייה שגיאות. מחפשים הודעות שמעידות על מיצוי המשאבים.
באמצעות שאילתה ב-Cloud Logging:
- במסוף Cloud de Confiance , עוברים אל Cloud Logging > Logs explorer.
- מריצים את השאילתה הבאה כדי לבדוק אם יש שגיאות שנובעות ממיצוי משאבים ב-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לא מופיעות ביומנים, סביר להניח שחוסר הזמינות של המשאבים לא גרם לבעיה בהרחבת הקיבולת. המשאבים לא זמינים:
- הסבר: הקצאת הצומת נכשלת בגלל ביקוש גבוה זמני לסוג מכונה ספציפי (במיוחד מכונות וירטואליות מסוג 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 לעומסי עבודה קריטיים שלא יכולים לסבול עיכובים.
אימות מכסות בפרויקט
מוודאים שלפרויקט יש מספיק מכסה למשאבים, כמו מעבדים (CPU), מעבדים גרפיים (GPU) וכתובות IP שנדרשים לצמתים החדשים.
בודקים ביומני ה-Autoscaler אם יש שגיאות שקשורות למכסת השימוש. אפשר להשתמש ב-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בדיקת המכסות במסוף Cloud de Confiance :
- במסוף Cloud de Confiance , נכנסים אל IAM & Admin > Quotas.
- מסננים לפי השירות Compute Engine API.
- בודקים את השימוש במדדים רלוונטיים כמו מעבדים (CPU), מעבדים גרפיים (GPU) (מכל הסוגים) וכתובות IP בשימוש באזור שבו נמצא אשכול GKE. בודקים שהשימוש הנוכחי לא הגיע למגבלה.
הערכת התוצאה
- המכסה נמוכה מהמגבלות: אם השימוש במכסה נמוך ממגבלות המכסה ולא נמצאו שגיאות
QUOTA_EXCEEDEDביומנים, מגבלות המכסה לא יחסמו את ההרחבה. - חריגה מהמכסה:
- פירוש: הקצאת הצמתים נכשלת בגלל מכסה לא מספקת למשאבים כמו מעבדים (CPU), מעבדים גרפיים (GPU), כתובות IP או MIG.
- פתרון: אם הפרויקט הגיע למגבלת מכסה, מגישים בקשה להגדלת המכסה.
הגדרות מתקדמות
להגדרות כמו יחידות GPU, מכונות וירטואליות מסוג Spot ושמירת מקום ב-Compute Engine יש דרישות ספציפיות משלהן ונקודות כשל פוטנציאליות שצריך לבדוק.
אימות הגדרות ה-GPU
במקרה של ComputeClasses בהתאמה אישית שמקצים צמתים של GPU, צריך לאמת את הגדרת ה-GPU ב-ComputeClass בהתאמה אישית ולוודא של-Pod יש את ה-toleration nvidia.com/gpu הנדרש.
בודקים את קובץ ה-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בדיקת ה-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 כולל את ה-tolerationnvidia.com/gpu, הגדרת ה-GPU נכונה. בדוגמה הבאה מוצגות ההגדרות הנדרשות של toleration:tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule"הגדרת ה-GPU שגויה:
- הסבר: יכול להיות שחסרה ב-Pod סבילות (toleration) נדרשת, יכול להיות שה-ComputeClass לא תקין בגלל אי התאמות בשדה GPU, או יכול להיות שגרסת GKE לא מטפלת בהגדרת GPU בצורה נכונה.
nvidia.com/gpu - פתרון: מבצעים אחת מהפעולות הבאות:
- משנים את קובץ ה-YAML של עומס העבודה כדי לכלול את ההגדרה המנדטורית של סבילות ל-GPU, ומחילים מחדש את קובץ ה-YAML.
- משדרגים את אשכול GKE. אם ה-ComputeClass המותאם אישית לא תקין והבעיה קשורה לשדות GPU, כדאי לבדוק אם יש בעיות ידועות ולשדרג לגרסת GKE עם תיקון, למשל 1.31.8-gke.1045000 ואילך.
- הסבר: יכול להיות שחסרה ב-Pod סבילות (toleration) נדרשת, יכול להיות שה-ComputeClass לא תקין בגלל אי התאמות בשדה GPU, או יכול להיות שגרסת GKE לא מטפלת בהגדרת GPU בצורה נכונה.
אימות ההגדרה של מכונות וירטואליות מסוג Spot
אם אתם משתמשים במכונות וירטואליות מסוג Spot, ודאו שההגדרה spot: true נמצאת בכללי העדיפות הנכונים במניפסט של ComputeClass. בנוסף, חשוב להבין את לוגיקת התמחור של המידרוג האוטומטי באשכול.
בודקים את מניפסט ComputeClass:
kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
בפלט, חפשו את spot: true בשדה spec.priorities, לדוגמה:
priorities:
- machineFamily: n2d
spot: true
יכול להיות שהכלי לשינוי גודל אוטומטי של אשכולות ישתמש בנתוני תמחור מ-us-central1 כנקודת השוואה כשמשווים את העלות של סוגים שונים של מכונות וירטואליות מסוג Spot, מה שיכול להוביל לבחירות שנראות לא אופטימליות באזורים אחרים. זוהי התנהגות מוכרת.
הערכת התוצאה
- מכונות וירטואליות מסוג Spot מוגדרות בצורה נכונה: אם השדה
spot: trueמצוין והכלי לשינוי גודל האשכול (cluster autoscaler) מקצה מכונות וירטואליות מסוג Spot, ההגדרה פועלת כמצופה. מכונות וירטואליות במודל Spot שלא ניתן לתזמן:
- הסבר: יכול להיות שהתזמון של פודים שדורשים מכונות וירטואליות מסוג Spot נכשל בגלל חוסר זמינות של משאבים באזור היעד, או בגלל שהכלי לשינוי גודל האשכול באופן אוטומטי בוחר סוג אחר של מכונה וירטואלית על סמך מודל התמחור
us-central1שלו. פתרון:
- אם אתם חושדים שהמשאב לא זמין, כדאי לעיין במאמר בדיקה של חוסר זמינות של משאבים.
כדי לשלוט בבחירה של מכונות 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
- הסבר: יכול להיות שהתזמון של פודים שדורשים מכונות וירטואליות מסוג Spot נכשל בגלל חוסר זמינות של משאבים באזור היעד, או בגלל שהכלי לשינוי גודל האשכול באופן אוטומטי בוחר סוג אחר של מכונה וירטואלית על סמך מודל התמחור
התקינות הכללית של המידרוג האוטומטי של האשכול
בקטע הזה מוסבר איך לבדוק אם יש בעיות שלא קשורות ישירות להגדרה של 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 לא יעביר באופן אוטומטי עומסי עבודה לצמתים בעלי עדיפות גבוהה יותר כשהם יהיו זמינים.
כדי לבדוק את ההרשאות של ה-Pod, בודקים את השדה
spec.tolerations. אם ל-Pod יש tolerations שתואמים ל-taints בכמה מאגרי צמתים עם עדיפויות שונות, יכול להיות שהמתזמן ימקם אותו בצומת עם עדיפות נמוכה יותר אם הוא יהיה זמין קודם.kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.tolerations[*]}{"\n"}'כדי לבדוק אם ההעברה הפעילה מופעלת, בודקים את השדה
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
- כדי להעדיף מאגרי צמתים עם עדיפות גבוהה יותר, אפשר להשתמש במגבלות תזמון ספציפיות יותר כמו
- הסבר: אם השדה
פנייה לתמיכה
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו לקבל עזרה נוספת במאמר בנושא קבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אפשר גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה נוספת מהקהילה. - פתיחת דיווחים על בעיות או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.
המאמרים הבאים
- החלת ComputeClasses על Pods כברירת מחדל
- הגדרת הפרדה בין עומסי עבודה ב-GKE
- פתרון בעיות בהגדלת הקיבולת של המידרוג האוטומטי של אשכולות