בעיות באחסון באשכולות Google Kubernetes Engine (GKE) יכולות להתבטא בדרכים שונות, החל מנקודות צוואר בקבוק בביצועים וכשלים בהרכבת נפחים, ועד לשגיאות בשימוש בסוגי דיסקים ספציפיים עם סוגי מכונות מסוימים. הבעיות האלה יכולות להשפיע על מצב האפליקציה, על שמירת הנתונים ועל תקינות העומס הכולל.
במאמר הזה מוסבר איך לפתור בעיות נפוצות שמשפיעות על פונקציונליות האחסון באשכולות. במאמר הזה מוסבר איך לפתור בעיות שקשורות להקצאה ולצירוף של נפח אחסון, לגישה לנתונים ולביצועים, ולניהול קיבולת האחסון.
המידע הזה חשוב לאדמינים ולמפעילים של פלטפורמות שמנהלים תשתית ואחסון של אשכולות, ולמפתחי אפליקציות שעומסי העבודה שלהם מסתמכים על אחסון קבוע. מידע נוסף על התפקידים הנפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם בתוכן של Google Cloud זמין במאמר תפקידי משתמשים נפוצים ומשימות ב-GKE.
שגיאה 400: אי אפשר לצרף RePD למכונה וירטואלית שעברה אופטימיזציה
מוגבלת האפשרות להשתמש בדיסקים לאחסון מתמיד אזורי עם מכונות מותאמות לצריכת זיכרון גבוהה (memory-optimized) או עם מכונות מותאמות לצריכת מעבד גבוהה (compute-optimized).
אם השימוש בדיסק לאחסון מתמיד אזורי הוא לא דרישה מחייבת, כדאי לשקול שימוש בסוג אחסון של דיסק לאחסון מתמיד לא אזורי. אם השימוש בדיסק לאחסון מתמיד אזורי הוא דרישה מחייבת, כדאי לשקול שימוש באסטרטגיות תזמון כמו taints ו-tolerations כדי לוודא שה-Pods שזקוקים לדיסקים לאחסון מתמיד אזורי מתוזמנים במאגר צמתים שלא כולל מכונות שעברו אופטימיזציה.
פתרון בעיות בביצועים של הדיסק
ביצועי דיסק האתחול חשובים כי דיסק האתחול של צמתי GKE משמש לא רק למערכת ההפעלה אלא גם ל:
- קובצי אימג' של Docker.
- מערכת הקבצים של הקונטיינר עבור מה שלא מותקן כנפח (כלומר, מערכת הקבצים של שכבת העל), ולרוב כוללת ספריות כמו
/tmp. -
emptyDirvolumes שמגובים בדיסק, אלא אם הצומת משתמש ב-SSD מקומי.
הביצועים של הדיסק משותפים לכל הדיסקים מאותו סוג דיסק בצומת. לדוגמה, אם יש לכם דיסק אתחול pd-standard בנפח 100GB ו-PersistentVolume pd-standard בנפח 100GB עם הרבה פעילות, הביצועים של דיסק האתחול יהיו כמו של דיסק בנפח 200GB. בנוסף, אם יש הרבה פעילות ב-PersistentVolume, זה משפיע גם על הביצועים של דיסק האתחול.
אם אתם נתקלים בהודעות דומות לאלה בצמתים, יכול להיות שמדובר בסימפטומים של ביצועי דיסק נמוכים:
INFO: task dockerd:2314 blocked for more than 300 seconds.
fs: disk usage and inodes count on following dirs took 13.572074343s
PLEG is not healthy: pleg was last seen active 6m46.842473987s ago; threshold is 3m0s
כדי לפתור בעיות כאלה, כדאי לעיין במידע הבא:
- חשוב לעיין בהשוואות בין סוגים של דיסקים לאחסון ולבחור סוג של דיסק אחסון מתמיד (persistent disk) שמתאים לצרכים שלכם.
- הבעיה הזו מתרחשת לעיתים קרובות בצמתים שמשתמשים בדיסקים קשיחים רגילים עם גודל של פחות מ-200 GB. כדאי להגדיל את גודל הדיסקים או לעבור ל-SSD, במיוחד עבור אשכולות שמשמשים בייצור.
- מומלץ להפעיל SSD מקומי לאחסון זמני במאגרי הצמתים.
האפשרות הזו יעילה במיוחד אם יש לכם מאגרי תגים שמשתמשים לעיתים קרובות בנפחי
emptyDir.
התקנת נפח אחסון מפסיקה להגיב בגלל ההגדרה fsGroup
בעיה אחת שיכולה לגרום לכשל בהרכבת PersistentVolume היא Pod שהוגדר עם ההגדרה fsGroup. בדרך כלל, המערכת מנסה שוב להפעיל את הכוננים באופן אוטומטי, והשגיאה נפתרת מעצמה. עם זאת, אם ב-PersistentVolume יש מספר גדול של קבצים, kubelet ינסה לשנות את הבעלות על כל קובץ במערכת הקבצים, מה שיכול להגדיל את זמן האחזור של טעינת אמצעי האחסון.
Unable to attach or mount volumes for pod; skipping pod ... timed out waiting for the condition
כדי לוודא ששגיאת הטעינה שנכשלה נובעת מההגדרה fsGroup, אפשר לבדוק את היומנים של ה-Pod.
אם הבעיה קשורה להגדרה fsGroup, תראה את רשומת היומן הבאה:
Setting volume ownership for /var/lib/kubelet/pods/POD_UUID and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699
אם PersistentVolume לא מותקן תוך כמה דקות, נסו את השלבים הבאים כדי לפתור את הבעיה:
- מצמצמים את מספר הקבצים בכרך.
- להפסיק להשתמש בהגדרה
[fsGroup]. - שינוי האפליקציה
fsGroupChangePolicyלOnRootMismatch.
פעולות איטיות בדיסק גורמות לכשלים ביצירת Pod
מידע נוסף זמין בבעיה מספר 4604 ב-containerd.
גרסאות הצמתים של GKE שהושפעו: 1.18, 1.19, 1.20.0 עד 1.20.15-gke.2100, 1.21.0 עד 1.21.9-gke.2000, 1.21.10 עד 1.21.10-gke.100, 1.22.0 עד 1.22.6-gke.2000, 1.22.7 עד 1.22.7-gke.100, 1.23.0 עד 1.23.3-gke.700, 1.23.4 עד 1.23.4-gke.100
דוגמאות לשגיאות שמופיעות ביומנים של k8s_node container-runtime:
Error: failed to reserve container name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0": name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0" is reserved for "1234567812345678123456781234567812345678123456781234567812345678"
צמצום הפגיעה
- אם יש כשלים ב-Pods, כדאי להשתמש ב-
restartPolicy:Alwaysאו ב-restartPolicy:OnFailureב-PodSpec. - להגדיל את ה-IOPS של דיסק האתחול (לדוגמה, לשדרג את סוג הדיסק או להגדיל את גודל הדיסק).
תיקון
הבעיה הזו תוקנה ב-containerd 1.6.0 ואילך. גרסאות GKE עם התיקון הזה הן 1.20.15-gke.2100 ואילך, 1.21.9-gke.2000 ואילך, 1.21.10-gke.100 ואילך, 1.22.6-gke.2000 ואילך, 1.22.7-gke.100 ואילך, 1.23.3-gke.1700 ואילך ו-1.23.4-gke.100 ואילך.
שינויים בהרחבת נפח האחסון לא משתקפים במערכת הקבצים של מאגר התגים
כשמבצעים הרחבה של נפח, חשוב תמיד לעדכן את PersistentVolumeClaim. שינוי ישיר של PersistentVolume עלול לגרום לכך שהרחבת נפח האחסון לא תתבצע. המצב הזה יכול להוביל לאחד מהתרחישים הבאים:
אם משנים ישירות אובייקט PersistentVolume, הערכים של PersistentVolume ושל PersistentVolumeClaim מתעדכנים לערך חדש, אבל גודל מערכת הקבצים לא משתקף בקונטיינר והוא עדיין משתמש בגודל הווליום הישן.
אם משנים ישירות אובייקט PersistentVolume, ואחרי זה מעדכנים את PersistentVolumeClaim כך שהשדה
status.capacityמתעדכן לגודל חדש, יכול להיות שיהיו שינויים ב-PersistentVolume אבל לא ב-PersistentVolumeClaim או במערכת הקבצים של הקונטיינר.
כדי לפתור את הבעיה, מבצעים את השלבים הבאים:
- האובייקט PersistentVolume ששונה יישאר כמו שהוא.
- עורכים את האובייקט PersistentVolumeClaim ומגדירים את
spec.resources.requests.storageלערך גבוה יותר מזה שהוגדר ב-PersistentVolume. - מוודאים שהגודל של PersistentVolume השתנה לערך החדש.
אחרי השינויים האלה, ה-kubelet אמור לשנות את הגודל של PersistentVolume, PersistentVolumeClaim ומערכת הקבצים של הקונטיינר באופן אוטומטי.
בודקים אם השינויים משתקפים ב-Pod.
kubectl exec POD_NAME -- /bin/bash -c "df -h"
מחליפים את POD_NAME ב-Pod שמצורף ל-PersistentVolumeClaim.
סוג המכונה שנבחר צריך לכלול SSD מקומי
יכול להיות שתיתקלו בשגיאה הבאה כשאתם יוצרים אשכול או מאגר צמתים שמשתמשים ב-SSD מקומי:
The selected machine type (c3-standard-22-lssd) has a fixed number of local SSD(s): 4. The EphemeralStorageLocalSsdConfig's count field should be left unset or set to 4, but was set to 1.
בהודעת השגיאה, יכול להיות שיופיע LocalNvmeSsdBlockConfig במקום EphemeralStorageLocalSsdConfig, בהתאם למה שציינתם.
השגיאה הזו מתרחשת כשמספר דיסקי ה-SSD המקומיים שצוין לא תואם למספר דיסקי ה-SSD המקומיים שכלולים בסוג המכונה.
כדי לפתור את הבעיה, צריך לציין מספר של דיסקים מסוג SSD מקומי שתואם לסוג המכונה הרצוי.
בסדרות מכונות מהדור השלישי, צריך להשמיט את הדגל count של ה-SSD המקומי, והערך הנכון יוגדר באופן אוטומטי.
מאגרי אחסון של Hyperdisk: יצירת אשכולות או מאגרי צמתים נכשלת
יכול להיות שתיתקלו בשגיאה ZONE_RESOURCE_POOL_EXHAUSTED או בשגיאות דומות במשאבי Compute Engine כשאתם מנסים להקצות דיסקים מסוג Hyperdisk Balanced כדיסק האתחול של הצומת או כדיסקים שמצורפים למאגר אחסון של Hyperdisk.
זה קורה כשמנסים ליצור אשכול GKE או מאגר צמתים באזור שבו יש מעט משאבים, למשל:
- יכול להיות שאין מספיק דיסקים מסוג Hyperdisk Balanced באזור.
- יכול להיות שלאזור אין מספיק קיבולת כדי ליצור את הצמתים של סוג המכונה שציינתם, כמו
c3-standard-4.
כדי לפתור את הבעיה:
- בוחרים אזור חדש באותו אזור עם מספיק קיבולת לסוג המכונה שבחרתם, ועם מאגרי אחסון מאוזנים של Hyperdisk.
- מוחקים את מאגר האחסון הקיים ויוצרים אותו מחדש באזור החדש. הסיבה לכך היא שמאגרי אחסון הם משאבים של תחום מוגדר.
- יוצרים את האשכול או את מאגר הצמתים באזור החדש.
זוהה לחץ גבוה על אחסון הצמתים
אם אתם רואים אירועים או תנאים של צומת שקשורים ל-StoragePressureRootFileSystem עם הסיבה StoragePressureDetected, זה מצביע על כך שמערכת קבצי השורש של הצומת או נקודת טעינה קריטית של אחסון חווים שימוש גבוה בדיסק, ומתקרבים לקיבולת שלהם.
כשמתארים צומת באמצעות הפקודה kubectl describe node NODE_NAME, יכול להיות שיוצג אירוע דומה לזה:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Warning StoragePressureDetected 46m device-capacity-monitor Node condition StoragePressureRootFileSystem is now: True, reason: StoragePressureDetected, message: "Disk /dev/nvme0n1 usage 89% exceeds threshold 85%"
הסיבה:
הסיבה StoragePressureDetected מציינת שהשימוש בדיסק במערכת הקבצים הבסיסית של הצומת (לרוב mnt/stateful_partition או נקודות טעינה קשורות) חרג מסף מוגדר מראש (לדוגמה, 85%). הסיבות האפשריות לכך:
- עומסי עבודה שכותבים נתונים בכמות מוגזמת לנפחי אחסון מסוג emptyDir שלא מגובים על ידי כונני SSD מקומיים.
- תמונות גדולות של קונטיינרים נמשכות אל הצומת.
- קבצי יומן שמצטברים בצומת.
- תהליכים אחרים שצורכים שטח בדיסק.
שימוש גבוה מתמשך בדיסק עלול לגרום לחוסר יציבות של הצומת, להוצאת Pod ולכשלים באפליקציה.
ניפוי באגים ופתרון בעיות:
זיהוי השימוש בדיסק: משתמשים ב-SSH כדי להתחבר לצומת המושפע ומשתמשים בפקודות כמו df -h כדי לבדוק את השימוש בדיסק בנקודות שונות של טעינת מערכת הקבצים, תוך שימת לב ל-/mnt/stateful_partition ולכל נקודות הטעינה של אחסון זמני.
ניתוח דפוסי האחסון של עומסי העבודה: בדיקת בקשות האחסון ודפוסי השימוש של ה-Pods שפועלים בצומת. לזהות אם עומסי עבודה ספציפיים צורכים כמות לא פרופורציונלית של אחסון זמני.
הגדלת קיבולת האחסון של הצומת: חשוב לדעת שהפתרון העיקרי הוא בדרך כלל לוודא שלצמתים יש קיבולת אחסון מספקת לעומסי העבודה. כמה נקודות שכדאי לחשוב עליהן:
- שימוש בדיסקים גדולים יותר לאתחול: כשיוצרים מאגרי צמתים, בוחרים גודל גדול יותר של דיסק אתחול אם עומסי העבודה דורשים יותר אחסון זמני במערכת קבצים בסיסית.
- שימוש בכונני SSD מקומיים גדולים יותר לאחסון זמני: לעומסי עבודה שדורשים אחסון זמני עם ביצועים גבוהים וזמן אחזור נמוך, צריך להגדיר את מאגרי הצמתים לשימוש בכונני SSD מקומיים. כך אפשר לקבל נפח נפרד וגדול יותר עבור נפחי emptyDir.
- התאמת בקשות או מגבלות של עומסי עבודה: מוודאים שמפרטי ה-Pod כוללים בקשות ומגבלות מתאימות של אחסון זמני, כדי לעזור למתזמן למקם את ה-Pods בצמתים עם מספיק מקום ולמנוע שימוש לא מבוקר בדיסק.
- ניקוי משאבים לא בשימוש: אם קבצים מיותרים, תמונות ישנות של קונטיינרים או יומנים תורמים לשימוש הגבוה בדיסק, כדאי להסיר אותם מהצומת.
כדי לפתור בעיות שקשורות ל-StoragePressureDetected ולעזור להפעיל את הצומת, צריך לטפל בקיבולת האחסון ובשימוש בצומת.
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו להיעזר בקבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אפשר גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה נוספת מהקהילה. - פתיחת באגים או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.