סטטוס NotReady ב-Google Kubernetes Engine (GKE) מציין ש-kubelet של הצומת לא מדווח לרמת הבקרה בצורה תקינה. מכיוון ש-Kubernetes לא יתזמן קבוצות Pod חדשות בצומת NotReady, הבעיה הזו עלולה להפחית את קיבולת האפליקציה ולגרום להשבתה.
המסמך הזה יעזור לכם להבחין בין סטטוסים צפויים של NotReady לבין בעיות בפועל, לאבחן את שורש הבעיה ולמצוא פתרונות לבעיות נפוצות כמו מיצוי משאבים, בעיות ברשת וכשלים בזמן הריצה של קונטיינרים.
המידע הזה מיועד לאדמינים ולמפעילים של פלטפורמות שאחראים ליציבות של אשכולות, ולמפתחי אפליקציות שרוצים להבין את ההתנהגות של אפליקציות שקשורות לתשתית. למידע נוסף על התפקידים הנפוצים ודוגמאות למשימות שאנחנו מתייחסים אליהן בתוכן של Google Cloud , קראו את המאמר תפקידי משתמשים ומשימות נפוצים ב-GKE.
לפני שמתחילים
-
כדי לקבל את ההרשאות שדרושות לביצוע המשימות שמפורטות במאמר הזה, בקשו מהאדמין להקצות לכם את התפקידים הבאים ב-IAM בפרויקט Google Cloud :
-
כדי לגשת לאשכולות GKE:
Kubernetes Engine Cluster Viewer (
roles/container.viewer). -
כדי לצפות ביומנים:
מציג היומנים (
roles/logging.viewer). -
כדי לראות את המדדים:
Monitoring Viewer (
roles/monitoring.viewer).
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
-
כדי לגשת לאשכולות GKE:
Kubernetes Engine Cluster Viewer (
מגדירים את כלי שורת הפקודה
kubectlכדי לתקשר עם אשכול GKE:gcloud container clusters get-credentials CLUSTER_NAME \ --location LOCATION \ --project PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: שם האשכול. -
LOCATION: האזור או התחום של Compute Engine (לדוגמה,us-central1אוus-central1-a) של האשכול. -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
-
בדיקת הסטטוס והתנאים של הצומת
כדי לוודא שהסטטוס של הצומת הוא NotReady ולעזור לכם לאבחן את שורש הבעיה, תוכלו לבצע את השלבים הבאים כדי לבדוק את התנאים, האירועים, היומנים ומדדי המשאבים של הצומת:
צופים בסטטוס של הצמתים. כדי לקבל פרטים נוספים כמו כתובות IP וגרסאות ליבה, שיכולים לעזור באבחון, משתמשים בדגל
-o wide:kubectl get nodes -o wideהפלט אמור להיראות כך:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME gke-cluster-pool-1-node-abc1 Ready <none> 94d v1.32.3-gke.1785003 10.128.0.1 1.2.3.4 Container-Optimized OS from Google 6.6.72+ containerd://1.7.24 gke-cluster-pool-1-node-def2 Ready <none> 94d v1.32.3-gke.1785003 10.128.0.2 5.6.7.8 Container-Optimized OS from Google 6.6.72+ containerd://1.7.24 gke-cluster-pool-1-node-ghi3 NotReady <none> 94d v1.32.3-gke.1785003 10.128.0.3 9.10.11.12 Container-Optimized OS from Google 6.6.72+ containerd://1.7.24בפלט, מחפשים צמתים עם הערך
NotReadyבעמודהSTATUSורושמים את השמות שלהם.כדי לראות מידע נוסף על צמתים ספציפיים עם
NotReadyסטטוס, כולל התנאים שלהם ואירועי Kubernetes האחרונים:kubectl describe node NODE_NAMEמחליפים את
NODE_NAMEבשם של צומת עם סטטוסNotReady.בפלט, מתמקדים בקטע
Conditionsכדי להבין את תקינות הצומת, ובקטעEventsכדי לראות היסטוריה של בעיות שהיו לאחרונה. לדוגמה:Name: gke-cluster-pool-1-node-ghi3 ... Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- NetworkUnavailable False Wed, 01 Oct 2025 10:29:19 +0100 Wed, 01 Oct 2025 10:29:19 +0100 RouteCreated RouteController created a route MemoryPressure Unknown Wed, 01 Oct 2025 10:31:06 +0100 Wed, 01 Oct 2025 10:31:51 +0100 NodeStatusUnknown Kubelet stopped posting node status. DiskPressure Unknown Wed, 01 Oct 2025 10:31:06 +0100 Wed, 01 Oct 2025 10:31:51 +0100 NodeStatusUnknown Kubelet stopped posting node status. PIDPressure False Wed, 01 Oct 2025 10:31:06 +0100 Wed, 01 Oct 2025 10:29:00 +0100 KubeletHasSufficientPID kubelet has sufficient PID available Ready Unknown Wed, 01 Oct 2025 10:31:06 +0100 Wed, 01 Oct 2025 10:31:51 +0100 NodeStatusUnknown Kubelet stopped posting node status. Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Starting 32m kubelet, gke-cluster-pool-1-node-ghi3 Starting kubelet. Warning PLEGIsNotHealthy 5m1s (x15 over 29m) kubelet, gke-cluster-pool-1-node-ghi3 PLEG is not healthy: pleg was last seen active 5m1.123456789s ago; threshold is 3m0s Normal NodeHasSufficientMemory 5m1s (x16 over 31m) kubelet, gke-cluster-pool-1-node-ghi3 Node gke-cluster-pool-1-node-ghi3 status is now: NodeHasSufficientMemoryבקטע
Conditions, סטטוס שלTrueלכל תנאי שלילי, אוUnknownלתנאיReady, מצביע על בעיה. חשוב לשים לב לשדותReasonו-Message, כי הם מסבירים את הסיבה לבעיה.המשמעות של כל סוג תנאי:
-
KernelDeadlock:Trueאם ליבת מערכת ההפעלה של הצומת זיהתה מצב של קיפאון, שזו שגיאה חמורה שיכולה לגרום להקפאת הצומת. -
FrequentUnregisterNetDevice:Trueאם הצומת מבטל לעיתים קרובות את הרישום של מכשירי הרשת שלו, מה שיכול להעיד על בעיות במנהל ההתקן או בחומרה. -
NetworkUnavailable:Trueאם הגדרת הרשת של הצומת לא תקינה. -
OutOfDisk:Trueאם נפח האחסון הזמין בכונן מלא לגמרי. המצב הזה חמור יותר מ-DiskPressure. -
MemoryPressure:Trueאם הזיכרון של הצומת נמוך. -
DiskPressure:Trueאם אין מספיק מקום בכונן בצומת. -
PIDPressure: הערךTrueאם הצומת חווה מיצוי של מזהה התהליך (PID). -
Ready: מציין אם הצומת תקין ומוכן לקבל קבוצות Pod.-
Trueאם הצומת תקין. -
Falseאם הצומת לא תקין ולא מקבל Pods. -
Unknownאם בקר הצומת לא קיבל עדכון מהצומת במשך תקופת חסד (ברירת המחדל היא 50 שניות) וסטטוס הצומת לא ידוע.
-
בשלב הבא, בודקים את הקטע
Eventsשבו מופיע יומן כרונולוגי של פעולות ותצפיות לגבי הצומת. ציר הזמן הזה חיוני כדי להבין מה קרה מיד לפני שהצומת הפך ל-NotReady. מחפשים הודעות ספציפיות שיכולות לעזור לכם למצוא את הסיבה, כמו אזהרות על פינוי (שמצביעות על עומס על המשאבים), בדיקות תקינות שנכשלו או אירועים במחזור החיים של הצומת, כמו גידור לצורך תיקון.-
כדי להבין למה הצמתים מקבלים את הסטטוס
NotReady, אפשר לעיין ביומנים מהצומת ומהרכיבים שלו.בודקים ביומני
kubeletאת הסטטוסNotReady.
kubeletהוא הסוכן הראשי שמדווח על סטטוס הצומת למישור הבקרה, ולכן סביר להניח שההודעהNotReadyתופיע ביומנים שלו. היומנים האלה הם המקור המוסמך לאבחון בעיות באירועים במחזור החיים של Pod, בתנאי לחץ על משאבים (כמוMemoryPressureאוDiskPressure) ובקישוריות של הצומת למישור הבקרה של Kubernetes.נכנסים לדף Logs Explorer במסוף Google Cloud :
בחלונית השאילתה, מזינים את השאילתה הבאה:
resource.type="k8s_node" resource.labels.node_name="NODE_NAME" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" log_id("kubelet") textPayload=~"(?i)NotReady"מחליפים את מה שכתוב בשדות הבאים:
-
NODE_NAME: שם הצומת שבודקים. -
CLUSTER_NAME: השם של האשכול. -
LOCATION: האזור או התחום של Compute Engine (לדוגמה,us-central1אוus-central1-a) של האשכול.
-
לוחצים על הפעלת שאילתה ובודקים את התוצאות.
אם היומנים
kubeletלא חושפים את שורש הבעיה, צריך לבדוק את היומניםcontainer-runtimeו-node-problem-detector. יכול להיות שהרכיבים האלה לא יתעדו את הסטטוסNotReadyבאופן ישיר, אבל לעיתים קרובות הם מתעדים את הבעיה הבסיסית (כמו כשל בזמן ריצה או תגובה לשגיאת ליבה קריטית) שגרמה לבעיה.בחלונית השאילתות של Logs Explorer, מזינים את השאילתה הבאה:
resource.type="k8s_node" resource.labels.node_name="NODE_NAME" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" log_id("COMPONENT_NAME")מחליפים את
COMPONENT_NAMEבאחד מהערכים הבאים:-
container-runtime: זמן הריצה (containerd), שאחראי למחזור החיים המלא של הקונטיינר, כולל משיכת תמונות וניהול של הרצת הקונטיינר. בדיקת יומני הרישוםcontainer-runtimeחיונית לפתרון בעיות שקשורות ליצירת מופע של קונטיינר, לשגיאות בשירות זמן הריצה או לבעיות שנגרמות בגלל ההגדרה של זמן הריצה. -
node-problem-detector: כלי שמנטר באופן יזום מגוון בעיות ברמת הצומת ומדווח עליהן למישור הבקרה. היומנים שלו חיוניים לזיהוי בעיות מערכתיות בסיסיות שעלולות לגרום לחוסר יציבות של הצומת, כמו חסימות ליבה, פגיעה במערכת הקבצים או כשלים בחומרה, שאולי לא יתועדו על ידי רכיבים אחרים של Kubernetes.
-
לוחצים על הפעלת שאילתה ובודקים את התוצאות.
כדי לחפש את המדדים של ניצול המשאבים בזמן שהצומת הפך ל-
NotReady, משתמשים ב-Metrics Explorer:במסוף Google Cloud , נכנסים לדף Metrics Explorer:
ב-Metrics Explorer, בודקים אם יש ניצול יתר של משאבים במכונה הבסיסית של Compute Engine של הצומת. התמקדו במדדים שקשורים למעבד (CPU), לזיכרון ולקלט/פלט (I/O) בדיסק. לדוגמה:
- מדדי צומת GKE: מתחילים במדדים עם הקידומת
kubernetes.io/node/, כמוkubernetes.io/node/cpu/allocatable_utilizationאוkubernetes.io/node/memory/allocatable_utilization. המדדים האלה מראים כמה מהמשאבים הזמינים של הצומת נמצאים בשימוש של ה-Pods. הכמות הזמינה לא כוללת את המשאבים ש-Kubernetes שומרת להוצאות תקורה של המערכת. - מדדים של מערכת ההפעלה של האורח: כדי לראות תצוגה מתוך מערכת ההפעלה של הצומת, משתמשים במדדים עם הקידומת
compute.googleapis.com/guest/, כמוcompute.googleapis.com/guest/cpu/usageאוcompute.googleapis.com/guest/memory/bytes_used. - מדדי Hypervisor: כדי לראות את הביצועים של המכונה הווירטואלית ברמת ה-Hypervisor, משתמשים במדדים עם הקידומת
compute.googleapis.com/instance/, כמוcompute.googleapis.com/instance/cpu/utilizationאו במדדי קלט/פלט של הדיסק כמוcompute.googleapis.com/instance/disk/read_bytes_count.
כדי להציג את המדדים של מערכת ההפעלה של האורח ושל ה-hypervisor, צריך לסנן לפי השם של מכונת Compute Engine הבסיסית, ולא לפי השם של צומת Kubernetes. כדי למצוא את שם המופע של צומת, מריצים את הפקודה
kubectl describe node NODE_NAMEומחפשים את השדהProviderIDבפלט. שם המופע הוא החלק האחרון של הערך הזה. לדוגמה:... Spec: ProviderID: gce://my-gcp-project-123/us-central1-a/gke-my-cluster-default-pool-1234abcd-5678 ...בדוגמה הזו, שם המכונה הוא
gke-my-cluster-default-pool-1234abcd-5678.- מדדי צומת GKE: מתחילים במדדים עם הקידומת
זיהוי הסיבה לפי הסימפטום
אם זיהיתם סימפטום ספציפי, כמו הודעה ביומן, תנאי של צומת או אירוע של אשכול, תוכלו להיעזר בטבלה הבאה כדי לקבל עצות לפתרון בעיות:
| קטגוריה | סימפטום או הודעת יומן | סיבה אפשרית | שלבים לפתרון בעיות |
|---|---|---|---|
| תנאי הצומת | NetworkUnavailable: True |
בעיה בקישוריות בין הצומת לבין מישור הבקרה או כשל בפלאגין של ממשק רשת קונטיינרים (CNI). | פתרון בעיות בקישוריות לרשת |
MemoryPressure: True |
אין מספיק זיכרון בצומת. | פתרון בעיות שקשורות למחסור במשאבים של צומת | |
DiskPressure: True |
אין מספיק מקום בכונן של הצומת. | פתרון בעיות שקשורות למחסור במשאבים בצומת | |
PIDPressure: True |
לצומת אין מספיק מזהי תהליכים זמינים. | פתרון בעיות שקשורות למחסור במשאבים בצומת | |
| אירועים והודעות ביומן | PLEG is not healthy |
Kubelet עמוס מדי בגלל שימוש גבוה במעבד (CPU) או בקלט/פלט (IO), או בגלל שיש יותר מדי Pods. | פתרון בעיות שקשורות ל-PLEG |
Out of memory: Kill processsys oom event |
הזיכרון של הצומת מוצה לחלוטין. | פתרון אירועי OOM ברמת המערכת | |
leases.coordination.k8s.io...is forbidden |
מרחב השמות kube-node-lease נתקע בתהליך הסיום. |
פתרון בעיות במרחב השמות kube-node-lease |
|
Container runtime not readyruntime is downשגיאות שמתייחסות ל- /run/containerd/containerd.sock או ל-docker.sock |
שירות Containerd או Docker נכשל או שההגדרה שלו שגויה. | פתרון בעיות בזמן הריצה של מארח הקונטיינר | |
פודים תקועים ב-Terminatingביומני Kubelet מופיע DeadlineExceeded עבור kill containerביומני containerd מופיעות הודעות Kill container חוזרות |
תהליכים שנתקעו במצב שינה של דיסק שלא ניתן להפריע לו (מצב D), בדרך כלל קשורים לקלט/פלט. | פתרון בעיות בתהליכים שנתקעו במצב D | |
| תסמינים ברמת האשכול | כמה צמתים נכשלים אחרי פריסת DaemonSet. | ה-DaemonSet מפריע לפעולות של הצומת. | פתרון בעיות שנגרמו על ידי DaemonSets של צד שלישי |
compute.instances.preempted ביומני הביקורת. |
ה-VM במודל Spot הופקע, וזו התנהגות צפויה. | אישור הקדימות של הצומת | |
kube-system Pods stuck in Pending. |
ה-webhook של בקרת הכניסה חוסם רכיבים קריטיים. | פתרון בעיות שנגרמו על ידי תגובות לפעולה מאתר אחר (webhooks) של אימות | |
exceeded quota: gcp-critical-pods |
מכסה שהוגדרה בצורה שגויה חוסמת את ה-Pods של המערכת. | פתרון בעיות שנגרמות בגלל מכסות משאבים |
בדיקה אם יש אירועים צפויים ב-NotReady
סטטוס NotReady לא תמיד מצביע על בעיה. התנהגות כזו יכולה להיות צפויה במהלך פעולות מתוכננות כמו שדרוג מאגר צמתים, או אם אתם משתמשים בסוגים מסוימים של מכונות וירטואליות.
אישור פעולות במחזור החיים של הצומת
תסמינים:
במהלך אירועים מסוימים במחזור החיים, הצומת מציג באופן זמני את הסטטוס NotReady.
הסיבה:
הסטטוס של צומת הופך באופן זמני ל-NotReady במהלך כמה אירועים נפוצים במחזור החיים. ההתנהגות הזו צפויה בכל פעם שנוצר צומת או נוצר מחדש, כמו בתרחישים הבאים:
- שדרוגים של מאגר הצמתים: במהלך שדרוג, כל צומת מנוקז ומוחלף. לצומת החדש והמשודרג יש סטטוס של
NotReadyעד שהוא מסיים את האתחול ומצטרף לאשכול. - תיקון אוטומטי של צומת: כש-GKE מחליף צומת לא תקין, הצומת החלופי נשאר במצב
NotReadyבזמן ההקצאה. - הרחבה אנכית בהתאם לעומס (scale up) של המידרוג האוטומטי באשכול: כשמוסיפים צמתים חדשים, הם מתחילים בסטטוס
NotReadyוהופכים ל-Readyרק אחרי שהם מוקצים באופן מלא ומצטרפים לאשכול. - שינויים ידניים בתבנית של הגדרות מכונה: מערכת GKE יוצרת מחדש את הצמתים כשמחילים שינויים בתבנית. לצומת החדש יש סטטוס
NotReadyבמהלך שלב ההפעלה שלו.
פתרון:
הסטטוס NotReady צריך להיות מוגדר לצמתים לזמן קצר בלבד. אם הסטטוס לא משתנה במשך יותר מ-10 דקות, צריך לבדוק סיבות אחרות.
אישור של הפסקת פעולה של צומת
אם הצומת שלכם פועל על VM במודל Spot או על VM זמני, יכול להיות ש-Compute Engine יפסיק את הפעולה שלה באופן פתאומי כדי לפנות משאבים. זו התנהגות צפויה במכונות וירטואליות מהסוג הזה, והיא לא מצביעה על שגיאה.
תסמינים:
אם אתם מבחינים בתסמינים הבאים, סביר להניח שהסטטוס NotReady של הצומת נגרם כתוצאה מהפקעה צפויה של VM במודל Spot:
- צומת נכנס באופן לא צפוי לסטטוס
NotReadyלפני שהוא נמחק ונוצר מחדש על ידי מידרוג אוטומטי של האשכול. - ביומני הביקורת של Cloud מופיע אירוע
compute.instances.preemptedלמכונה הבסיסית של ה-VM.
הסיבה:
הצומת פעל ב-VM במודל Spot או ב-VM זמני, ו-Compute Engine החזיר את משאבי המחשוב האלה למשימה אחרת. יכול להיות שיהיו הפרעות בשימוש ב-VM במודל Spot בכל שלב, אבל בדרך כלל תקבלו הודעה על סיום השימוש 30 שניות מראש.
פתרון:
כדאי להשתמש ב-VM במודל Spot או ב-VM זמני רק לעומסי עבודה עמידים בכשלים, בלי שמירת מצב או לעומסי עבודה של אצווה, שמיועדים לטיפול בהפסקות תכופות בצורה חלקה. לעומסי עבודה של ייצור או לעומסי עבודה עם שמירת מצב שלא יכולים לסבול הפרעות פתאומיות, כדאי להקצות את מאגרי הצמתים באמצעות מכונות וירטואליות רגילות על פי דרישה.
פתרון בעיות של מחסור במשאבי צומת
צומת הופך לNotReady בדרך כלל כי חסרים לו משאבים חיוניים כמו מעבד (CPU), זיכרון או נפח אחסון. אם אין מספיק משאבים כאלה בצומת, רכיבים קריטיים לא יכולים לפעול בצורה תקינה, מה שמוביל לחוסר יציבות באפליקציה ולחוסר תגובה של הצומת. בקטעים הבאים מוסבר על הדרכים השונות שבהן יכולים להופיע מחסורים כאלה, החל מתנאי לחץ כלליים ועד לאירועים חמורים יותר ברמת המערכת.
פתרון בעיות של עומס על משאבי הצומת
תופעת מיצוי המשאבים מתרחשת כשבצומת חסרים מעבד, זיכרון, מקום בכונן או מזהי תהליכים (PID) כדי להריץ את עומסי העבודה שלו. הבעיה הזו יכולה לגרום לסטטוס NotReady.
תסמינים:
אם אתם רואים את התנאים והיומנים הבאים של הצומת, סביר להניח שהסיבה לסטטוס NotReady של הצומת היא מיצוי משאבים:
- בפלט של הפקודה
kubectl describe node, הסטטוסTrueמוצג לתנאים כמוOutOfDisk, MemoryPressure, DiskPressureאוPIDPressure. - יומני kubelet עשויים להכיל אירועים של חוסר זיכרון (OOM), שמציינים שהופעל OOM Killer של המערכת.
הסיבה:
עומסי העבודה בצומת דורשים ביחד יותר משאבים ממה שהצומת יכול לספק.
פתרון:
במקרים של אשכולות Standard, אפשר לנסות את הפתרונות הבאים:
- הפחתת הדרישה לעומס עבודה:
- מפחיתים את מספר ה-Pods שפועלים בצומת המושפע על ידי הקטנת מספר הרפליקות של הפריסות. מידע נוסף זמין במאמר בנושא שינוי גודל של אפליקציה.
- בודקים את האפליקציות ומשפרים אותן כדי שיצרכו פחות משאבים.
- הגדלת קיבולת הצומת:
- להגדיל את המעבד (CPU) והזיכרון שהוקצו לצומת. מידע נוסף מופיע במאמר בנושא שינוי מאפייני מכונת הצומת כדי לבצע שינוי גודל אנכי.
- אם הבעיה קשורה לדיסק, מגדילים את הגודל של דיסק האתחול של הצומת. כדי לשפר את הביצועים, כדאי להשתמש בדיסק אתחול SSD.
במערכות Autopilot, אין לכם שליטה ישירה על סוגי המכונות של הצמתים או על גדלי דיסקי האתחול. קיבולת הצומת מנוהלת באופן אוטומטי על סמך הבקשות של ה-Pod. מוודאים שהבקשות למשאבים של עומס העבודה הן במסגרת המגבלות של Autopilot ומשקפות במדויק את הצרכים של האפליקציה. בעיות מתמשכות במשאבים עשויות להצביע על הצורך באופטימיזציה של בקשות Pod או, במקרים נדירים, על בעיה בפלטפורמה שדורשת עזרה מ-Cloud Customer Care.
פתרון אירועי OOM ברמת המערכת
אירוע של חוסר זיכרון (OOM) ברמת המערכת מתרחש כשנגמר הזיכרון הכולל של הצומת, מה שמאלץ את ליבת Linux לסיים תהליכים כדי לפנות משאבים. האירוע הזה שונה מאירוע OOM ברמת מאגר, שבו פוד יחיד חורג ממגבלות הזיכרון שלו.
תסמינים:
אם אתם מבחינים בתסמינים הבאים, סביר להניח שאירוע OOM ברמת המערכת הוא הסיבה לחוסר היציבות של הצומת:
- ההודעה
Out of memory: Kill processמופיעה ביומני הקונסולה הטורית של הצומת. - ביומני ה-kubelet יש אירועי
oom_watcher, שמציינים שה-kubelet זיהה אירוע OOM ברמת המערכת. - סיום לא צפוי של תהליכים שונים, כולל תהליכי רקע (daemon) קריטיים של המערכת או פודים של עומסי עבודה, לא בהכרח אלה שצורכים הכי הרבה זיכרון.
הסיבה:
הזיכרון הכולל של הצומת נגמר. הבעיה הזו יכולה להיגרם מבאג בשירות מערכת, מעומס עבודה שהוגדר בצורה שגויה וצורכת כמות מוגזמת של זיכרון, או מצומת קטן מדי ביחס לדרישות הזיכרון המשותפות של כל ה-Pods שפועלים בו.
פתרון:
כדי לפתור אירועי OOM ברמת המערכת, צריך לאבחן את הסיבה ואז להפחית את דרישת הזיכרון או להגדיל את קיבולת הצומת. מידע נוסף זמין במאמר בנושא פתרון בעיות שקשורות לאירועי OOM.
פתרון בעיות שקשורות ל-PLEG
מחולל אירועים במחזור החיים של ה-Pod (PLEG) הוא רכיב בתוך kubelet. הוא בודק מעת לעת את המצב של כל המאגדים בצומת ומדווח על כל שינוי בחזרה ל-kubelet.
אם יש בעיות בביצועים של PLEG, הוא לא יכול לספק עדכונים בזמן ל-kubelet, וזה עלול לגרום לחוסר יציבות של הצומת.
תסמינים:
אם מופיעים התסמינים הבאים, יכול להיות שה-PLEG לא פועל בצורה תקינה:
- יומני kubelet של הצומת מכילים הודעה שדומה ל-
PLEG is not healthy. - הסטטוס של הצומת משתנה לעיתים קרובות בין
Readyל-NotReady.
הסיבה:
בעיות ב-PLEG נגרמות בדרך כלל מבעיות בביצועים שמונעות מ-kubelet לקבל עדכונים בזמן מ-container runtime. סיבות נפוצות כוללות:
- עומס גבוה על המעבד: המעבד של הצומת רווי, ולכן ל-kubelet ולזמן הריצה של הקונטיינר אין את כוח העיבוד שהם צריכים.
- הגבלת קצב העברת נתונים (I/O): בדיסק האתחול של הצומת מתבצעות פעולות קלט/פלט (I/O) רבות, שיכולות להאט את כל המשימות שקשורות לדיסק.
- יותר מדי Pods: יותר מדי Pods בצומת אחד יכולים להעמיס על ה-kubelet ועל זמן הריצה של הקונטיינר, וכתוצאה מכך לגרום לתחרות על משאבים.
פתרון:
באשכולות Standard, מפחיתים את העומס על המשאבים של הצומת:
- הפחתת העומס על הצומת: הפחתת עומס העבודה הכולל על הצומת על ידי הקטנת הפריסות. כדי להשפיע על התזמון, אתם יכולים גם לפזר את ה-Pods בצורה שווה יותר בין צמתים אחרים באשכול באמצעות taints ו-tolerations, node affinities או אילוצי פריסה של טופולוגיית Pod.
- הגדרת מגבלות על השימוש במעבד: כדי למנוע מצב שבו עומס עבודה יחיד ינצל את כל משאבי המעבד הזמינים, כדאי להגדיר מגבלות על השימוש במעבד ב-Pods. מידע נוסף זמין במאמר ניהול משאבים עבור Pods וקונטיינרים במאמרי העזרה של Kubernetes.
- הגדלת קיבולת הצומת: כדאי להשתמש בצמתים גדולים יותר עם יותר מעבד (CPU) וזיכרון כדי לטפל בעומס העבודה. מידע נוסף זמין במאמר שינוי קנה מידה אנכי על ידי שינוי מאפייני המכונה של הצומת.
- שיפור הביצועים של הדיסק: אם הבעיה קשורה להגבלת קצב העברת הנתונים (I/O), צריך להשתמש בדיסק אתחול גדול יותר או לשדרג לדיסק אתחול SSD. השינוי הזה יכול לשפר באופן משמעותי את ביצועי הדיסק. למידע נוסף, קראו את המאמר פתרון בעיות בביצועי הדיסק.
באשכולות Autopilot, אי אפשר לשנות ישירות את הגודל או את סוג הדיסק של צומת קיים, אבל אפשר להשפיע על החומרה שעליה פועלים עומסי העבודה באמצעות ComputeClasses בהתאמה אישית. התכונה הזו מאפשרת לציין דרישות במניפסט של עומס העבודה, כמו כמות מינימלית של CPU וזיכרון או סדרת מכונות ספציפית, כדי להנחות את המיקום שבו יתוזמנו הפודים.
אם לא משתמשים ב-ComputeClasses, צריך להתאים את פריסות עומסי העבודה (כמו מספר העותקים ומגבלות או בקשות משאבים) ולוודא שהן עומדות במגבלות של Autopilot. אם הבעיות ב-PLEG נמשכות אחרי אופטימיזציה של עומסי העבודה, פנו ל-Cloud Customer Care.
פתרון בעיות בתהליכים שנתקעו במצב D
תהליכים שנתקעים במצב שינה של הדיסק (מצב D) שלא ניתן להפריע לו עלולים לגרום לכך שהצומת לא יגיב. הבעיה הזו מונעת את סיום הפעולה של Pods ויכולה לגרום לכשל ברכיבים קריטיים כמו containerd, מה שמוביל לסטטוס NotReady.
תסמינים:
- פודים, במיוחד כאלה שמשתמשים באחסון ברשת כמו NFS, נתקעים במצב
Terminatingלמשך זמן רב. - ביומני Kubelet מופיעות שגיאות מסוג
DeadlineExceededכשמנסים לעצור קונטיינר. - יכול להיות שביומני הקונסולה הטורית של הצומת יופיעו הודעות ליבה (kernel) לגבי
hung tasksאו משימות שנחסמו למשך יותר מ-120 שניות.
הסיבה:
תהליכים עוברים למצב D כשהם ממתינים להשלמת פעולת קלט/פלט, ואי אפשר להפריע להם. הסיבות הנפוצות כוללות:
- מערכות קבצים מרחוק איטיות או לא מגיבות, כמו שיתוף NFS שהוגדר בצורה שגויה או עמוס מדי.
- פגיעה חמורה בביצועי הדיסק או שגיאות קלט/פלט בחומרה בדיסקים המקומיים של הצומת.
פתרון:
כדי לפתור בעיות בתהליכים במצב D, צריך לזהות את מקור הקלט/פלט ואז לנקות את המצב באמצעות אחת מהאפשרויות הבאות:
אשכולות רגילים
מאתרים את התהליך התקוע ומנסים להבין למה הוא מחכה:
מתחברים לצומת המושפע באמצעות SSH:
gcloud compute ssh NODE_NAME \ --zone ZONE \ --project PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
-
NODE_NAME: השם של הצומת שאליו רוצים להתחבר. -
ZONE: אזור Compute Engine של הצומת. PROJECT_ID: מזהה הפרויקט.
-
כדי למצוא תהליכים במצב D:
ps -eo state,pid,comm,wchan | grep '^D'הפלט אמור להיראות כך:
D 12345 my-app nfs_wait D 54321 data-writer io_scheduleלפלט לא תהיה כותרת. העמודות, לפי הסדר, מייצגות:
- מדינה
- מזהה תהליך (PID)
- פקודה
- ערוץ המתנה (wchan)
בודקים את העמודה
wchanכדי לזהות את מקור הקלט/פלט:- אם העמודה
wchanכוללת מונחים כמוnfsאוrpc, התהליך ממתין לשיתוף NFS. - אם בעמודה
wchanמופיעים מונחים כמוio_schedule,jbd2אוext4, התהליך ממתין לדיסק האתחול המקומי של הצומת.
- אם העמודה
כדי לקבל פרטים נוספים על פונקציות הליבה שהתהליך ממתין להן, בודקים את סטאק הביצוע של הליבה של התהליך:
cat /proc/PID/stackמחליפים את
PIDבמזהה התהליך שמצאתם בשלב הקודם.
מפעילים מחדש את הצומת. הפעלה מחדש היא לרוב הדרך היעילה ביותר לנקות תהליך שנתקע במצב D.
- הפסקת הפעילות של הצומת.
- מוחקים את המכונה הווירטואלית הבסיסית. בדרך כלל, GKE יוצר מכונה וירטואלית חדשה כדי להחליף אותה.
אחרי שמטפלים בבעיה המיידית, צריך לבדוק את מערכת האחסון הבסיסית כדי למנוע הישנות של הבעיה.
לפתרון בעיות באחסון ברשת (NFS): משתמשים בכלי המעקב של ספק האחסון כדי לבדוק אם יש חביון גבוה, שגיאות בצד השרת או בעיות ברשת בין צומת GKE לבין שרת NFS.
לבעיות בדיסק מקומי: בודקים אם יש הגבלת קצב העברת נתונים (throttling) של קלט/פלט (I/O) ב-Cloud Monitoring על ידי צפייה במדדים
compute.googleapis.com/instance/disk/throttled_read_ops_countו-compute.googleapis.com/instance/disk/throttled_write_ops_countשל מכונת Compute Engine.
אשכולות בטייס אוטומטי
מנסים לזהות את מקור החסימה:
גישת SSH ישירה לצמתים והרצת פקודות כמו
psאוcat /procלא זמינות באשכולות של Autopilot. אתם צריכים להסתמך על יומנים ומדדים.- בדיקת יומני הצמתים: ב-Cloud Logging, מנתחים את היומנים מהצומת המושפע. מסננים לפי שם הצומת ופרק הזמן שבו הבעיה התרחשה. מחפשים הודעות ליבה שמציינות שגיאות קלט/פלט, פסק זמן של אחסון (לדוגמה, לדיסק או ל-NFS) או הודעות ממנהלי התקנים של CSI.
- בדיקת יומני עומסי העבודה: בודקים את היומנים של ה-Pods שפועלים בצומת המושפע. ביומני האפליקציות יכולות להופיע שגיאות שקשורות לפעולות בקבצים, לקריאות למסד נתונים או לגישה לאחסון ברשת.
- שימוש ב-Cloud Monitoring: למרות שאי אפשר לקבל פרטים ברמת התהליך, אפשר לבדוק בעיות קלט/פלט ברמת הצומת.
מפעילים החלפה של צומת כדי לנקות את המצב.
אי אפשר למחוק ידנית את המכונה הווירטואלית הבסיסית. כדי להפעיל החלפה, צריך לרוקן את הצומת. הפעולה הזו מבודדת את הצומת ומפנה את ה-Pods.
GKE מזהה אוטומטית צמתים לא תקינים ומתחיל לתקן אותם, בדרך כלל על ידי החלפת המכונה הווירטואלית הבסיסית.
אם הצומת נשאר תקוע אחרי הניקוז ולא מוחלף באופן אוטומטי, פנו ל-Cloud Customer Care.
אחרי שמטפלים בבעיה המיידית, צריך לבדוק את מערכת האחסון הבסיסית כדי למנוע הישנות של הבעיה.
- לבעיות בדיסק מקומי: בודקים אם יש הגבלת קצב העברת נתונים (throttling) של קלט/פלט ב-Cloud Monitoring על ידי צפייה במדדים
compute.googleapis.com/instance/disk/throttled_read_ops_countו-compute.googleapis.com/instance/disk/throttled_write_ops_count. אפשר לסנן את המדדים האלה לפי קבוצת המופעים הבסיסית של מאגר הצמתים, אבל Google מנהלת את המופעים הבודדים. - לפתרון בעיות באחסון ברשת (NFS): משתמשים בכלי המעקב של ספק האחסון כדי לבדוק אם יש חביון גבוה, שגיאות בצד השרת או בעיות ברשת בין צומת GKE לבין שרת NFS. בודקים את היומנים של כל ה-Pods של מנהלי התקנים של CSI ב-Cloud Logging.
- לבעיות בדיסק מקומי: בודקים אם יש הגבלת קצב העברת נתונים (throttling) של קלט/פלט ב-Cloud Monitoring על ידי צפייה במדדים
פתרון בעיות שקשורות לכשלים ברכיבי ליבה
אחרי ששוללים את הסיבות הצפויות ואת המחסור במשאבים, יכול להיות שהבעיה נובעת מהתוכנה של הצומת או ממנגנון ליבה של Kubernetes. NotReadyסטטוס יכול להתרחש כשמרכיב קריטי, כמו זמן הריצה של הקונטיינר, נכשל.
זה יכול לקרות גם כשמנגנון מרכזי לבדיקת תקינות של Kubernetes, כמו מערכת השכירות של הצומת, מתקלקל.
פתרון בעיות בזמן הריצה של מאגרים
בעיות בזמן הריצה של הקונטיינר, כמו containerd, יכולות למנוע מ-kubelet להפעיל Pods בצומת.
תסמינים:
אם ההודעות הבאות מופיעות ביומני kubelet, סביר להניח שבעיה בזמן הריצה של הקונטיינר היא הסיבה לסטטוס NotReady של הצומת:
Container runtime not readyContainer runtime docker failed!docker daemon exited- שגיאות בהתחברות לשקע של זמן הריצה (לדוגמה,
unix:///var/run/docker.sockאוunix:///run/containerd/containerd.sock).
הסיבה:
סביבת זמן הריצה של הקונטיינר לא פועלת כמו שצריך, מוגדרת באופן שגוי או תקועה בלולאת הפעלה מחדש.
פתרון:
כדי לפתור בעיות בסביבת זמן הריצה של קונטיינרים:
ניתוח יומני זמן ריצה של קונטיינרים:
נכנסים לדף Logs Explorer במסוף Google Cloud .
כדי לראות את כל יומני האזהרות והשגיאות של סביבת זמן הריצה של הקונטיינר בצומת המושפע, מזינים את השאילתה הבאה בחלונית השאילתות:
resource.type="k8s_node" resource.labels.node_name="NODE_NAME" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" log_id("container-runtime") severity>=WARNINGמחליפים את מה שכתוב בשדות הבאים:
-
NODE_NAME: שם הצומת שבודקים. -
CLUSTER_NAME: השם של האשכול. -
LOCATION: האזור או התחום של Compute Engine (לדוגמה,us-central1אוus-central1-a) של האשכול.
-
לוחצים על הפעלת שאילתה ובודקים את הפלט כדי לראות הודעות שגיאה ספציפיות שמציינות למה זמן הריצה נכשל. הודעה כמו
failed to load TOMLביומניcontainerdב-Cloud Logging בדרך כלל מצביעה על קובץ פגום.כדי לבדוק אם זמן הריצה נתקע בלולאת הפעלה מחדש, מריצים שאילתה שמחפשת הודעות הפעלה. מספר גבוה של הודעות כאלה תוך זמן קצר מעיד על הפעלה מחדש בתדירות גבוהה.
resource.type="k8s_node" resource.labels.node_name="NODE_NAME" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" log_id("container-runtime") ("starting containerd" OR "Containerd cri plugin version" OR "serving..." OR "loading plugin" OR "containerd successfully booted")הפעלה מחדש בתדירות גבוהה מצביעה בדרך כלל על בעיה בסיסית, כמו קובץ הגדרה פגום או עומס על המשאבים, שגורמת לקריסה חוזרת של השירות.
בודקים את ההגדרה של
containerdאם בוצעו בה שינויים: הגדרות שגויות עלולות לגרום לזמן הריצה של הקונטיינר להיכשל. אפשר לבצע שינויים בהגדרות באמצעות קובץ תצורה של מערכת צמתים או באמצעות שינויים ישירים שמבוצעים על ידי עומסי עבודה עם הרשאות מורחבות.בודקים אם מאגר הצמתים משתמש בקובץ תצורה של מערכת הצמתים:
gcloud container node-pools describe NODE_POOL_NAME \ --cluster CLUSTER_NAME \ --location LOCATION \ --format="yaml(config.containerdConfig)"מחליפים את מה שכתוב בשדות הבאים:
-
NODE_POOL_NAME: השם של מאגר הצמתים. -
CLUSTER_NAME: השם של האשכול. -
LOCATION: האזור או התחום של Compute Engine שבו נמצא האשכול.
אם הפלט מציג קטע
containerdConfig, סימן שהגדרות מותאמות אישית אלה מנוהלות על ידי GKE. כדי לשנות או לבטל את ההגדרות, פועלים לפי ההוראות במאמר התאמה אישית של הגדרות containerd בצומתי GKE.-
אם ההתאמות האישיות שמנוהלות על ידי GKE לא פעילות, או אם אתם חושדים בשינויים אחרים, כדאי לחפש עומסי עבודה שאולי משנים את מערכת הקבצים של הצומת ישירות. מחפשים DaemonSets עם הרשאות גבוהות (
securityContext.privileged: true) או אמצעי אחסוןhostPathשמבצעים mount של ספריות רגישות כמו/etc.כדי לבדוק את ההגדרות שלהם, מציגים את כל ה-DaemonSets בפורמט YAML:
kubectl get daemonsets --all-namespaces -o yamlבודקים את הפלט ואת היומנים של כל DaemonSet חשוד.
עבור אשכולות Standard, בדוק את קובץ התצורה ישירות. אי אפשר לגשת ל-SSH ולבדוק קבצים באופן ידני באשכולות של Autopilot, כי Google מנהלת את הגדרות זמן הריצה. אם נתקלים בבעיות שחוזרות על עצמן בזמן הריצה, צריך לדווח עליהן לצוות Cloud Customer Care של Google.
אם משתמשים באשכול רגיל, בודקים את הקובץ:
מתחברים לצומת באמצעות SSH:
gcloud compute ssh NODE_NAME \ --zone ZONE \ --project PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
-
NODE_NAME: השם של הצומת שאליו רוצים להתחבר. -
ZONE: אזור Compute Engine של הצומת. PROJECT_ID: מזהה הפרויקט.
-
מציגים את התוכן של קובץ התצורה של containerd:
sudo cat /etc/containerd/config.tomlכדי לבדוק אם בוצעו שינויים לאחרונה, מציגים את פרטי הקובץ:
ls -l /etc/containerd/config.toml
משווים את התוכן של הקובץ הזה לתוצאה של הפקודה
gcloud node-pools describeשהרצתם בשלב הקודם. כל הגדרה ב-/etc/containerd/config.tomlשלא מופיעה בפלט שלgcloudהיא שינוי לא מנוהל.כדי לתקן הגדרה שגויה, צריך להסיר את כל השינויים שלא הוחלו דרך הגדרת מערכת הצמתים.
פתרון בעיות נפוצות בזמן ריצה: שלבים נוספים לפתרון בעיות מפורטים במאמר פתרון בעיות בזמן הריצה של הקונטיינר.
פתרון בעיות במרחב השמות kube-node-lease
המשאבים במרחב השמות kube-node-lease אחראים לתקינות הצומת. אין למחוק את מרחב השמות הזה. אם תנסו למחוק את מרחב השמות הזה, הוא ייתקע בסטטוס Terminating. כשמרחב השמות kube-node-lease נתקע בסטטוס Terminating, ל-kubelets אין אפשרות לחדש את חוזי החכירה של בדיקות תקינות. הבעיה הזו גורמת לרמת הבקרה להתייחס לצמתים כאל צמתים לא תקינים, מה שמוביל לבעיה באשכול שבה הצמתים עוברים לסירוגין בין הסטטוסים Ready ו-NotReady.
תסמינים:
אם מופיעים התסמינים הבאים, סביר להניח שהסיבה לחוסר היציבות ברמת האשכול היא בעיה במרחב השמות kube-node-lease:
ביומני kubelet בכל צומת מוצגות שגיאות קבועות שדומות לשגיאות הבאות:
leases.coordination.k8s.io NODE_NAME is forbidden: unable to create new content in namespace kube-node-lease because it is being terminatedהצמתים באשכול עוברים שוב ושוב בין סטטוסים של
Readyל-NotReady.
הסיבה:
מרחב השמות kube-node-lease, שמנהל את האותות של צומת, תקוע באופן חריג בסטטוס Terminating. השגיאה הזו מונעת משרת ה-API של Kubernetes לאפשר יצירה או שינוי של אובייקט במרחב השמות. כתוצאה מכך, רכיבי ה-kubelet לא יכולים לחדש את אובייקטי ה-Lease שלהם, שהם חיוניים לסימון הפעילות שלהם למישור הבקרה. בלי עדכוני הסטטוס האלה, מישור הבקרה לא יכול לאשר שהצמתים תקינים, ולכן הסטטוסים של הצמתים מתחלפים בין Ready ל-NotReady.
הסיבות הבסיסיות לכך שמרחב השמות kube-node-lease עצמו עלול להיתקע בסטטוס Terminating כוללות:
- משאבים עם finalizers: למרות שזה פחות נפוץ במרחב השמות של המערכת
kube-node-lease(שמכיל בעיקר אובייקטים מסוגLease), יכול להיות שלמשאב בתוכו יש finalizer. Finalizers ב-Kubernetes הם מפתחות שמסמנים לבקר לבצע משימות ניקוי לפני שאפשר למחוק משאב. אם אמצעי הבקרה שאחראי להסרת ה-finalizer לא פועל בצורה תקינה, המשאב לא נמחק ותהליך המחיקה של מרחב השמות נעצר. - שירותי API מצטברים לא תקינים או לא מגיבים: יכול להיות שסיום מרחב השמות ייחסם אם אובייקט APIService, שמשמש לרישום שרת API מצטבר, מקושר למרחב השמות והופך ללא תקין. יכול להיות שרמת הבקרה תמתין עד ששרת ה-API המצטבר ייסגר או ינוקה בצורה תקינה, אבל זה לא יקרה אם השירות לא מגיב.
- בעיות ברמת הבקרה או בבקר: במקרים נדירים, באגים או בעיות ברמת הבקרה של Kubernetes, במיוחד בבקר של מרחב השמות, עלולים למנוע את איסוף הנתונים המיותרים ומחיקת מרחב השמות.
פתרון:
פועלים לפי ההנחיות במאמר בנושא פתרון בעיות של מרחבי שמות שנתקעו במצב Terminating.
פתרון בעיות בחיבור לרשת
בעיות ברשת יכולות למנוע מצומת לתקשר עם מישור הבקרה או למנוע מרכיבים קריטיים כמו תוסף CNI לפעול, מה שמוביל לסטטוס NotReady.
תסמינים:
אם אתם מבחינים בתסמינים הבאים, יכול להיות שבעיות ברשת הן הגורם לסטטוס NotReady של הצמתים:
- התנאי
NetworkNotReadyהואTrue. - ביומני Kubelet בצומת מופיעות שגיאות דומות לאלה:
connection timeout to the control plane IP addressnetwork plugin not readyCNI plugin not initialized- הודעות
connection refusedאוtimeoutכשמנסים להגיע לכתובת ה-IP של מישור הבקרה.
- פודים, במיוחד במרחב השמות
kube-system, נתקעים ב-ContainerCreatingעם אירועים כמוNetworkPluginNotReady.
הסיבה:
תסמינים שקשורים לרשת בדרך כלל מעידים על כשל באחד מהתחומים הבאים:
- בעיות בקישוריות: הצומת לא מצליח ליצור חיבור רשת יציב למישור הבקרה של Kubernetes.
- כשל בתוסף CNI: תוסף CNI, שאחראי להגדרת הרשת של Pod, לא פועל בצורה תקינה או שהאתחול שלו נכשל.
- בעיות ב-webhook: תגובות לפעולה מאתר אחר (webhooks) של אישור שהוגדרו באופן שגוי יכולות להפריע למשאבים שקשורים לפלאגין של CNI, ולמנוע את ההגדרה הנכונה של הרשת.
פתרון:
כדי לפתור בעיות ברשת:
טיפול בסטטוס
NetworkNotReadyזמני: בצמתים חדשים שנוצרו, זה נורמלי לראות אירועNetworkNotReadyקצר. הסטטוס הזה אמור להיפתר תוך דקה או שתיים בזמן שהתוסף CNI ורכיבים אחרים עוברים אתחול. אם הסטטוס לא משתנה, ממשיכים לשלבים הבאים.בודקים את הקישוריות בין הצומת לבין מישור הבקרה ואת כללי חומת האש: מוודאים שנתיב הרשת בין הצומת לבין מישור הבקרה פתוח ופועל בצורה תקינה:
- בדיקת הכללים של חומת האש: מוודאים שהכללים של חומת האש ב-VPC מאפשרים את תעבורת הנתונים הנדרשת בין צומתי GKE לבין מישור הבקרה. במאמר כללים של חומת אש שנוצרים באופן אוטומטי תוכלו לקרוא על הכללים שנדרשים ב-GKE לתקשורת בין הצומת למישור הבקרה.
- בדיקת הקישוריות: משתמשים בבדיקת הקישוריות במרכז Network Intelligence כדי לוודא את נתיב הרשת בין כתובת ה-IP הפנימית של הצומת לבין כתובת ה-IP של נקודת הקצה של מישור הבקרה ביציאה
443. תוצאה שלNot Reachableעוזרת לכם לזהות את כלל חומת האש או את בעיית הניתוב שחוסמת את התקשורת.
בודקים את הסטטוס והיומנים של פלאגין CNI: אם הרשת של הצומת לא מוכנה, יכול להיות שהבעיה היא בפלאגין CNI.
בדיקת הסטטוס של ה-Pod של CNI: מזהים את הפלאגין של CNI שנמצא בשימוש (לדוגמה,
netdאוcalico-node) ובודקים את הסטטוס של ה-Pods שלו במרחב השמותkube-system. אפשר לסנן לפי הצומת הספציפי באמצעות הפקודה הבאה:kubectl get pods \ -n kube-system \ -o wide \ --field-selector spec.nodeName=NODE_NAME \ | grep -E "netd|calico|anetd"בדיקת היומנים של CNI Pod: אם ה-Pods לא פועלים בצורה תקינה, צריך לבדוק את היומנים שלהם ב-Cloud Logging כדי לראות הודעות שגיאה מפורטות. כדי להשתמש ב-
netdPods בצומת ספציפי, אפשר להשתמש בשאילתה שדומה לזו:resource.type="k8s_container" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" resource.labels.namespace_name="kube-system" labels."k8s-pod/app"="netd" resource.labels.node_name="NODE_NAME" severity>=WARNINGטיפול בשגיאות ספציפיות של CNI:
- אם ביומנים מופיע
Failed to allocate IP address, יכול להיות שטווח כתובות ה-IP של ה-Pod מוצה. בודקים את השימוש בכתובות ה-IP של Pod ובוחנים את טווחי ה-CIDR של האשכול. - אם ביומנים מופיע
NetworkPluginNotReadyאוcni plugin not initialized, צריך לוודא שיש מספיק משאבי מעבד וזיכרון בצומת. אפשר גם לנסות להפעיל מחדש את ה-Pod של CNI על ידי מחיקה שלו, כדי לאפשר ל-DaemonSet ליצור אותו מחדש. - אם אתם משתמשים ב-GKE Dataplane V2 והיומנים מציגים
Cilium API client timeout exceeded, מפעילים מחדש את ה-Podanetdבצומת.
- אם ביומנים מופיע
בדיקה אם יש הפרעה ל-admission webhook: תקלות ב-webhooks יכולות למנוע את ההפעלה של פודים של CNI, ולהשאיר את הצומת בסטטוס
NetworkNotReady.בדיקת יומני שרת ה-API: בודקים את יומני שרת ה-API ב-Cloud Logging כדי לאתר שגיאות שקשורות לקריאות ל-webhook. כדי לזהות אם webhook חוסם יצירה של משאב CNI, מחפשים הודעות כמו
failed calling webhook.אם webhook גורם לבעיות, יכול להיות שתצטרכו לזהות את
ValidatingWebhookConfigurationאו אתMutatingWebhookConfigurationהבעייתיים ולהשבית אותם באופן זמני כדי לאפשר לצומת להיות מוכן. מידע נוסף זמין במאמר פתרון בעיות שנגרמו על ידי תגובות לפעולה מאתר אחר (webhook) של בקרת גישה.
פתרון בעיות שקשורות להגדרות שגויות של אשכולות
בקטעים הבאים מוסבר איך לבדוק כמה הגדרות ברמת האשכול שעשויות להפריע לפעולות רגילות של הצמתים.
פתרון בעיות שנגרמו על ידי תגובות לפעולה מאתרי אימות (admission webhooks)
אם יש בעיה בהגדרת ה-webhook של בקרת הכניסה, אם הוא לא זמין או אם הוא איטי מדי, הוא עלול לחסום בקשות API קריטיות ולמנוע הפעלה של רכיבים חיוניים או הצטרפות של צמתים לאשכול.
תסמינים:
אם אתם רואים את התסמינים הבאים, סביר להניח ש-webhook של בקרת כניסה שהוגדר בצורה שגויה או לא זמין חוסם פעולות חיוניות של אשכול:
- Pods, במיוחד במרחב השמות
kube-system(כמו CNI או Pods של אחסון), תקועים במצבPendingאוTerminating. - צמתים חדשים לא מצליחים להצטרף לאשכול, ולעתים קרובות חלף הזמן הקצוב לתפוגה עם סטטוס
NotReady.
הסיבה:
יכול להיות ש-admission webhooks שלא הוגדרו נכון או שלא מגיבים חוסמים פעולות חיוניות באשכול.
פתרון:
בודקים את הגדרות ה-webhook כדי לוודא שהן עמידות ומוגדרות בהיקף הנכון. כדי למנוע הפסקות, צריך להגדיר את השדה failurePolicy לערך Ignore ל-webhooks לא קריטיים. כדי למנוע מצבים של קיפאון במישור הבקרה, חשוב לוודא שהשירות שתומך ב-webhook קריטי זמין מאוד, ולהחריג את מרחב השמות kube-system מפיקוח ה-webhook באמצעות namespaceSelector. למידע נוסף, ראו איך מוודאים את היציבות של מישור הבקרה כשמשתמשים ב-webhooks.
פתרון בעיות שנגרמות בגלל מכסות משאבים
חישוב שגוי של מכסת משאבים במרחב השמות kube-system יכול למנוע מ-GKE ליצור פודים קריטיים של המערכת. הבעיה הזו יכולה למנוע מצמתים חדשים להצטרף לאשכול בהצלחה, כי רכיבים כמו רשת (CNI) ו-DNS חסומים.
תסמינים:
- Pods קריטיים במרחב השמות
kube-system(לדוגמה,netd,konnectivity-agentאוkube-dns) תקועים בסטטוסPending. - הודעות שגיאה ביומני האשכול או בפלט
kubectl describe podמציגות כשלים כמוexceeded quota: gcp-critical-pods.
הסיבה:
הבעיה הזו מתרחשת כשבקר מכסת המשאבים של Kubernetes מפסיק לעדכן באופן מדויק את מספר האובייקטים מסוג ResourceQuota שנמצאים בשימוש. אחת הסיבות הנפוצות היא שגיאה ב-webhook של צד שלישי שמונעת את העדכונים של בקר הכניסה, ולכן נראה שהשימוש במכסת הנתונים גבוה בהרבה ממה שהוא בפועל.
פתרון:
- סביר להניח שהגורם לבעיה הוא webhook בעייתי. לכן, כדי לזהות ולתקן את ה-webhooks שחוסמים את רכיבי המערכת, צריך לפעול לפי ההוראות בקטע פתרון בעיות שנגרמו על ידי webhooks של בקרת גישה. ברוב המקרים, תיקון ה-webhook פותר את בעיית המכסה באופן אוטומטי.
מוודאים שהשימוש המתועד במכסה לא מסונכרן עם המספר בפועל של Pods שפועלים. בשלב הזה בודקים אם הערך של המונה באובייקט ResourceQuota שגוי:
בודקים את נפח השימוש המדווח במכסה:
kubectl get resourcequota gcp-critical-pods -n kube-system -o yamlבודקים את המספר בפועל של Pods:
kubectl get pods -n kube-system --no-headers | wc -l
אם מספר הפריטים בשימוש ב-
ResourceQuotaנראה שגוי (לדוגמה, גבוה בהרבה מהמספר בפועל של Pods), מחקו את האובייקטgcp-critical-pods. מישור הבקרה של GKE מתוכנן ליצור מחדש את האובייקט הזה באופן אוטומטי עם ספירות השימוש הנכונות והמתואמות:kubectl delete resourcequota gcp-critical-pods -n kube-systemעוקבים אחרי מרחב השמות
kube-systemלמשך כמה דקות כדי לוודא שהאובייקט נוצר מחדש ושהתזמון של ה-Pods בהמתנה מתחיל.
פתרון בעיות שנגרמות על ידי DaemonSets של צד שלישי
DaemonSet של צד שלישי שזה עתה נפרס או עודכן, ומשמש לעיתים קרובות לאבטחה, למעקב או לרישום ביומן, עלול לגרום לחוסר יציבות של הצומת. הבעיה הזו יכולה לקרות אם DaemonSet מפריע לזמן הריצה של הקונטיינר או לרשת של הצומת, צורך משאבי מערכת מוגזמים או מבצע שינויים לא צפויים במערכת.
תסמינים:
אם אתם מבחינים בתסמינים הבאים, יכול להיות ש-DaemonSet של צד שלישי שנפרס או שונה לאחרונה גורם לכשלים בצומת:
- כמה צמתים, שיכול להיות שהם נמצאים באשכול, נכנסים למצב
NotReadyזמן קצר אחרי הפריסה או העדכון של DaemonSet. - ביומני Kubelet של הצמתים המושפעים מדווחות שגיאות כמו:
container runtime is downFailed to create pod sandbox- שגיאות בחיבור לשקע של זמן הריצה של הקונטיינר (לדוגמה,
/run/containerd/containerd.sock).
- פודים, כולל פודים של המערכת או פודים של DaemonSet, תקועים במצב
PodInitializingאוContainerCreating. - ביומני מאגרי התגים של האפליקציות מוצגות שגיאות חריגות, כמו
exec format error. - יכול להיות ש-Node Problem Detector ידווח על תנאים שקשורים לתקינות של זמן הריצה או ללחץ על המשאבים.
הסיבה:
יכול להיות שה-DaemonSet של הצד השלישי משפיע על היציבות של הצומת מהסיבות הבאות:
- צריכה מוגזמת של מעבד (CPU), זיכרון או קלט/פלט (I/O) של דיסק, שמשפיעה על הביצועים של רכיבי צומת קריטיים.
- הפרעה לפעולה של זמן הריצה של הקונטיינר.
- גורם לקונפליקטים עם הגדרת הרשת של הצומת או עם התוסף Container Network Interface (CNI).
- שינוי הגדרות המערכת או מדיניות האבטחה באופן לא מכוון.
פתרון:
כדי לבדוק אם DaemonSet הוא הגורם לבעיה, מבודדים אותו ובודקים אותו:
זיהוי DaemonSets: מציגים את כל ה-DaemonSets שפועלים באשכול:
kubectl get daemonsets --all-namespacesחשוב לשים לב במיוחד ל-DaemonSets שלא נכללים בהתקנת ברירת המחדל של GKE.
לרוב אפשר לזהות את ה-DaemonSets האלה על ידי בדיקה של:
- Namespace (מרחב שמות): רכיבי GKE שמוגדרים כברירת מחדל פועלים בדרך כלל במרחב השמות
kube-system. סביר להניח שקבוצות DaemonSet במרחבי שמות אחרים הן של צד שלישי או בהתאמה אישית. - שמות: ל-DaemonSet שמוגדרים כברירת מחדל יש בדרך כלל שמות כמו
gke-metrics-agent,netdאוcalico-node. לסוכנים של צד שלישי יש לרוב שמות שמשקפים את המוצר.
- Namespace (מרחב שמות): רכיבי GKE שמוגדרים כברירת מחדל פועלים בדרך כלל במרחב השמות
השוואה בין זמן הפריסה: בודקים אם המופעים של צמתי
NotReadyחופפים לפריסה או לעדכון של DaemonSet ספציפי של צד שלישי.בדיקה בצומת יחיד:
- בוחרים צומת אחד שמושפע.
- מבודדים ומרוקנים את הצומת.
- מונעים באופן זמני מה-DaemonSet לתזמן בצומת הזה:
- החלת תווית צומת זמנית והגדרת זיקה או אנטי-זיקה של צומת במניפסט של DaemonSet.
- מוחקים את ה-Pod של ה-DaemonSet בצומת הספציפי הזה.
- מפעילים מחדש את המכונה הווירטואלית של הצומת.
- בודקים אם הצומת הופך ל-
Readyונשאר יציב בזמן ש-DaemonSet לא פועל בו. אם הבעיות יחזרו אחרי שתחזירו את DaemonSet, סביר להניח שהוא גורם לבעיות.
כדאי לעיין במסמכי התיעוד של הספק: אם אתם חושדים שסוכן צד שלישי הוא הגורם לבעיה, כדאי לעיין במסמכי התיעוד של הספק כדי לראות אם יש בעיות תאימות ידועות או שיטות מומלצות להפעלת הסוכן ב-GKE. אם אתם צריכים תמיכה נוספת, אתם יכולים לפנות לספק התוכנה.
מוודאים שהצומת שוחזר
אחרי שמחילים פתרון פוטנציאלי, צריך לפעול לפי השלבים הבאים כדי לוודא שהצומת שוחזר בהצלחה ויציב:
בודקים את הסטטוס של הצומת:
kubectl get nodes -o wideמחפשים את הצומת המושפע בפלט. עכשיו בעמודה
Statusאמור להופיע הערךReady. יכול להיות שיעברו כמה דקות עד שהסטטוס יתעדכן אחרי שהתיקון יוחל. אם הסטטוס עדייןNotReadyאו שהוא משתנה לסירוגין בין סטטוסים שונים, סימן שהבעיה לא נפתרה באופן מלא.בודקים את הקטע
Conditionsשל הצומת:kubectl describe node NODE_NAMEבקטע
Conditions, בודקים את הערכים הבאים:- התנאי
Readyהוא בסטטוסTrue. - התנאים השליליים שהסטטוס שלהם היה
True(לדוגמה,MemoryPressureאוNetworkUnavailable) מקבלים עכשיו את הסטטוסFalse. בשדותReasonו-Messageשל התנאים האלה צריך לציין שהבעיה נפתרה.
- התנאי
תזמון של Pod לבדיקה. אם הצומת לא הצליח להריץ עומסי עבודה בעבר, צריך לבדוק אם מתוזמנים בו פודים חדשים ואם פודים קיימים פועלים ללא בעיות:
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAMEהסטטוס של Pods בצומת צריך להיות
RunningאוCompleted. לא אמורים לראות Pods תקועים בסטטוסPendingאו בסטטוסי שגיאה אחרים.
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו להיעזר בקבלת תמיכה, כולל עצות בנושאים הבאים:
- לפתוח בקשת תמיכה באמצעות פנייה ל-Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אתם יכולים גם להצטרף לערוץ Slack של#kubernetes-engineכדי לקבל תמיכה מהקהילה. - דיווח על בעיות או שליחת בקשות להוספת תכונות באמצעות הכלי הציבורי Issue Tracker.