בדף הזה מוסבר איך לזהות בעיות של תחרות על משאבים בסביבת Google Distributed Cloud ולפתור אותן.
סקירה כללית
לפעמים יכול להיות שיהיו התנגשויות על משאבים ב-Google Distributed Cloud, שיגרמו להאטה של הקונטיינרים, לביצועים נמוכים או לסיום הפעולה שלהם. זה יכול לקרות בגלל צריכה גבוהה של מעבד או זיכרון על ידי הקונטיינרים.
איך מתבצע ניהול של משאבי המעבד (CPU) והזיכרון
CPU:
- תזמון של Pod מתבצע לצומת על סמך בקשות ה-CPU שצוינו על ידי הקונטיינרים ב-Pod.
- קונטיינר ב-Pod לא יכול להשתמש ביותר יחידות CPU מהמגבלה שצוינה על ידי הקונטיינר
- השימוש במעבד של הקונטיינר מוגבל על ידי מגבלת המעבד.
- אם השימוש במעבד מוגבל ברמת הצומת, למאגרי התוכן מוקצים באופן אוטומטי מחזורי מעבד באופן יחסי לבקשות.
זיכרון:
- התזמון של Pod לצומת מתבצע על סמך בקשות הזיכרון שצוינו על ידי הקונטיינרים ב-Pod.
- קונטיינר לא יכול להשתמש ביותר זיכרון מהמגבלה שצוינה על ידי הקונטיינר.
- אם לא מצוינת מגבלת זיכרון, יכול להיות שקונטיינר יצרוך את כל הזיכרון שזמין בצומת. לאחר מכן, המערכת עשויה להפעיל את OOM-Killer (הכלי לחיסול תהליכים שצורכים יותר מדי זיכרון) ולסלק את ה-Pods בעדיפות הנמוכה.
למידע נוסף, קראו את המאמרים הבאים:
בעיות
הקונטיינר הופך לאיטי
בעיות של תחרות על משאבי המעבד עלולות לגרום להאטה של הקונטיינרים. אלה כמה מהסיבות האפשריות:
ניצול גבוה של המעבד (CPU) במאגר התגים:
קצב העיבוד של קונטיינר יכול להיות איטי אם הוא לא מקבל מחזורי CPU שפרופורציונליים לבקשות ה-CPU, או אם בקשות ה-CPU הוגדרו לערך נמוך ממה שהקונטיינר צריך. לכן, כדאי לבדוק את היחס בין מגבלת המעבד לבין ניצול המעבד של הקונטיינר.
במסוף Google Cloud > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
avg_over_time({
"__name__"="kubernetes.io/anthos/container/cpu/limit_utilization",
"monitored_resource"="k8s_container",
"cluster_name"="CLUSTER_NAME",
"container_name"="CONTAINER_NAME",
"pod_name"="POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
לאחר מכן, מבצעים אחת מהפעולות הבאות:
- אם היחס הזה גבוה (>=0.8), המשמעות היא שמגבלת השימוש במעבד (CPU) של הקונטיינר נמוכה, ו-Kubernetes מגביל את מחזורי ה-CPU של הקונטיינר כדי לשמור על השימוש במעבד במסגרת המגבלה. כדי לפתור את הבעיה, צריך להגדיל את מגבלת השימוש במעבד (CPU) במאגר התגים.
- אם היחס הזה לא גבוה (<0.8), צריך לבדוק אם ניצול המעבד (CPU) בצומת גבוה.
ניצול גבוה של המעבד בצומת
אם היחס בין מגבלת המעבד לניצול שלו לא גבוה עבור אף אחד מהקונטיינרים של ה-Pod, יכול להיות שלצומת אין מספיק מחזורי מעבד להקצאה לקבוצת הקונטיינרים שפועלים בצומת. כדי לבדוק את היחס בין השימוש בפועל במעבד לבין המעבדים שניתנים להקצאה בצומת, פועלים לפי השלבים הבאים:
מקבלים את הצומת של ה-Pod שפועל לאט:
kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wideב-Google Cloud console > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
avg_over_time({ "__name__"="kubernetes.io/anthos/node/cpu/allocatable_utilization", "monitored_resource"="k8s_node", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME" }[${__interval}])אם היחס הזה גבוה (>=0.8), המשמעות היא שלצומת אין מספיק מחזורי מעבד, והיא עמוסה מדי. לכן, צריך לפעול לפי השלבים הבאים כדי לבדוק את השימוש ביחידת העיבוד המרכזית (CPU) בכל שאר ה-Pods בצומת הזה, ולבדוק אם יש מאגר אחר שמשתמש ביותר יחידות עיבוד מרכזיות.
- קבלת כל ה-Pods בצומת:
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME- בודקים את השימוש במעבד בכל קונטיינר:
avg_over_time({ "__name__"="kubernetes.io/anthos/container/cpu/limit_utilization", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "container_name"="CONTAINER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}])אם יש מאגר אחר שמשתמש ב-CPU גבוה בצומת, צריך להגדיל את בקשות ה-CPU ואת המגבלות במאגר שפועל לאט. הפעולה הזו תיצור מחדש את ה-Pod בצומת אחר כדי לקבל את מחזורי ה-CPU הנדרשים.
אם מדובר ב-Pod של המערכת שפועל לאט, צריך לפנות לתמיכה של Google.
CPU oversubscription at the vSphere level
אם צריכת המעבד לא גבוהה בצומת או ב-Pod, והקונטיינר עדיין איטי, יכול להיות שהמכונה הווירטואלית נמצאת בהקצאת יתר ברמת vSphere. לכן, הצומת לא יכול לקבל את מחזורי המעבד הצפויים מהווירטואליזציה הבסיסית.
כדי לבדוק אם יש הקצאת יתר של מכונה וירטואלית, פועלים לפי השלבים האלה. אם מזוהה הרשמה עודפת, נסו את הפעולות הבאות:
- להעביר חלק מהמכונות הווירטואליות למארחים אחרים.
- להעריך את מספר המעבדים הווירטואליים לכל מכונה וירטואלית במארח, ולצמצם אותו.
- הקצאת יותר משאבים למכונות הווירטואליות של האשכול.
- הגדלת הבקשות והמגבלות של ה-CPU בקונטיינר. הפעולה הזו תיצור מחדש את ה-Pod בצומת אחר כדי לקבל את מחזורי ה-CPU הנדרשים.
ה-Pod נסגר בגלל חוסר זיכרון (OOMkilled)
יכול להיות שה-Pods יופסקו בגלל חריגה מזיכרון (OOMKilled) בגלל דליפות זיכרון או הגדרה לא טובה של בקשות זיכרון ומגבלות על הקונטיינרים. אלה כמה מהסיבות האפשריות:
שימוש גבוה בזיכרון במאגר
יכול להיות ש-Pod יופסק בגלל חריגה מזיכרון (OOM) אם קונטיינר כלשהו ב-Pod צורך יותר מדי מהזיכרון שהוקצה לו. לכן, כדאי לבדוק את היחס בין בקשות הזיכרון לבין מגבלות הזיכרון במאגר.
ב-Google Cloud console > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
avg_over_time({
"__name__"="kubernetes.io/anthos/container/memory/limit_utilization",
"monitored_resource"="k8s_container",
"memory_type"="non-evictable",
"cluster_name"="CLUSTER_NAME",
"container_name"="CONTAINER_NAME",
"pod_name"="POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
לאחר מכן, מבצעים אחת מהפעולות הבאות:
- אם היחס הזה גבוה (>= 0.8), צריך להגדיל את מגבלת הזיכרון של הקונטיינר.
- אם היחס הזה לא גבוה (<0.8), צריך לבדוק אם השימוש בזיכרון בצומת גבוה.
שימוש גבוה בזיכרון בצומת
יכול להיות ש-Pod יקבל OOMkilled אם השימוש בזיכרון של כל ה-Pods שפועלים בצומת יעלה על הזיכרון הזמין. לכן, כדאי לבדוק אם התנאי MemoryPressure בצומת הוא True.
מריצים את הפקודה הבאה ובודקים את הקטע
Conditions:kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAMEאם התנאי
MemoryPressureהואTrue, צריך לבדוק את ניצול הזיכרון בצומת:avg_over_time({ "__name__"="kubernetes.io/anthos/node/memory/allocatable_utilization", "monitored_resource"="k8s_node", "memory_type"="non-evictable", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME", }[${__interval}])אם היחס הזה גבוה (>= 0.8), המשמעות היא שלצומת אין מספיק זיכרון להקצאה ל-Pod, יכול להיות בגלל תהליכים מסוימים או בגלל Pods אחרים שצורכים הרבה זיכרון.
ב-Google Cloud console > Monitoring > Metrics explorer, ב-PromQL editor, מריצים את השאילתה הבאה כדי לבדוק את השימוש בזיכרון של הקונטיינרים בצומת:
avg_over_time({ "__name__"="kubernetes.io/anthos/container_memory_usage_bytes", "monitored_resource"="k8s_node", "cluster_name"="CLUSTER_NAME", "node_name"="NODE_NAME", }[${__interval}])אם יש קונטיינר שמשתמש בזיכרון רב, צריך לבדוק את הפעולה של הקונטיינר או להגדיל את בקשת הזיכרון של הקונטיינר, אם צריך.
אם מדובר ב-Pod של מערכת שצורכת הרבה זיכרון, אפשר לפנות אל התמיכה של Google.
בנוסף, אתם יכולים להפעיל את התכונה התאמה אוטומטית לעומס ב-Google Distributed Cloud כדי להגדיל או להקטין באופן אוטומטי את מספר הצמתים בהתאם לדרישות של עומסי העבודה.
איך מפעילים את הכלי לשינוי גודל אוטומטי
בעיות ב-etcd
לפעמים יכול להיות שיהיו כשלים בקונטיינרים באשכולות Anthos ב-VMware בגלל בעיות בשרת etcd, ואולי תראו את הדברים הבאים:
יומני שרת API חוזרים מהסוג הבא:
etcdserver: request timed outוגםetcdserver: leader changedיומני etcd חוזרים מהטופס:
W | wal: sync duration of 2.466870869s, expected less than 1sוגםW | etcdserver: read-only range request * took too long
אלה כמה מהסיבות האפשריות:
ויסות נתונים (throttle) של יחידת עיבוד מרכזית (CPU
יכול להיות שהשרת etcd איטי בגלל הגבלת מהירות המעבד (CPU throttling) ב-Pod של שרת etcd או בצומת שבו שרת etcd פועל. כדי לבדוק אם יש בעיות שקשורות לתחרות על משאבי CPU, אפשר להיעזר בשלבים שמפורטים בקטע המאגר הופך לאיטי.
אם אתם מזהים תחרות על משאבי CPU ב-Pod של שרת ה-etcd או בצומת, מוסיפים מעבדי CPU לצומת של מישור הבקרה של אשכול המשתמשים. משתמשים ב-gkectl update כדי לערוך את השדה cpus בקובץ התצורה של אשכול המשתמשים.
Etcd Pod OOMkilled
יכול להיות ש-Pod של etcd יופסק בגלל חוסר זיכרון (OOM) עקב בעיות של תחרות על משאבים. כדי לבדוק אם יש בעיות של תחרות על הזיכרון ב-Pod של שרת etcd או בצומת שבו שרת etcd פועל, אפשר לעיין בשלבים שבקטע Pod gets OOMkilled (Out of Memory-Killed).
אם אתם מזהים OOMkills עבור ה-Pod של etcd, הגדילו את הזיכרון שזמין לצומת של מישור הבקרה של אשכול המשתמשים. משתמשים ב-gkectl update כדי לערוך את השדה memoryMB בקובץ התצורה של אשכול המשתמשים.
הדיסק איטי
אם אין בעיות בשימוש במעבד או בזיכרון ב-Pod או בצומת של שרת etcd, יכול להיות ש-etcd איטי כי מאגר הנתונים הבסיסי איטי או מוגבל.
כדאי לבדוק את הבעיות הבאות:
כדי לבדוק אם לשרת etcd לוקח יותר מדי זמן לקרוא מהדיסק הבסיסי או לכתוב אליו:
מאחזרים את היומנים של etcd:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_PODכדי לזהות אם ל-etcd לוקח יותר מדי זמן לקרוא מהדיסק, מחפשים את הרשומות בדפוס הבא:
W | etcdserver: read-only range request "key:\"/registry/configmaps/default/clusterapi-vsphere-controller-manager-leader-election\" " with result "range_response_count:1 size:685" took too long (6.893127339s) to executeכדי לזהות אם ל-etcd לוקח יותר מדי זמן לכתוב לדיסק, מחפשים את הרשומות בדפוס הבא:
W | wal: sync duration of 2.466870869s, expected less than 1s
אם אחד מהדפוסים של היומנים שלמעלה או שניהם מופיעים לעיתים קרובות ביומני etcd, זה מצביע על איטיות של הדיסק. לאחר מכן בודקים את הביצועים של מאגר הנתונים והדיסקים.
כדי לבדוק את המדדים של etcd:
מאחזרים את השהיות של סנכרון etcd wal:
ב-Google Cloud console > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
histogram_quantile(0.99, sum by ("le") ( increase({ "__name__"="kubernetes.io/anthos/etcd_disk_wal_fsync_duration_seconds_bucket", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}]) ) )מאחזרים את נתוני ההשהיה של פעולות הכתיבה ב-etcd:
ב-Google Cloud console > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
histogram_quantile(0.99, sum by ("le") ( increase({ "__name__"="kubernetes.io/anthos/etcd_disk_backend_commit_duration_seconds", "monitored_resource"="k8s_container", "cluster_name"="CLUSTER_NAME", "pod_name"="POD_NAME", "namespace_name"="NAMESPACE_NAME" }[${__interval}]) ) )
אם הערך של
p99עבורetcd_disk_wal_fsync_duration_secondsהוא מעל 10ms באופן רציף, ו/או הערך שלp99עבורetcd_disk_backend_commit_duration_secondsהוא מעל 25ms באופן רציף, זה מצביע על איטיות של הדיסק. לאחר מכן בודקים את הביצועים של מאגר הנתונים והדיסקים.
זמני האחזור של קריאה/כתיבה בדיסק של המכונה הווירטואלית
כדי לבדוק את זמן האחזור של קריאה/כתיבה בדיסק הווירטואלי של מכונת ה-VM:
מזהים את הצומת של ה-Pod האיטי של etcd:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owideנכנסים אל vSphere ובוחרים את המכונה הווירטואלית שזוהתה בשלב הקודם: ב-vSphere, עוברים אל Monitor (מעקב) > Performance (ביצועים) > Advanced (מתקדם), ובוחרים באפשרות Virtual Disk (דיסק וירטואלי) בקטע View (תצוגה) כדי לזהות את זמן האחזור של הקריאה והכתיבה בדיסקים הווירטואליים.
אם זמן האחזור של קריאה מהדיסק הווירטואלי או כתיבה לדיסק הווירטואלי גבוה:
- בודקים מכונות וירטואליות אחרות שפועלות במאגר הנתונים כדי לראות אם יש שימוש גבוה בפעולות קלט/פלט לשנייה (IOPS). אם יש מכונה וירטואלית שבה נרשמים שיאים ב-IOPS, צריך לבדוק את הפעולה של המכונה הווירטואלית הזו.
- כדאי להתייעץ עם צוות המעבדה או התשתית כדי לוודא שרוחב הפס של הקריאה והכתיבה לא מוגבל או מצומצם בשום שלב.
- כדאי להתייעץ עם צוות המעבדה או התשתית כדי לזהות בעיות בביצועי הדיסק ובביצועי האחסון, אם יש כאלה.
מידע נוסף זמין במאמר בנושא שיטות מומלצות להרחבת המשאבים.
בעיות בשרת API
אם יש השהיה במיכלים ב-Google Distributed Cloud בזמן התקשורת עם שרת ה-API, או אם הפקודות של Kubectl נכשלות או לוקח להן יותר מדי זמן להגיב, יכול להיות שיש בעיות בשרת ה-API.
אלה כמה מהסיבות האפשריות:
נפח גבוה של בקשות API
יכול להיות ששרת ה-API יגיב לאט אם התדירות והנפח של הבקשות שמועברות אליו גבוהים מדי. יכול להיות שזמן התגובה האיטי יימשך גם אחרי ששרת ה-API יתחיל להגביל את הבקשות. לכן, צריך לבדוק את קצב הבקשות ל-API בשרת ה-API.
ב-Google Cloud console > Monitoring > Metrics explorer, בPromQL editor, מריצים את השאילתה הבאה:
sum by (verb) (
rate({
"__name__"="kubernetes.io/anthos/apiserver_request_total",
"monitored_resource"="k8s_container",
"cluster_name"="CLUSTER_NAME",
"pod_name"="APISERVER_POD_NAME",
"namespace_name"="NAMESPACE_NAME"
}[${__interval}])
)
אם יש עלייה לא צפויה בבקשות ל-API, אפשר להשתמש ברישום ביומן של ביקורת ב-Cloud כדי לזהות את ה-Pod שאולי שולח שאילתות לשרת ה-API בתדירות גבוהה מדי.
- אם מדובר ב-Pod של המערכת, צריך לפנות אל התמיכה של Google.
- אם מדובר ב-Pod של משתמש, צריך לבדוק לעומק כדי להבין אם בקשות ה-API צפויות.
ויסות נתונים (throttle) של יחידת עיבוד מרכזית (CPU
קצב בקשות גבוה בשרת ה-API עלול להוביל להגבלת מהירות המעבד. במקרה כזה, יכול להיות ששרת ה-API יהפוך לאיטי בגלל התחרות על המעבד ב-Pod של שרת ה-API או בצומת.
כדי לבדוק אם יש בעיות של תחרות על משאבי CPU ב-Pod או בצומת, אפשר לעיין בקטע המאגר הופך לאיטי.
API server Pod OOMkilled
יכול להיות ש-Pod של שרת API יושבת בגלל בעיות בתחרות על משאבים. כדי לבדוק אם יש בעיות של תחרות על הזיכרון ב-Pod או בצומת, אפשר לעיין בשלבים שבקטע Pod gets OOMkilled (Out of Memory-Killed).
תגובות איטיות של etcd
שרת ה-API מסתמך על תקשורת עם אשכול etcd כדי להגיב לבקשות קריאה / כתיבה של הלקוחות. אם etcd איטי או לא מגיב, גם שרת ה-API הופך לאיטי.
מאחזרים את היומנים של שרת ה-API כדי לבדוק אם שרת ה-API פועל לאט בגלל בעיות ב-etcd:
kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n APISERVER_NAMESPACE APISERVER_POD_NAME
אם אתם רואים ביומנים הודעות שחוזרות על עצמן, כמו etcdserver: request timedout או etcdserver: leader changed, צריך לבצע את השלבים שמפורטים במאמר בעיות ב-Etcd כדי לפתור בעיות שקשורות לדיסק.
אם האשכול לא מייצא מדדים
הטכניקות שמוצגות קודם במסמך הזה מסתמכות על ייצוא מדדים מהאשכול לפרויקט Google Cloud .
אם האשכול לא מייצא מדדים, אפשר להשתמש בשורת הפקודה כדי לבדוק את התחרות על משאבים. הנה כמה פקודות שאפשר להריץ בתחנת העבודה של האדמין כדי לראות מדדים.
כדי לראות את המדדים של צומת מסוים:
kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
/apis/metrics.k8s.io/v1beta1/nodes/NODE_NAME | jq
מחליפים את מה שכתוב בשדות הבאים:
- CLUSTER_KUBECONFIG: הנתיב לקובץ kubeconfig של האשכול
- NODE_NAME: שם הצומת
כדי לראות את המדדים של Pod:
kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
/apis/metrics.k8s.io/v1beta1/namespaces/NAMESPACE/pods/POD_NAME | jq
מחליפים את מה שכתוב בשדות הבאים:
- NAMESPACE: מרחב השמות של ה-Pod
- POD_NAME: השם של ה-Pod
הצגת מדדים לכל הצמתים:
kubectl --kubeconfig CLUSTER_KUBECONFIG top node
הצגת מדדים של כל ה-Pods במרחב שמות:
kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --namespace NAMESPACE
כדי לראות את המדדים של המאגרים בכל ה-Pods במרחב שמות:
kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --containers --namespace NAMESPACE
מידע נוסף זמין במאמרים בנושא kubectl top pod ו-kubectl top node.
אפשר גם להריץ את הפקודה top מתוך מאגר שפועל בצומת.
יש שתי דרכים להריץ פקודה בתוך קונטיינר:
בתחנת העבודה של האדמין, מריצים את הפקודה kubectl exec כדי לקבל מעטפת בקונטיינר. מריצים את הפקודה במעטפת.
יצירת חיבור SSH לצומת. אחר כך משתמשים בפקודה docker exec כדי לקבל מעטפת לתוך הקונטיינר. מריצים את הפקודה במעטפת.
המאמרים הבאים
לקבלת עזרה נוספת, אפשר לפנות אל Cloud Customer Care.
אפשר גם לעיין במאמר קבלת תמיכה לקבלת מידע נוסף על מקורות מידע לתמיכה, כולל:
- דרישות לפתיחת בקשת תמיכה.
- כלים שיעזרו לכם לפתור בעיות, כמו יומנים ומדדים.
- רכיבים, גרסאות ותכונות נתמכים של Google Distributed Cloud ל-VMware (תוכנה בלבד).