בעיות באשכולות Autopilot של Google Kubernetes Engine (GKE) יכולות להשפיע על הזמינות של האפליקציה ועל היעילות התפעולית שלה. הבעיות האלה עלולות לשבש את כל מחזור החיים של האפליקציות, החל מהפריסה הראשונית ועד להתאמה של האפליקציה לשינויים בעומס.
בדף הזה אפשר לאבחן ולפתור בעיות נפוצות שספציפיות לאשכולות של Autopilot. במאמר הזה מוסבר איך לפתור בעיות שמונעות הקצאת משאבים לאשכול, בעיות שקשורות לשינוי גודל האשכול כמו שגיאות out
of resources, ובעיות שקשורות לעומסי עבודה כמו שגיאות באחסון זמני או פודים שנתקעו במצב Pending.
המידע הזה חשוב למפתחי אפליקציות שצריכים לוודא שהאפליקציות שלהם נפרסות ופועלות בצורה חלקה, ולמנהלי פלטפורמה ולמפעילים שאחראים על התקינות הכוללת ועל ניהול המשאבים של אשכולות Autopilot. מידע נוסף על התפקידים הנפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם בתוכן של Google Cloud זמין במאמר תפקידי משתמשים נפוצים ומשימות ב-GKE.
בעיות באשכול
אי אפשר ליצור אשכול: לא נרשמו צמתים
הבעיה הבאה מתרחשת כשמנסים ליצור אשכול Autopilot עם חשבון שירות IAM שמושבת או שאין לו את ההרשאות הנדרשות. יצירת האשכול נכשלת עם הודעת השגיאה הבאה:
All cluster resources were brought up, but: only 0 nodes out of 2 have registered.
כדי לפתור את הבעיה:
בודקים אם חשבון השירות שמוגדר כברירת מחדל ב-Compute Engine או חשבון השירות המותאם אישית ב-IAM שרוצים להשתמש בו מושבת:
gcloud iam service-accounts describe SERVICE_ACCOUNTמחליפים את
SERVICE_ACCOUNTבכתובת האימייל של חשבון השירות, לדוגמהmy-iam-account@my-first-project.iam.gserviceaccount.com.אם חשבון השירות מושבת, הפלט דומה לפלט הבא:
disabled: true displayName: my-service-account email: my-service-account@my-project.iam.gserviceaccount.com ...אם חשבון השירות מושבת, צריך להפעיל אותו:
gcloud iam service-accounts enable SERVICE_ACCOUNT
אם חשבון השירות מופעל והשגיאה נמשכת, צריך להעניק לחשבון השירות את ההרשאות המינימליות שנדרשות ל-GKE:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:SERVICE_ACCOUNT" \
--role roles/container.defaultNodeServiceAccount
מרחב שמות נתקע במצב Terminating (סיום) כשלצבר יש 0 צמתים
הבעיה הבאה מתרחשת כשמוחקים מרחב שמות באשכול אחרי שהאשכול מצטמצם לאפס צמתים. רכיב metrics-server לא יכול לקבל את בקשת המחיקה של מרחב השמות כי יש לו אפס עותקים.
כדי לאבחן את הבעיה, מריצים את הפקודה הבאה:
kubectl describe ns/NAMESPACE_NAME
מחליפים את NAMESPACE_NAME בשם של מרחב השמות.
הפלט שיתקבל:
Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request
כדי לפתור את הבעיה, צריך להגדיל את עומס העבודה כדי להפעיל את GKE ליצירת צומת חדש. כשהצומת מוכן, הבקשה למחיקת מרחב השמות מסתיימת באופן אוטומטי. אחרי ש-GKE מוחק את מרחב השמות, מצמצמים את עומס העבודה.
בעיות שקשורות לשינוי גודל
הגדלת קנה המידה של הצומת נכשלה: קיים סיכון שה-Pod לא יתוזמן
הבעיה הבאה מתרחשת כשרישום ביומן של יציאה טורית מושבת בGoogle Cloud פרויקט. כדי לנפות ביעילות בעיות בצמתים באשכולות GKE Autopilot, צריך להפעיל רישום ביומן של יציאה טורית. אם הרישום ביומן של יציאה טורית מושבת, Autopilot לא יכול להקצות צמתים להרצת עומסי העבודה.
הודעת השגיאה ביומן האירועים של Kubernetes דומה להודעה הבאה:
LAST SEEN TYPE REASON OBJECT MESSAGE
12s Warning FailedScaleUp pod/pod-test-5b97f7c978-h9lvl Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled
יכול להיות שהרישום ביומן של יציאה טורית מושבת ברמת הארגון באמצעות מדיניות ארגונית שמחייבת את האילוץ compute.disableSerialPortLogging. אפשר גם להשבית את הרישום ביומן של היציאה הטורית ברמת הפרויקט או ברמת המכונה הווירטואלית (VM).
כדי לפתור את הבעיה:
- צריך לבקש מהאדמין של מדיניות הארגון Google Cloud להסיר את האילוץ
compute.disableSerialPortLoggingבפרויקט עם אשכול Autopilot. - אם אין לכם מדיניות ארגון שמחילה את האילוץ הזה, נסו להפעיל את הכתיבה ליומן של היציאה הטורית במטא-נתונים של הפרויקט.
כדי לבצע את הפעולה הזו נדרשת הרשאת IAM
compute.projects.setCommonInstanceMetadata.
הגדלת הקיבולת של הצומת נכשלה: אין מספיק משאבים ב-GCE
הבעיה הבאה מתרחשת כשעומסי העבודה שלכם מבקשים יותר משאבים מאלה שזמינים לשימוש באזור או בתחום של Compute Engine. יכול להיות שה-Pods יישארו במצב Pending.
בודקים את האירועים ב-Pod:
kubectl events --for='pod/POD_NAME' --types=Warningמחליפים את
RESOURCE_NAMEבשם של משאב Kubernetes בהמתנה. לדוגמהpod/example-pod.הפלט אמור להיראות כך:
LAST SEEN TYPE REASON OBJECT Message 19m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 14m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 12m (x2 over 18m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled. 34s (x3 over 17m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
כדי לפתור את הבעיה, נסו את הפתרונות הבאים:
- פורסים את ה-Pod באזור או באזור אחר. אם ל-Pod שלכם יש הגבלה אזורית, כמו בורר טופולוגיה, כדאי להסיר את ההגבלה אם אפשר. הוראות מפורטות במאמר בנושא מיקום של פודים של GKE באזורים ספציפיים.
- יוצרים אשכול באזור אחר ומנסים שוב לפרוס את האפליקציה.
- נסו להשתמש בסוג אחר של מכונת חישוב. יש סיכוי גבוה יותר שיהיו משאבים זמינים בכיתות Compute שמגובות על ידי סוגים קטנים יותר של מכונות ב-Compute Engine. לדוגמה, סוג המכונה שמוגדר כברירת מחדל ב-Autopilot הוא בעל הזמינות הגבוהה ביותר. רשימה של מחלקות מחשוב וסוגי המכונות התואמים מופיעה במאמר מתי כדאי להשתמש במחלקות מחשוב ספציפיות.
- אם אתם מריצים עומסי עבודה של GPU, יכול להיות שה-GPU המבוקש לא יהיה זמין במיקום הצומת. נסו לפרוס את עומס העבודה במיקום אחר או לבקש סוג אחר של GPU.
כדי למנוע בעיות בהרחבת היקף הפעילות בעתיד בגלל זמינות משאבים, כדאי לשקול את הגישות הבאות:
- שימוש ב-Kubernetes PriorityClasses כדי להקצות באופן עקבי קיבולת מחשוב נוספת באשכול. פרטים נוספים זמינים במאמר בנושא הקצאת קיבולת מחשוב נוספת להרחבת Pod מהירה.
- שימוש בהזמנות של קיבולת ב-Compute Engine עם מחלקות המחשוב Performance או Accelerator. פרטים נוספים זמינים במאמר בנושא שימוש במשאבים שמורים של אזור מוגדר.
הצמתים לא מצליחים להתרחב: חריגה ממגבלות המשאבים של ה-Pod באזור
הבעיה הבאה מתרחשת כש-Autopilot לא מקצה צמתים חדשים ל-Pod באזור מסוים כי צומת חדש יגרום לחריגה ממגבלות המשאבים.
הודעת השגיאה ביומנים דומה להודעה הבאה:
"napFailureReasons": [
{
"messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
...
השגיאה הזו מתייחסת לאירוע noScaleUp, שבו הקצאת משאבים אוטומטית של צומת לא הקצתה אף קבוצת צמתים ל-Pod באזור.
אם נתקלתם בשגיאה הזו, כדאי לבדוק את הדברים הבאים:
- ל-Pods יש מספיק זיכרון ומעבד.
- טווח ה-CIDR של כתובות ה-IP של ה-Pod גדול מספיק כדי לתמוך בגודל המקסימלי הצפוי של האשכול.
בעיות בעומסי עבודה
עומסי עבודה נתקעים בגלל שגיאה באחסון זמני
מערכת GKE לא תיצור Pod אם בקשות האחסון הזמני של ה-Pod חורגות מהמקסימום של 10GiB ב-Autopilot ב-GKE בגרסה 1.28.6-gke.1317000 ואילך.
כדי לאבחן את הבעיה הזו, צריך לתאר את בקרת עומס העבודה, כמו Deployment או Job:
kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME
מחליפים את מה שכתוב בשדות הבאים:
-
CONTROLLER_TYPE: הסוג של בקר עומס העבודה, כמוreplicasetאוdaemonset. רשימה של סוגי בקרים מופיעה במאמר ניהול עומסי עבודה. -
CONTROLLER_NAME: השם של עומס העבודה התקוע.
אם ה-Pod לא נוצר כי הבקשה לאחסון זמני חורגת מהמקסימום, הפלט ייראה כך:
# lines omitted for clarity
Events:
{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}
כדי לפתור את הבעיה, צריך לעדכן את הבקשות לאחסון זמני כך שהנפח הכולל של האחסון הזמני שנדרש על ידי קונטיינרים של עומסי עבודה ועל ידי קונטיינרים שמוזרקים על ידי ווּב-הוּקים יהיה קטן מהנפח המקסימלי המותר או שווה לו. מידע נוסף על המקסימום זמין במאמר בקשות למשאבים ב-Autopilot בנושא הגדרת עומס העבודה.
חבילות (Pods) נתקעות במצב Pending
יכול להיות ש-Pod ייתקע במצב Pending אם תבחרו צומת ספציפי לשימוש ב-Pod, אבל סכום בקשות המשאבים ב-Pod וב-DaemonSets שצריכים לפעול בצומת יעלה על הקיבולת המקסימלית שניתן להקצות לצומת. יכול להיות שהסטטוס של ה-Pod יהיה Pending והוא יישאר לא מתוזמן.
כדי להימנע מהבעיה הזו, צריך לבדוק את הגדלים של עומסי העבודה שפרסתם כדי לוודא שהם לא חורגים מבקשות המשאבים המקסימליות הנתמכות ב-Autopilot.
אפשר גם לנסות לתזמן את DaemonSets לפני שתזמנו את פודי העומס הרגילים.
ביצועים לא אמינים של עומס עבודה בצורה עקבית בצומת ספציפי
בגרסה 1.24 של GKE ואילך, אם עומסי העבודה בצומת מסוים חווים שיבושים, קריסות או התנהגות לא אמינה דומה באופן עקבי, אפשר להודיע ל-GKE על הצומת הבעייתי באמצעות בידוד שלו באמצעות הפקודה הבאה:
kubectl drain NODE_NAME --ignore-daemonsets
מחליפים את NODE_NAME בשם הצומת הבעייתי.
אפשר להריץ את הפקודה kubectl get nodes כדי למצוא את שם הצומת.
GKE מבצע את הפעולות הבאות:
- מפנה עומסי עבודה קיימים מהצומת ומפסיק לתזמן עומסי עבודה בצומת הזה.
- יצירה מחדש באופן אוטומטי של עומסי עבודה שסולקו ומנוהלים על ידי בקר, כמו Deployment או StatefulSet, בצמתים אחרים.
- מפסיק את כל עומסי העבודה שנותרו בצומת ומתקן או יוצר מחדש את הצומת לאורך זמן.
- אם משתמשים ב-Autopilot, GKE מכבה את הצומת ומחליף אותו באופן מיידי, ומתעלם מכל תקציב שהוגדר להפרעות ב-Pod.
תזמון של פודים באשכולות ריקים נמשך יותר זמן מהצפוי
האירוע הזה מתרחש כשפורסים עומס עבודה באשכול Autopilot שאין בו עומסי עבודה אחרים. אשכולות Autopilot מתחילים עם אפס צמתים שניתן להשתמש בהם, ומתרחבים לאפס צמתים אם האשכול ריק, כדי למנוע מצב שבו יש באשכול משאבי מחשוב שלא נעשה בהם שימוש. פריסת עומס עבודה באשכול עם אפס צמתים מפעילה אירוע של הגדלת הקיבולת.
אם נתקלתם במצב כזה, המשמעות היא שהטייס האוטומטי פועל כמצופה ואין צורך לבצע פעולה כלשהי. עומס העבודה ייפרס כצפוי אחרי שהצמתים החדשים יופעלו.
בודקים אם ה-Pods ממתינים לצמתים חדשים:
תאר את ה-Pod בהמתנה:
kubectl describe pod POD_NAMEמחליפים את
POD_NAMEבשם של ה-Pod בהמתנה.בודקים את הקטע
Eventsבפלט. אם ה-Pod ממתין לצמתים חדשים, הפלט אמור להיראות כך:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 11s gke.io/optimize-utilization-scheduler no nodes available to schedule pods Normal TriggeredScaleUp 4s cluster-autoscaler pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]האירוע
TriggeredScaleUpמציין שהאשכול מתרחב מאפס צמתים למספר הצמתים שנדרש להפעלת עומס העבודה שנפרס.
תזמון של System Pods באשכולות ריקים נכשל
האירוע הזה מתרחש כשאין עומסי עבודה שלכם שפועלים באשכול, וכתוצאה מכך האשכול מצטמצם לאפס צמתים. אשכולות במצב Autopilot מתחילים עם אפס צמתים שניתן להשתמש בהם, ומתכווצים לאפס צמתים אם לא מריצים באשכול אף אחד מעומסי העבודה. ההתנהגות הזו מצמצמת את בזבוז משאבי המחשוב באשכול.
כשמצמצמים את מספר הצמתים באשכול לאפס, עומסי העבודה של מערכת GKE לא מתוזמנים ונשארים במצב Pending. זו התנהגות צפויה ולא נדרשת פעולה. בפעם הבאה שתפרסו עומס עבודה באשכול, GKE יגדיל את האשכול ופודים של המערכת בהמתנה יפעלו בצמתים האלה.
כדי לבדוק אם ה-Pods של המערכת נמצאים בהמתנה בגלל אשכול ריק, מבצעים את הפעולות הבאות:
בודקים אם יש צמתים באשכול:
kubectl get nodesהפלט שמתקבל הוא הבא, שמציין שלקלאסטר אין צמתים:
No resources foundבודקים את הסטטוס של ה-Pods במערכת:
kubectl get pods --namespace=kube-systemהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE antrea-controller-horizontal-autoscaler-6d97f7cf7c-ngfd2 0/1 Pending 0 9d egress-nat-controller-84bc985778-6jcwl 0/1 Pending 0 9d event-exporter-gke-5c5b457d58-7njv7 0/2 Pending 0 3d5h event-exporter-gke-6cd5c599c6-bn665 0/2 Pending 0 9d konnectivity-agent-694b68fb7f-gws8j 0/2 Pending 0 3d5h konnectivity-agent-7d659bf64d-lp4kt 0/2 Pending 0 9d konnectivity-agent-7d659bf64d-rkrw2 0/2 Pending 0 9d konnectivity-agent-autoscaler-5b6ff64fcd-wn7fw 0/1 Pending 0 9d konnectivity-agent-autoscaler-cc5bd5684-tgtwp 0/1 Pending 0 3d5h kube-dns-65ccc769cc-5q5q7 0/5 Pending 0 3d5h kube-dns-7f7cdb9b75-qkq4l 0/5 Pending 0 9d kube-dns-7f7cdb9b75-skrx4 0/5 Pending 0 9d kube-dns-autoscaler-6ffdbff798-vhvkg 0/1 Pending 0 9d kube-dns-autoscaler-8b7698c76-mgcx8 0/1 Pending 0 3d5h l7-default-backend-87b58b54c-x5q7f 0/1 Pending 0 9d metrics-server-v1.31.0-769c5b4896-t5jjr 0/1 Pending 0 9dבודקים את הסיבה לסטטוס
Pendingשל ה-Pods במערכת:kubectl describe pod --namespace=kube-system SYSTEM_POD_NAMEמחליפים את
SYSTEM_POD_NAMEבשם של Pod במערכת מהפלט של הפקודה הקודמת.הפלט אמור להיראות כך:
... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 4m35s (x27935 over 3d5h) default-scheduler no nodes available to schedule pods ...בפלט, הערך
no nodes available to schedule podsבשדהMessageשל האירועFailedSchedulingמציין שלא בוצע תזמון של ה-Pod של המערכת כי האשכול ריק.
שגיאה שקשורה להרשאה בניסיון להריץ tcpdump מ-Pod ב-GKE Autopilot
הגישה לצמתים הבסיסיים אסורה באשכול GKE Autopilot. לכן, צריך להריץ את כלי השירות tcpdump מתוך Pod ואז להעתיק אותו באמצעות הפקודה kubectl cp.
אם בדרך כלל מריצים את כלי השירות tcpdump מתוך Pod באשכול GKE Autopilot, יכול להיות שתופיע השגיאה הבאה:
tcpdump: eth0: You don't have permission to perform this capture on that device
(socket: Operation not permitted)
הסיבה לכך היא ש-GKE Autopilot מחיל כברירת מחדל הקשר אבטחה על כל ה-Pods, שמבטל את היכולת NET_RAW כדי לצמצם נקודות חולשה פוטנציאליות. לדוגמה:
apiVersion: v1
kind: Pod
metadata:
labels:
app: tcpdump
name: tcpdump
spec:
containers:
- image: nginx
name: nginx
resources:
limits:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
requests:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
securityContext:
capabilities:
# This section drops NET_RAW to mitigate security vulnerabilities
drop:
- NET_RAW
כפתרון, אם עומס העבודה שלכם דורש את היכולת NET_RAW, אתם יכולים להפעיל אותה מחדש:
מוסיפים את היכולת
NET_RAWלקטעsecurityContextבמפרט ה-YAML של ה-Pod:securityContext: capabilities: add: - NET_RAWמריצים את הפקודה
tcpdumpמתוך Pod:tcpdump port 53 -w packetcap.pcap tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytesמשתמשים בפקודה
kubectl cpכדי להעתיק אותו למכונה המקומית לצורך ניתוח נוסף:kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAMEמשתמשים ב-
kubectl execכדי להריץ את הפקודהtcpdumpכדי לבצע תיעוד של חבילות נתונים ברשת ולהפנות את הפלט:kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
אי אפשר להריץ Pods בצומת בגלל כשל ב-NRI RunPodSandbox
במקרים נדירים, צומת Autopilot בסוגי מחשוב ברירת המחדל, מאוזן, Scale-Out, autopilot ו-autopilot-spot יכול להיכנס למצב שבו פודים של המערכת, כמו anetd, ופודים של משתמשים שהוקצו לצומת, לא יכולים לעבור למצב פעיל. אם anetd לא יכול לעבור למצב פעיל, סימן שהרישות של ה-Pod פגום חלקית או לגמרי בצומת. מצב השגיאה הזה מופעל רק במהלך שדרוגים מסוימים של מישור הבקרה של האשכול.
אם אתם מבחינים בבעיה, אתם יכולים לצמצם אותה בצומת מסוים באמצעות ההליך לצמצום בעיות בביצועי עומס עבודה לא אמינים בצומת מסוים.
כדי למנוע את חזרת הבעיה, צריך לשדרג ידנית את האשכול לאחת מגרסאות התיקונים הבאות של GKE:
- 1.35: כל גרסאות התיקון
- 1.34: 1.34.1-gke.3899000 ואילך
- 1.33: גרסה 1.33.5-gke.2392000 ואילך
אם אתם חושדים שצומת נמצא במצב השגיאה הזה, אתם יכולים לבצע את הפעולות הבאות כדי לוודא זאת:
מוצאים את
efficiency-daemonPod שפועל בצומת החשוד:DAEMON_POD_NAME=$(kubectl get pods \ --namespace kube-system \ --selector k8s-app=efficiency-daemon \ --field-selector spec.nodeName=NODE_NAME \ --output custom-columns=":metadata.name" \ --no-headers) echo $DAEMON_POD_NAMEאם אין
efficiency-daemonpod בצומת, הצומת לא מושפע מהבעיה הספציפית הזו.בודקים אם יש שגיאות ספציפיות ב-
efficiency-daemonPod:kubectl logs -n kube-system $DAEMON_POD_NAME | grep "connect: operation not permitted" | wc -lאם הפלט גדול מ-
10, סביר מאוד שהצומת מושפע מהבעיה הזו.
אם הודעת השגיאה הבאה מופיעה שוב ושוב באירועים של Pod עבור Pod שהוקצה לצומת, סימן שהצומת מושפע מהבעיה הזו: Failed to create pod sandbox: rpc error: code = Unknown desc = NRI RunPodSandbox failed: rpc error: code = Unknown desc = internal error: reconciliation failed.
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו להיעזר בקבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אפשר גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה נוספת מהקהילה. - פתיחת דיווחים על בעיות או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.