פתרון בעיות בעומסי עבודה שנפרסו

בדף הזה מוסבר איך לפתור שגיאות בעומסי העבודה שנפרסו ב-Google Kubernetes Engine ‏ (GKE).

עצות כלליות נוספות לפתרון בעיות באפליקציות זמינות במאמר פתרון בעיות באפליקציות במסמכי התיעוד של Kubernetes.

כל השגיאות: בדיקת הסטטוס של Pod

אם יש בעיות ב-Pods של עומס עבודה, Kubernetes מעדכן את הסטטוס של ה-Pod בהודעת שגיאה. כדי לראות את השגיאות האלה, בודקים את הסטטוס של Pod באמצעות מסוף Google Cloud או כלי שורת הפקודה kubectl.

המסוף

כך עושים את זה:

  1. נכנסים לדף Workloads במסוף Google Cloud .

    כניסה לדף Workloads

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

  3. בקטע Managed Pods (מאגרי מידע מנוהלים), לוחצים על הודעת סטטוס שגיאה כלשהי.

kubectl

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

kubectl get pods

הפלט אמור להיראות כך:

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

שגיאות אפשריות מופיעות בעמודה Status.

כדי לקבל מידע נוסף על Pod ספציפי, מריצים את הפקודה הבאה:

kubectl describe pod POD_NAME

מחליפים את POD_NAME בשם ה-Pod שרוצים לבדוק.

בפלט, השדה Events מציג מידע נוסף על השגיאות.

כדי לקבל מידע נוסף, אפשר לעיין ביומני מאגר התגים:

kubectl logs POD_NAME

היומנים האלה יכולים לעזור לכם לזהות אם פקודה או קוד במאגר גרמו לקריסת ה-Pod.

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

שגיאה: CrashLoopBackOff

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

מידע נוסף זמין במאמר בנושא פתרון בעיות שקשורות לאירועי CrashLoopBackOff.

שגיאות: ImagePullBackOff ו-ErrImagePull

סטטוס ImagePullBackOff או ErrImagePull מציין שלא ניתן לטעון את התמונה שנעשה בה שימוש על ידי מאגר מהרישום של התמונות.

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

שגיאה: OutOfPods

הסטטוס OutOfPods מציין שצומת לא יכול להריץ Pod כי הצומת הגיע לקיבולת המקסימלית של Pod.

תסמינים

יכול להיות שתופיע הודעה באירועים של ה-Pod, בדומה להודעה הבאה:

Node didn't have enough resource: pods, requested: 1, used: 32, capacity: 32

מטרה

השגיאה הזו מתרחשת כשמתקבלת בקשה לתזמן Pod בצומת שכבר הגיע לקיבולת המקסימלית שלו. מצב כזה יכול לקרות בדרך כלל במהלך הפעלת הצומת, למשל כשהרכיב kube-scheduler מקצה פודים לצומת חדש לפני שהסוכן kubelet דיווח על נוכחות של פודים סטטיים כמו הרכיב kube-proxy, שדורשים קיבולת פוד משלהם.

רזולוציה

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

  • הגדלת המספר המקסימלי של Pods לכל צומת. אם הצמתים מגיעים באופן עקבי למגבלת ה-Pod, צריך להגדיל את ההגדרה --max-pods-per-node של מאגרי הצמתים. יכול להיות שכדי להגדיל את מספר ה-Pods תצטרכו להשתמש בצמתים גדולים יותר כדי לעמוד בדרישות המשאבים המוגדלות.

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

  • שינוי פרופיל ההתאמה האוטומטית לעומס. אם אתם כבר משתמשים בשינוי גודל אוטומטי של אשכולות, נסו לשנות את פרופיל השינוי האוטומטי של הגודל לפרופיל balanced במקום לפרופיל optimize-utilization. הפרופיל optimize-utilization יכול להגדיל את הסיכוי לשגיאות OutOfPods כי הוא מנסה למקם את ה-Pods בצמתים שהשימוש בהם הוא הגבוה ביותר.

שגיאה: אי אפשר לתזמן את הפוד

