בדף הזה מוסבר איך לפתור שגיאות בעומסי העבודה שנפרסו ב-Google Kubernetes Engine (GKE).
עצות כלליות נוספות לפתרון בעיות באפליקציות זמינות במאמר פתרון בעיות באפליקציות בתיעוד של Kubernetes.
כל השגיאות: בדיקת הסטטוס של ה-Pod
אם יש בעיות ב-Pods של עומס עבודה, מערכת Kubernetes מעדכנת את סטטוס ה-Pod בהודעת שגיאה. כדי לראות את השגיאות האלה, בודקים את הסטטוס של Pod באמצעות מסוף Google Cloud או כלי שורת הפקודה kubectl.
המסוף
כך עושים את זה:
נכנסים לדף Workloads במסוף Google Cloud .
בוחרים את עומס העבודה שרוצים לבדוק. בכרטיסייה סקירה כללית מוצג הסטטוס של עומס העבודה.
בקטע 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 מקצה Pods לצומת חדש לפני ש-kubelet דיווח על נוכחות של Pods סטטיים כמו kube-proxy, שדורשים קיבולת Pod משלהם.
הפתרון:
כדי לפתור את הבעיה, נסו אחד מהפתרונות הבאים:
הגדלת מספר ה-Pods המקסימלי לכל צומת. אם הצמתים מגיעים באופן עקבי למגבלת ה-Pod, צריך להגדיל את ההגדרה
--max-pods-per-nodeשל מאגרי הצמתים. יכול להיות שיהיה צורך להגדיל את הצמתים כדי לעמוד בדרישות המשאבים המוגדלות.מפעילים את המידרוג האוטומטי של האשכול ואת ההקצאה האוטומטית של הצמתים. אם אתם נתקלים לעיתים קרובות במצב שבו אין מספיק קיבולת של Pod, הפעלה של התאמה אוטומטית של גודל האשכול ושל הקצאת צמתים אוטומטית (NAP) יכולה לעזור לוודא שיש באשכול מספיק צמתים כדי לעמוד בדרישות של עומסי העבודה.
שינוי פרופיל ההתאמה האוטומטית לעומס. אם כבר משתמשים ב-cluster autoscaler, כדאי לנסות לשנות את פרופיל ההתאמה האוטומטית לעומס ל-
balancedבמקום ל-optimize-utilization.optimize-utilizationהפרופיל יכול להגדיל את הסיכוי לשגיאותOutOfPodsכי הוא מנסה למקם את ה-Pods בצמתים שהשימוש בהם הוא הגבוה ביותר.
שגיאה: אי אפשר לתזמן את הפוד
סטטוס PodUnschedulable מציין שלא ניתן לתזמן את ה-Pod בגלל משאבים לא מספיקים או שגיאת הגדרה כלשהי.
אם הגדרתם מדדים של מישור הבקרה, תוכלו למצוא מידע נוסף על השגיאות האלה במדדים של מתזמן ובמדדים של שרת API.
שימוש במדריך האינטראקטיבי של Pods שלא ניתן לתזמן
אתם יכולים לפתור בעיות שקשורות ל-PodUnschedulable באמצעות מדריך אינטראקטיבי במסוף Google Cloud :
כדאי לעיין במדריך האינטראקטיבי בנושא פודים שלא ניתן לתזמן:
ברשימה הנפתחת Cluster, בוחרים את האשכול שרוצים לפתור בו בעיות. אם אתם לא מוצאים את האשכול, מזינים את שם האשכול בשדה Filter.
בתפריט הנפתח Namespace, בוחרים את מרחב השמות שרוצים לפתור בו בעיות. אם לא מוצאים את מרחב השמות, מזינים אותו בשדה Filter.
כדי לעזור לכם לזהות את הסיבה, כדאי לעבור על כל הקטעים במדריך:
- בדיקת המעבד (CPU) והזיכרון
- בדיקת מספר הפודים המקסימלי לכל צומת
- בדיקת התנהגות של כלי להתאמה אוטומטית של מספר השרתים
- בדיקת מצבי כשל אחרים
- השוואה בין אירועי שינוי
אופציונלי: כדי לקבל התראות על שגיאות עתידיות של
PodUnschedulable, בקטע Future Mitigation Tips (טיפים למניעת שגיאות בעתיד), בוחרים באפשרות Create an Alert (יצירת התראה).
שגיאה: אין מספיק משאבים
יכול להיות שתיתקלו בשגיאה שמציינת שאין מספיק מעבד, זיכרון או משאב אחר. לדוגמה: No nodes are available that match all of the predicates:
Insufficient cpu (2), שמציין שבשני צמתים אין מספיק CPU זמין כדי למלא את הבקשות של Pod.
אם בקשות המשאבים של ה-Pod חורגות מהבקשות של צומת יחיד מכל מאגר צמתים שעומד בדרישות, GKE לא מתזמן את ה-Pod וגם לא מפעיל הגדלה כדי להוסיף צומת חדש. כדי ש-GKE יתזמן את ה-Pod, צריך לבקש פחות משאבים ל-Pod או ליצור מאגר צמתים חדש עם מספיק משאבים.
אפשר גם להפעיל הקצאת צמתים אוטומטית (NAP) כדי ש-GKE יוכל ליצור באופן אוטומטי מאגרי צמתים עם צמתים שבהם אפשר להריץ את ה-Pods שלא נכללו בתזמון.
בקשת ברירת המחדל של המעבד היא 100m או 10% מהמעבד (או ליבה אחת).
אם רוצים לבקש יותר או פחות משאבים, מציינים את הערך במפרט של ה-Pod בקטע spec: containers: resources: requests.
שגיאה: MatchNodeSelector
MatchNodeSelector מציין שאין צמתים שתואמים לבורר התוויות של ה-Pod.
כדי לוודא זאת, בודקים את התוויות שצוינו בשדה nodeSelector במפרט של ה-Pod, בקטע spec: nodeSelector.
כדי לראות את התוויות של הצמתים באשכול, מריצים את הפקודה הבאה:
kubectl get nodes --show-labels
כדי לצרף תווית לצומת, מריצים את הפקודה הבאה:
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
מחליפים את מה שכתוב בשדות הבאים:
-
NODE_NAME: הצומת שרוצים להוסיף לו תווית. -
LABEL_KEY: המפתח של התווית. -
LABEL_VALUE: הערך של התווית.
מידע נוסף זמין במאמר הקצאת Pod לצמתים במאמרי העזרה של Kubernetes.
שגיאה: PodToleratesNodeTaints
PodToleratesNodeTaints מציין שלא ניתן לתזמן את ה-Pod לאף צומת כי ל-Pod אין סבילות שמתאימות לכתמי צומת קיימים.
כדי לוודא שזה המצב, מריצים את הפקודה הבאה:
kubectl describe nodes NODE_NAME
בפלט, בודקים את השדה Taints שבו מפורטים צמדי מפתח-ערך וההשפעות של התזמון.
אם ההשפעה שמופיעה היא NoSchedule, אי אפשר לתזמן אף Pod בצומת הזה, אלא אם יש לו טולרנטיות תואמת.
אחת הדרכים לפתור את הבעיה היא להסיר את הכתם. לדוגמה, כדי להסיר את ה-taint NoSchedule, מריצים את הפקודה הבאה:
kubectl taint nodes NODE_NAME key:NoSchedule-
שגיאה: PodFitsHostPorts
השגיאה PodFitsHostPorts מציינת שצומת מנסה להשתמש ביציאה שכבר תפוסה.
כדי לפתור את הבעיה, כדאי לפעול לפי השיטות המומלצות לשימוש ב-Kubernetes ולהשתמש ב-NodePort במקום ב-hostPort.
אם אתם חייבים להשתמש ב-hostPort, בדקו את קובצי המניפסט של ה-Pods וודאו שלכל ה-Pods באותו צומת מוגדרים ערכים ייחודיים ל-hostPort.
שגיאה: אין זמינות מינימלית
אם לצומת יש מספיק משאבים אבל ההודעה Does not have minimum availabilityעדיין מוצגת, צריך לבדוק את הסטטוס של ה-Pod. אם הסטטוס הוא SchedulingDisabled או Cordoned, הצומת לא יכול לתזמן פודים חדשים. אפשר לבדוק את הסטטוס של צומת באמצעות מסוף Google Cloud או כלי שורת הפקודה kubectl.
המסוף
כך עושים את זה:
נכנסים לדף Google Kubernetes Engine במסוף Google Cloud .
בוחרים את האשכול שרוצים לבדוק. בכרטיסייה Nodes מוצגים הצמתים והסטטוס שלהם.
כדי להפעיל את התזמון בצומת:
ברשימה, לוחצים על הצומת שרוצים לבדוק.
בקטע פרטי הצומת, לוחצים על ביטול ההסגר.
kubectl
כדי לקבל את הסטטוסים של הצמתים, מריצים את הפקודה הבאה:
kubectl get nodes
כדי להפעיל את התזמון בצומת, מריצים את הפקודה:
kubectl uncordon NODE_NAME
שגיאה: הגעת למגבלה המקסימלית של Pods לכל צומת
אם כל הצמתים באשכול מגיעים למגבלה של Maximum Pods per node, הפודים נתקעים במצב Unschedulable. בכרטיסייה אירועים של הפוד, מוצגת הודעה שכוללת את הביטוי Too many pods.
כדי לפתור את השגיאה, מבצעים את השלבים הבאים:
בודקים את ההגדרה של
Maximum pods per nodeבכרטיסייה Nodes בפרטי אשכול GKE במסוף Google Cloud .כדי לקבל רשימה של צמתים:
kubectl get nodesלכל צומת, בודקים את מספר ה-Pods שפועלים בצומת:
kubectl get pods -o wide | grep NODE_NAME | wc -lאם הגעתם למגבלה, תוכלו להוסיף מאגר צמתים חדש או להוסיף צמתים נוספים למאגר הצמתים הקיים.
בעיה: הגעתם לגודל המקסימלי של מאגר הצמתים כשהתכונה Cluster Autoscaler מופעלת
אם מאגר הצמתים הגיע לגודל המקסימלי לפי הגדרת שינוי הגודל האוטומטי של האשכול, GKE לא יפעיל הגדלה של ה-Pod שאחרת היה מתוזמן עם מאגר הצמתים הזה. כדי לתזמן את ה-Pod עם מאגר הצמתים הזה, משנים את ההגדרה של Cluster Autoscaler.
בעיה: הגעתם לגודל המקסימלי של מאגר הצמתים כשהמידרוג האוטומטי של האשכול מושבת
אם מאגר הצמתים הגיע למספר המקסימלי של הצמתים, והתכונה לשינוי גודל האשכול באופן אוטומטי מושבתת, מערכת GKE לא יכולה לתזמן את ה-Pod עם מאגר הצמתים. להגדיל את הגודל של מאגר הצמתים או להפעיל את התכונה לשינוי גודל האשכול באופן אוטומטי ב-GKE.
שגיאה: בקשות לא קשורות לנפח אחסון מתמיד (PersistentVolumeClaims)
Unbound PersistentVolumeClaims מציין שה-Pod מפנה ל-PersistentVolumeClaim שלא קשור. השגיאה הזו עשויה להתרחש אם הקצאת המקום ב-PersistentVolume נכשלה. כדי לוודא שההקצאה נכשלה, אפשר לקבל את האירועים של PersistentVolumeClaim ולבדוק אם יש בהם כשלים.
כדי לקבל אירועים, מריצים את הפקודה הבאה:
kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
מחליפים את מה שכתוב בשדות הבאים:
-
STATEFULSET_NAME: השם של אובייקט StatefulSet. -
PVC_NAME: השם של אובייקט PersistentVolumeClaim.
מצב כזה יכול לקרות גם אם הייתה שגיאת הגדרה במהלך הקצאה מראש ידנית של PersistentVolume והקישור שלו ל-PersistentVolumeClaim.
כדי לפתור את השגיאה, צריך לנסות להקצות מראש את אמצעי האחסון שוב.
שגיאה: המכסה לא מספיקה
מוודאים שלפרויקט יש מכסת Compute Engine מספיקה כדי ש-GKE יוכל להגדיל את האשכול. אם GKE מנסה להוסיף צומת לאשכול כדי לתזמן את ה-Pod, והגדלת קנה המידה תחרוג מהמכסה הזמינה של הפרויקט, תוצג הודעת השגיאה scale.up.error.quota.exceeded.
מידע נוסף זמין במאמר בנושא שגיאות ב-ScaleUp.
בעיה: ממשקי API שהוצאו משימוש
מוודאים שלא משתמשים בממשקי API שהוצאו משימוש והוסרו בגרסה המשנית של האשכול. מידע נוסף זמין במאמר הוצאה משימוש של תכונות וממשקי API.
שגיאה: לא היו יציאות פנויות ליציאות של ה-Pod שהתבקשו
אם מופיעה שגיאה דומה לזו שבהמשך, כנראה שיש לכם כמה פודים באותו צומת עם אותו ערך שמוגדר בשדה hostPort:
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.
קישור של Pod ל-hostPort מגביל את המקומות שבהם GKE יכול לתזמן את ה-Pod, כי כל שילוב של hostIP, hostPort ו-protocol חייב להיות ייחודי.
כדי לפתור את הבעיה, כדאי לפעול לפי השיטות המומלצות לשימוש ב-Kubernetes ולהשתמש ב-NodePort במקום ב-hostPort.
אם אתם חייבים להשתמש ב-hostPort, בדקו את קובצי המניפסט של ה-Pods וודאו שלכל ה-Pods באותו צומת מוגדרים ערכים ייחודיים ל-hostPort.
בעיה: כשלים באפליקציה ובבדיקה בקבוצות Pod
הבעיה הבאה מתרחשת כשמפעילים אפליקציות שמשתמשות ב-HTTPS כדי לתקשר עם שרת. כשלים באפליקציות האלה דומים לכשלים הבאים:
- הפודים לא מופעלים והקונטיינרים קורסים עם קוד יציאה
137. בדיקות הפעילות או המוכנות נכשלות עם הודעת שגיאה שדומה להודעה הבאה:
probeResult="failure" output="Get "https://example.com/healthy": EOF"הפודים פועלים כצפוי, אבל ביומני האפליקציות מופיעות שגיאות בחיבור.
הבעיות האלה עשויות להתרחש כי ב-Kubernetes בגרסה 1.30 ואילך נעשה שימוש בגרסאות Golang שמשביתות את חבילות ההצפנה הבאות של TLS:
TLS_RSA_WITH_AES_128_GCM_SHA256TLS_RSA_WITH_AES_256_GCM_SHA384TLS_RSA_WITH_AES_128_CBC_SHATLS_RSA_WITH_AES_256_CBC_SHATLS_RSA_WITH_3DES_EDE_CBC_SHA
כדי לפתור את הבעיה, צריך להשתמש בסטים נתמכים של אלגוריתמים להצפנה מ-TLS 1.2 ואילך.
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו לקבל עזרה נוספת במאמר בנושא קבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אפשר גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה נוספת מהקהילה. - פתיחת דיווחים על בעיות או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.