סטטוס PodUnschedulable מציין שלא ניתן לתזמן את ה-Pod בגלל משאבים לא מספיקים או שגיאת הגדרה.

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

שימוש במדריך האינטראקטיבי בנושא פודים שלא ניתן לתזמן

אתם יכולים לפתור בעיות שקשורות ל-PodUnschedulable באמצעות מדריך אינטראקטיבי במסוף Google Cloud :

  1. עוברים לפלייבוק האינטראקטיבי של פודים שלא ניתן לתזמן:

    אל המדריך

  2. ברשימה הנפתחת Cluster, בוחרים את האשכול שרוצים לפתור בו בעיות. אם אתם לא מוצאים את האשכול, הזינו את שם האשכול בשדה Filter.

  3. בתפריט הנפתח Namespace, בוחרים את מרחב השמות שרוצים לפתור בו בעיות. אם אתם לא מוצאים את מרחב השמות, הזינו אותו בשדה Filter.

  4. כדי לזהות את הסיבה, כדאי לעבור על כל אחד מהסעיפים במדריך:

    1. בדיקת המעבד (CPU) והזיכרון
    2. בדיקה של מספר ה-Pods המקסימלי לכל צומת
    3. בדיקת ההתנהגות של הכלי להתאמת גודל הקבוצה
    4. בדיקת מצבי כשל אחרים
    5. השוואה בין אירועי שינוי
  5. אופציונלי: כדי לקבל התראות על PodUnschedulableשגיאות עתידיות, בקטע טיפים למניעת שגיאות בעתיד, בוחרים באפשרות יצירת התראה.

שגיאה: אין מספיק משאבים

סטטוס PodUnschedulable יכול להופיע אם אין מספיק מעבד, זיכרון או משאבים אחרים כדי לעמוד בדרישות של ה-Pod.

תסמינים

יכול להיות שתיתקלו בשגיאה שמציינת שאין מספיק מעבד, זיכרון או משאב אחר. לדוגמה: No nodes are available that match all of the predicates: Insufficient cpu (2). ההודעה הזו מציינת שבשני צמתים אין מספיק CPU זמין כדי למלא את הבקשות של Pod.

מטרה

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

האשכול שלכם מפעיל קונטיינרים של המערכת במרחב השמות kube-system. גם הקונטיינרים האלה משתמשים במשאבי האשכול.

רזולוציה

נסו את הפתרונות הבאים:

  • משנים את בקשת המשאבים של ה-Pod על ידי ציון ערך נמוך יותר בשדה spec: containers: resources: requests. בקשת ברירת המחדל למעבד היא ‎100m או 10% מהמעבד (או ליבה אחת).

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

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

שגיאה: MatchNodeSelector

שגיאה MatchNodeSelector מציינת שאין צמתים שתואמים לסלקטור התוויות של ה-Pod.

תסמינים

בסטטוס או באירועים של ה-Pod מופיעה שגיאה MatchNodeSelector.

מטרה

התוויות שצוינו בשדה nodeSelector במניפסט של ה-Pod לא קיימות באף צומת באשכול.

רזולוציה

כדי לפתור את השגיאה הזו, צריך לוודא שהתוויות שצוינו בשדה nodeSelector של ה-Pod תואמות לתוויות של צומת אחד לפחות באשכול:

  1. כדי לזהות את דרישות התווית שה-Pod מחפש, בודקים את השדה spec: nodeSelector שלו.

  2. כדי לבדוק אם יש תוויות שתואמות לדרישות של ה-Pod, צריך להציג את התוויות בפועל שהוקצו לצמתים באשכול:

    kubectl get nodes --show-labels
    
  3. אם צומת מיועד להריץ את ה-Pod הזה, צריך לצרף את התווית הנדרשת:

    kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫NODE_NAME: הצומת שרוצים להוסיף לו תווית.
    • ‫LABEL_KEY: המפתח של התווית.
    • ‫LABEL_VALUE: הערך של התווית.

מידע נוסף זמין במאמר הקצאת פודים לצמתים במאמרי העזרה של Kubernetes.

שגיאה: PodToleratesNodeTaints

שגיאה PodToleratesNodeTaints מציינת שלא ניתן לתזמן את ה-Pod לאף צומת כי ל-Pod אין סבילות שמתאימות להכתמות של הצומת הקיימות.

תסמינים

בסטטוס או באירועים של ה-Pod מופיעה שגיאה PodToleratesNodeTaints.

מטרה

אי אפשר לתזמן את ה-Pod לאף צומת כי אין לו tolerations שתואמים ל-taints קיימים של צומת.

רזולוציה

  1. בודקים את ה-taints בצומת:

    kubectl describe nodes NODE_NAME
    

    בפלט, בודקים את השדה Taints שמכיל רשימה של צמדי מפתח/ערך והשפעות על התזמון. אם האפקט שמופיע הוא NoSchedule, אי אפשר לתזמן אף Pod בצומת הזה, אלא אם יש לו toleration תואם.

  2. מסירים את הכתם מהצומת. לדוגמה, כדי להסיר טאנט מסוג NoSchedule, מריצים את הפקודה הבאה:

    kubectl taint nodes NODE_NAME key:NoSchedule-
    

שגיאה: PodFitsHostPorts

השגיאה PodFitsHostPorts מציינת שצומת מנסה להשתמש ביציאה שכבר תפוסה.

תסמינים

בסטטוס של ה-Pod מופיעה שגיאה PodFitsHostPorts.

מטרה

‫Pod מבקש יציאת מארח שכבר נמצאת בשימוש על ידי Pod או תהליך אחר בצומת היעד.

רזולוציה

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

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

שגיאה: אין זמינות מינימלית

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

תסמינים

  • מוצגת השגיאה Does not have minimum availability.

  • הסטטוס של הצומת מציג סטטוס SchedulingDisabled או סטטוס Cordoned.

מטרה

הסטטוס 'מוקצה' של הצומת מונע תזמון של Pods חדשים בו.

רזולוציה

כדי שהצומת יהיה זמין שוב לתזמון של Pods, צריך לבטל את ההגדרה שלו כ-cordon:

המסוף

כך עושים את זה:

  1. נכנסים לדף Google Kubernetes Engine במסוף Google Cloud .

    מעבר אל Google Kubernetes Engine

  2. בוחרים את האשכול שרוצים לבדוק. בכרטיסייה Nodes מוצגים הצמתים והסטטוס שלהם.

כדי להפעיל את התזמון בצומת:

  1. ברשימה, לוחצים על הצומת שרוצים לחקור.

  2. בקטע Node Details, לוחצים על Uncordon.

kubectl

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

kubectl get nodes

כדי להפעיל את התזמון בצומת, מריצים את הפקודה:

kubectl uncordon NODE_NAME

שגיאה: הגעת למגבלה המקסימלית של Pods לכל צומת

השגיאה Too many pods מציינת שלא ניתן לתזמן Pod כי צומת היעד הגיע לקיבולת המקסימלית שהוגדרה ל-Pod.

תסמינים

  • ה-Pods תקועים במצב Unschedulable.
  • מוצגת הודעה שכוללת את הביטוי Too many pods.

מטרה

כל הצמתים באשכול הגיעו למגבלה של Maximum Pods per node.

רזולוציה

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

  1. בודקים את ההגדרה של Maximum pods per node בכרטיסייה Nodes (צמתים) בפרטי אשכול GKE במסוף Google Cloud .

  2. כדי לקבל רשימה של צמתים:

    kubectl get nodes
    
  3. לכל צומת, בודקים את מספר ה-Pods שפועלים בצומת:

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. אם מגיעים למגבלה, צריך להוסיף מאגר צמתים חדש או להוסיף צמתים נוספים למאגר הצמתים הקיים.

הבעיה: הגעה לגודל המקסימלי של מאגר הצמתים כשהתכונה Cluster Autoscaler מופעלת

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

תסמינים

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

מטרה

מאגר הצמתים הגיע לגודל המקסימלי בהתאם להגדרת ה-autoscaler של האשכול.

רזולוציה

כדי להגדיל את הגודל המקסימלי של מאגר הצמתים, צריך לשנות את ההגדרה של Cluster Autoscaler.

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

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

תסמינים

‫GKE לא יכול לתזמן את ה-Pod עם מאגר הצמתים.

מטרה

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

רזולוציה

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

שגיאה: Unbound PersistentVolumeClaims

שגיאה מסוג Unbound PersistentVolumeClaims מציינת שה-Pod מפנה ל-PersistentVolumeClaim שלא מאוגד.

תסמינים

בסטטוס או באירועים של ה-Pod מופיעה שגיאה Unbound PersistentVolumeClaims.

מטרה

השגיאה הזו יכולה להתרחש בגלל אחת מהסיבות הבאות:

  • הקצאת PersistentVolume נכשלה.
  • קרתה שגיאת הגדרה במהלך הקצאה מראש ידנית של PersistentVolume ושל הקישור שלו ל-PersistentVolumeClaim.

רזולוציה

  1. כדי לוודא שהקצאת המשאבים נכשלה, צריך לקבל את האירועים של PersistentVolumeClaim:

    kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫STATEFULSET_NAME: השם של אובייקט StatefulSet.
    • ‫PVC_NAME: השם של אובייקט PersistentVolumeClaim.
  2. מנסים להקצות מראש את נפח האחסון שוב.

שגיאה: חריגה מהמכסה

אם GKE מנסה להגדיל את קנה המידה של האשכול כדי לתזמן Pod, אבל נתקל במגבלות של מכסת המשאבים, הגדלת קנה המידה נכשלת.

תסמינים

מופיעה הודעת השגיאה scale.up.error.quota.exceeded באירועים של ה-Pod.

מטרה

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

רזולוציה

מוודאים שבפרויקט יש מספיק מכסה ב-Compute Engine כדי ש-GKE יוכל להגדיל את האשכול. למידע נוסף, ראו שגיאות ScaleUp.

בעיה: ממשקי API שהוצאו משימוש

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

תסמינים

אי אפשר לפרוס או להריץ עומסי עבודה בגלל שימוש ב-API שהוצא משימוש.

מטרה

המניפסטים משתמשים בממשקי API שהוצאו משימוש והוסרו בגרסה המשנית של האשכול.

רזולוציה

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

שגיאה: לא היו יציאות פנויות ליציאות ה-Pod המבוקשות

קישור של Pod ליציאת מארח מגביל את המקומות שבהם GKE יכול לתזמן את ה-Pod, כי כל שילוב של כתובת hostIP, הגדרת hostPort וערך protocol חייב להיות ייחודי.

תסמינים

מופיעה שגיאה שדומה לזו:

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

מטרה

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

רזולוציה

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

  • כדאי לפעול לפי השיטות המומלצות ל-Kubernetes ולהשתמש בשירות NodePort במקום ביציאת מארח.
  • אם אתם חייבים להשתמש ביציאת מארח, בדקו את המניפסטים של ה-Pods וודאו שלכל ה-Pods באותו צומת יש ערכים ייחודיים שמוגדרים בשדה hostPort.

בעיה: כשלים באפליקציה ובבדיקה בקבוצות Pod

הבעיה הזו מתרחשת כשמפעילים אפליקציות שמשתמשות ב-HTTPS כדי לתקשר עם שרת.

תסמינים

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

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

    probeResult="failure" output="Get "https://example.com/healthy": EOF"
    
  • ה-Pods פועלים כצפוי, אבל ביומני האפליקציה מוצגים כשלים בחיבור.

מטרה

בגרסאות 1.30 ואילך של Kubernetes נעשה שימוש בגרסאות של Golang שמשביתות את הסטים הבאים של אלגוריתמים להצפנה (cipher suite) ב-TLS:

  • TLS_RSA_WITH_AES_128_GCM_SHA256
  • TLS_RSA_WITH_AES_256_GCM_SHA384
  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_3DES_EDE_CBC_SHA

רזולוציה

שימוש בסטים נתמכים של אלגוריתמים להצפנה (cipher suite) מ-TLS 1.2 ומגרסאות מאוחרות יותר.

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