אם התאמה אוטומטית אופקית של Pod לא פועלת כמו שצריך ב-Google Kubernetes Engine (GKE), יכול להיות שעומסי העבודה לא יותאמו כמו שצריך. הבעיה הזו יכולה למנוע מאפליקציות לטפל בעומס, מה שעלול לגרום לבעיות בביצועים או להפסקות בשירות. יכול להיות שתראו שה-Pods לא גדלים למרות שיש עומס גבוה על המעבד, ערכי המדדים
מוצגים כ-<unknown> בסטטוס של HorizontalPodAutoscaler, או שלא מתבצעות פעולות של שינוי קנה מידה.
במאמר הזה מוסבר איך לאבחן ולפתור בעיות נפוצות שקשורות לשינוי אוטומטי של מספר העותקים של Pod אופקי, החל מבעיות בהגדרות הראשוניות של אובייקטים מסוג HorizontalPodAutoscaler ועד לכשלים מורכבים יותר בצינור של מדדי הביצועים. אם תפעלו לפי השלבים האלה לפתרון בעיות, תוכלו לוודא שהאפליקציות שלכם יתבססו על הביקוש כדי להגדיל את הקיבולת שלהן בצורה יעילה ואמינה, ושהן ישתמשו ביעילות במשאב HorizontalPodAutoscaler.
המידע הזה חשוב למפתחי אפליקציות שמגדירים אובייקטים של HorizontalPodAutoscaler וצריכים לוודא שהאפליקציות שלהם משתנות בהתאם לעומס בצורה נכונה. הוא גם עוזר לאדמינים ולמפעילים של הפלטפורמה לפתור בעיות בצינור המדדים או בהגדרת האשכול שמשפיעות על כל עומסי העבודה שמוגדרים בהם שינוי גודל אוטומטי. מידע נוסף על התפקידים הנפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם ב Google Cloud תוכן זמין במאמר תפקידי משתמשים נפוצים ומשימות ב-GKE.
לפני שמתחילים
- חשוב להשתמש באובייקטים של HorizontalPodAutoscaler עם עומסי עבודה שניתנים להרחבה, כמו Deployments ו-StatefulSets. אי אפשר להשתמש בהרחבה אוטומטית אופקית של Pod עם עומסי עבודה שלא ניתן להרחיב, למשל DaemonSets.
-
כדי לקבל את ההרשאות שדרושות לפתרון בעיות בהתאמה אופקית של קבוצות Pod לעומס ב-GKE, כולל בדיקה של אובייקטים מסוג HorizontalPodAutoscaler וצפייה ביומני האשכול, אתם צריכים לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:
-
בדיקת משאבי GKE:
GKE Viewer (
roles/container.viewer) -
צפייה ביומני אשכול:
מציג היומנים (
roles/logging.viewer)
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
-
בדיקת משאבי GKE:
GKE 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 .
-
אבחון בעיות ב-HorizontalPodAutoscaler
כדי לאבחן בעיות ב-HorizontalPodAutoscaler, בודקים את הסטטוס וההגדרה באמצעות פקודות kubectl או במסוף Google Cloud .
תיאור של HorizontalPodAutoscaler
כדי לראות את החישובים בזמן אמת ואת ההחלטות האחרונות לגבי שינוי הגודל, משתמשים בפקודה kubectl describe hpa:
kubectl describe hpa HPA_NAME -n NAMESPACE_NAME
מחליפים את מה שכתוב בשדות הבאים:
-
HPA_NAME: השם של אובייקט HorizontalPodAutoscaler. -
NAMESPACE_NAME: מרחב השמות של אובייקט HorizontalPodAutoscaler.
הפלט אמור להיראות כך:
Name: php-apache-hpa
Namespace: default
Reference: Deployment/php-apache
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): 1% (1m) / 50%
Min replicas: 1
Max replicas: 10
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricFound the HorizontalPodAutoscaler was able to successfully calculate a replica count
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulRescale 39m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization...
Normal SuccessfulRescale 26m horizontal-pod-autoscaler New size: 1; reason: cpu resource utilization...
בפלט, שלושת הקטעים הבאים עוזרים לאבחן את הבעיה:
-
Metrics: מוצגים ערכי המדדים הנוכחיים בהשוואה ליעדים שלהם. ערך המדד<unknown>מציין שה-HorizontalPodAutoscaler לא אחזר את המדד או שצינור המדדים שבור. -
Conditions: מראה אם האובייקט HorizontalPodAutoscaler יכול לאחזר מדדים (AbleToScale) ולבצע חישובי שינוי גודל (ScalingActive). סטטוסFalseבכל אחד מהתנאים האלה מציין כשל. -
Events: יומנים של פעולות קנה מידה, אזהרות ושגיאות מהזמן האחרון מהבקר HorizontalPodAutoscaler. לרוב, זה המקום הראשון שבו אפשר למצוא הודעות שגיאה ספציפיות או סיבות לשגיאה, כמוFailedGetScaleאוFailedGetResourceMetric.
בדיקת המניפסט של HorizontalPodAutoscaler
קובץ המניפסט של YAML של אובייקט HorizontalPodAutoscaler מאפשר לכם לראות מידע על ההגדרה שלו ועל המצב הנוכחי שלו.
כדי לראות את קובץ ה-YAML של המניפסט, בוחרים באחת מהאפשרויות הבאות:
המסוף
נכנסים לדף Object Browser במסוף Google Cloud .
ברשימה Object Kinds, מסמנים את התיבה HorizontalPodAutoscaler ולוחצים על OK.
עוברים לקבוצת ה-API autoscaling (שינוי גודל אוטומטי), ואז לוחצים על החץ להרחבה של HorizontalPodAutoscaler (שינוי גודל אוטומטי של Pod אופקי).
לוחצים על השם של אובייקט HorizontalPodAutoscaler שרוצים לבדוק.
בודקים את הקטע YAML שבו מוצגת ההגדרה המלאה של אובייקט HorizontalPodAutoscaler.
kubectl
מריצים את הפקודה הבאה:
kubectl get hpa HPA_NAME -n NAMESPACE_NAME -o yaml
מחליפים את מה שכתוב בשדות הבאים:
-
HPA_NAME: השם של אובייקט HorizontalPodAutoscaler. -
NAMESPACE_NAME: מרחב השמות של אובייקט HorizontalPodAutoscaler.
אחרי שמאחזרים את המניפסט, מחפשים את הקטעים החשובים הבאים:
spec(ההגדרה שלכם):-
scaleTargetRef: עומס העבודה (למשל Deployment) שהוגדר עבור HorizontalPodAutoscaler לצורך שינוי גודל. -
minReplicasו-maxReplicas: הגדרות המינימום והמקסימום של העותק. -
metrics: המדדים שהוגדרו לצורך שינוי גודל (לדוגמה, ניצול CPU או מדדים מותאמים אישית).
-
-
status(המצב הפעיל של HorizontalPodAutoscaler):-
currentMetrics: הערכים האחרונים של המדדים שנצפו על ידי HorizontalPodAutoscaler. -
currentReplicasו-desiredReplicas: המספר הנוכחי של ה-Pods והמספר שאליו רוצה HorizontalPodAutoscaler לבצע שינוי גודל. -
conditions: מציג את תקינות ה-HorizontalPodAutoscaler:-
AbleToScale: מציין אם האובייקט HorizontalPodAutoscaler יכול למצוא את היעד והמדדים שלו. -
ScalingActive: מראה אם ל-HorizontalPodAutoscaler מותר לחשב ולבצע שינוי קנה מידה. -
ScalingLimited: מציין אם HorizontalPodAutoscaler רוצה לשנות את קנה המידה אבל מוגבל על ידי ההגדרות שלminReplicasאוmaxReplicas.
-
-
צפייה ביומני האירועים
כדי לקבל תובנות מעמיקות יותר לגבי אובייקט HorizontalPodAutoscaler, אפשר להשתמש בסוגי היומנים הבאים:
הצגת אירועים של HorizontalPodAutoscaler ב-Cloud Logging: אפשר להשתמש במסנן יומן כדי למצוא את כל האירועים של HorizontalPodAutoscaler באשכול מסוים. לדוגמה:
נכנסים לדף Logs Explorer במסוף Google Cloud .
בחלונית השאילתה, מזינים את השאילתה הבאה:
resource.type="k8s_cluster" resource.labels.cluster_name="CLUSTER_NAME" resource.labels.location="LOCATION" logName="projects/PROJECT_ID/logs/events" jsonPayload.involvedObject.kind="HorizontalPodAutoscaler"מחליפים את מה שכתוב בשדות הבאים:
-
CLUSTER_NAME: השם של האשכול שאליו שייך HorizontalPodAutoscaler. -
LOCATION: האזור או התחום של Compute Engine (לדוגמה,us-central1אוus-central1-a) של האשכול. PROJECT_ID: מזהה הפרויקט.
-
לוחצים על Run query (הפעלת שאילתה) ובודקים את הפלט.
הצגת אירועים של התאמה אופקית של קבוצות Pod לעומס: היומנים האלה מספקים יומנים מובנים וקריאים לאנשים שמסבירים איך HorizontalPodAutoscaler מחשב המלצה, ומציעים תובנות מפורטות לגבי תהליך קבלת ההחלטות שלו.
פתרון בעיות בהגדרת HorizontalPodAutoscaler
בקטעים הבאים מוסבר על טעויות בהגדרות במניפסט של HorizontalPodAutoscaler, כמו שדות עם הקלדה שגויה, יעדי מדדים לא חוקיים או הגדרות סותרות.
עומס העבודה של היעד לא נמצא
תסמינים
בקטע Events יש תנאי של FailedGetScale עם הודעה שדומה לזו:
the HorizontalPodAutoscaler controller was unable to get the target's current scale: WORKLOAD_TYPE.apps "TARGET_WORKLOAD" not found
הפלט הזה כולל את הערכים הבאים:
-
WORKLOAD_TYPE: סוג עומס העבודה, למשלDeploymentאוStatefulSet. -
TARGET_WORKLOAD: שם עומס העבודה.
מטרה
הבקר HorizontalPodAutoscaler לא מצליח למצוא את עומס העבודה (כמו Deployment או StatefulSet) שהוא מוגדר לנהל. הבעיה הזו מתרחשת בגלל הגדרה שגויה בשדה scaleTargetRef במניפסט של HorizontalPodAutoscaler. יכול להיות שהמשאב שצוין לא קיים, שהוא נמחק או שיש בו שגיאת איות.
רזולוציה
אפשר לנסות את הפתרונות הבאים:
- בודקים את השדה
scaleTargetRefשל המניפסט HorizontalPodAutoscaler: מוודאים שהערכים שלname,kindו-apiVersionבשדהscaleTargetRefזהים בדיוק למטא-נתונים התואמים של עומס העבודה של היעד. אם שם עומס העבודה שגוי, צריך לעדכן את השדהscaleTargetRefשל HorizontalPodAutoscaler כך שיצביע על השם הנכון. - מוודאים שעומס העבודה קיים: בודקים שעומס העבודה של היעד קיים באותו מרחב שמות כמו HorizontalPodAutoscaler. אפשר לבדוק את זה באמצעות פקודה כמו
kubectl get deployment DEPLOYMENT_NAME. אם מחקתם את עומס העבודה בכוונה, מחקו את אובייקט HorizontalPodAutoscaler המתאים כדי לנקות את האשכול. אם צריך ליצור מחדש את עומס העבודה, ה-HorizontalPodAutoscaler מוצא אותו באופן אוטומטי אחרי שהוא זמין, והשגיאה נפתרת. - מוודאים ש-HorizontalPodAutoscaler ועומס העבודה נמצאים באותו מרחב שמות: HorizontalPodAutoscaler ועומס העבודה של היעד שלו צריכים להיות באותו מרחב שמות. אם שוכחים לציין מרחב שמות כשיוצרים אובייקט באמצעות פקודות
kubectl, Kubernetes ממקם את האובייקט במרחב השמותdefault. התנהגות כזו עלולה לגרום לחוסר התאמה אם ה-HorizontalPodAutoscaler נמצא במרחב השמותdefaultועומס העבודה נמצא במרחב שמות אחר, או להיפך. בודקים את מרחב השמות של שני האובייקטים ומוודאים שהם זהים.
אחרי שהכלי HorizontalPodAutoscaler מאתר בהצלחה את היעד שלו, התנאי AbleToScale הופך ל-True, וההודעה משתנה ל:
the HorizontalPodAutoscaler controller was able to get the target's current scale.
מדדים לא חוקיים
תסמינים
אם לא ניתן לחשב את העותקים הנדרשים של HorizontalPodAutoscaler בגלל בעיה בהגדרות, בקטע Events שלו מוצגת סיבה FailedComputeMetricsReplicas עם הודעה שדומה להודעה הבאה:
invalid metrics (1 invalid out of 1)
מטרה
בדרך כלל, השגיאה הזו מצביעה על חוסר התאמה בין המדד type לבין target שהגדרתם במניפסט של HorizontalPodAutoscaler. לדוגמה, יכול להיות שציינתם type של Utilization, אבל סיפקתם ערך יעד של averageValue במקום averageUtilization.
רזולוציה
מתקנים את המניפסט של HorizontalPodAutoscaler כך שהערך של השדה target יתאים למדד type:
- אם הערך של
typeהואUtilization, הערך בשדהtargetצריך להיותaverageUtilization. - אם הערך של
typeהואAverageValue, הערך בשדהtargetצריך להיותaverageValue.
אסור להשתמש בתווית המדד
תסמינים
השגיאה הבאה מופיעה:
unable to fetch metrics from external metrics API: googleapi: Error 400: Metric label: 'LABEL_NAME' is not allowed
בפלט הזה, LABEL_NAME הוא השם של התווית השגויה.
מטרה
במניפסט של HorizontalPodAutoscaler מצוין מפתח תווית לא תקין בקטע metric.selector.matchLabels, ו-Cloud Monitoring לא מזהה את המפתח הזה ולא מאפשר להשתמש בו למדד.
רזולוציה
כדי לפתור את הבעיה:
- מזהים את שם התווית האסור מתוך הודעת השגיאה.
- מסירים או מתקנים את מפתח התווית הזה בקטע
metric.selector.matchLabelsשל קובץ המניפסט HorizontalPodAutoscaler. - כדי למצוא מפתח תווית תקין שאפשר לסנן באמצעותו, אפשר לעיין במסמכי Cloud Monitoring בנוגע למדד הזה.
כמה רכיבי HorizontalPodAutoscaler מטרגטים את אותה עומס עבודה
תסמינים
אין ערך ספציפי של Condition או Reason בסטטוס של HorizontalPodAutoscaler שמציין ישירות את הקונפליקט הזה. במקום זאת, יכול להיות שתבחינו בתסמינים הבאים:
- מספר העותקים של עומס העבודה יכול להשתנות באופן בלתי צפוי.
- יכול להיות שהחלטות לגבי שינוי גודל לא יתאימו למדדים שמוגדרים באף HorizontalPodAutoscaler יחיד.
- כשמציגים אירועים, יכול להיות שיוצגו אירועים מתחלפים או סותרים
SuccessfulRescaleמאובייקטים שונים של HorizontalPodAutoscaler.
מטרה
הבעיה הזו מתרחשת כי יותר מאובייקט אחד של HorizontalPodAutoscaler באותו מרחב שמות מציין את אותו עומס עבודה בדיוק בשדה spec.scaleTargetRef. כל HorizontalPodAutoscaler מחשב באופן עצמאי את מספר הרפליקות ומנסה לשנות את קנה המידה של עומס העבודה על סמך קבוצת המדדים והיעדים שלו. מערכת Kubernetes לא חוסמת את ההגדרה הזו, אבל היא גורמת לשינויים לא צפויים בהתאמת הגודל כי רכיבי ה-HorizontalPodAutoscalers מתחרים זה בזה.
רזולוציה
כדי למנוע התנגשויות, צריך להגדיר את כל מדדי ההרחבה באובייקט HorizontalPodAutoscaler יחיד. כל HorizontalPodAutoscaler מחשב את הצורך בהרחבה מהשדה spec.metrics שלו, ולכן מיזוג שלהם מאפשר לאובייקט HorizontalPodAutoscaler שנבחר להתחשב בכל הגורמים, כמו CPU ובקשות לשנייה, ביחד:
כדי לזהות אילו אובייקטים של HorizontalPodAutoscaler מכוונים לאותו עומס עבודה, צריך לקבל את מניפסט ה-YAML של כל אובייקט HorizontalPodAutoscaler. חשוב לשים לב לשדה
spec.scaleTargetRefבתוצאה.kubectl get hpa -n NAMESPACE_NAME -o yamlמחליפים את
NAMESPACE_NAMEבמרחב השמות של אובייקט HorizontalPodAutoscaler.מחפשים מקרים שבהם למשאבי HorizontalPodAutoscaler שונים יש את אותם ערכים במאפיינים
apiVersion,kindו-nameבשדהscaleTargetRefשלהם.איחוד מדדים באובייקט HorizontalPodAutoscaler יחיד:
- בוחרים אובייקט HorizontalPodAutoscaler אחד לשמירה. זהו ה-HorizontalPodAutoscaler שתשנו.
- בודקים את הקטע
spec.metricsבמניפסט של כל אחד מאובייקטי HorizontalPodAutoscaler האחרים שמטרגטים את אותה עומס עבודה. - מעתיקים את הגדרות המדדים שרוצים לשמור מהקטעים
spec.metricsשל אובייקטים כפולים של HorizontalPodAutoscaler. - מדביקים את הגדרות המדדים שהועתקו למערך
spec.metricsשל HorizontalPodAutoscaler שהחלטתם לשמור.
מחילים את השינויים:
kubectl apply -f MANIFEST_NAMEמחליפים את
MANIFEST_NAMEבשם של מניפסט HorizontalPodAutoscaler שהחלטתם לשמור.מוחקים את האובייקטים האחרים של HorizontalPodAutoscaler שטרגטו את אותו עומס עבודה:
kubectl delete hpa DUPLICATE_MANIFEST_NAME -n NAMESPACE_NAMEמחליפים את
DUPLICATE_MANIFEST_NAMEבשם של אובייקט HorizontalPodAutoscaler מיותר שרוצים למחוק.
פתרון בעיות שקשורות לעומסי עבודה ולשגיאות בשירות
בקטעים הבאים מוסבר על שגיאות שנגרמות בגלל עומס העבודה של היעד או השירותים המשויכים אליו, ולא בגלל אובייקט HorizontalPodAutoscaler עצמו.
חסרות בקשות למשאבים לחישוב של שינוי הגודל
תסמינים
התנאי ScalingActive הוא False עם Reason של FailedGetResourceMetric. בדרך כלל מוצגת גם הודעה שדומה להודעה הבאה:
the HorizontalPodAutoscaler was unable to compute the replica count
מטרה
ה-HorizontalPodAutoscaler צריך לחשב את ניצול המשאבים כאחוז כדי לשנות את קנה המידה של עומס העבודה, אבל הוא לא יכול לבצע את החישוב הזה כי חסרה הגדרה של resources.requests למשאב המתאים (cpu או memory) לפחות במאגר אחד במפרט ה-Pod.
רזולוציה
כדי לפתור את הבעיה, מעדכנים את מניפסט ה-Pod ב-Deployment, ב-StatefulSet או בבקר אחר כדי לכלול שדה resources.requests עבור המשאב (cpu או memory) ש-HorizontalPodAutoscaler מנסה לשנות את קנה המידה שלו עבור כל הקונטיינרים ב-Pod. לדוגמה:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
# Multiple lines are omitted here
spec:
containers:
- name: example-container
resources:
requests:
cpu: "100m"
memory: "128Mi"
אי אפשר לאחזר מדדים של רצף מודעות
תסמינים
מופיעה הודעה קבועה שדומה להודעה הבאה:
unable to fetch pod metrics for pod
זה נורמלי לראות את ההודעה הזו באופן זמני כששרת המדדים מופעל.
מטרה
כדי לשנות את גודל הקבוצה בהתאם לאחוז ניצול המשאבים (למשל cpu או memory), צריך להגדיר את השדה resources.requests עבור כל משאב ספציפי בכל קונטיינר ב-Pods שמטרגטים על ידי האובייקט HorizontalPodAutoscaler.
אחרת, ל-HorizontalPodAutoscaler לא תהיה אפשרות לבצע את החישובים שהוא צריך, והוא לא יבצע פעולה שקשורה למדד הזה.
רזולוציה
אם הודעות השגיאה האלה ממשיכות להופיע ואתם מבחינים שה-Pods לא משנים את הגודל שלהם בהתאם לעומס העבודה, צריך לוודא שציינתם בקשות למשאבים עבור כל מאגר בעומס העבודה.
מספר שירותים בוחרים את אותו יעד
תסמינים
השגיאה הבאה מופיעה:
multiple services selecting the same target of HPA_NAME: SERVICE_NAME
הפלט הזה כולל את הערכים הבאים:
-
HPA_NAME: השם של HorizontalPodAutoscaler. -
SERVICE_NAME: השם של שירות.
מטרה
הוגדרה התאמה אוטומטית לעומס שמבוססת על תנועה, אבל יותר משירות Kubernetes אחד מכוון לשדה scaleTargetRef של HorizontalPodAutoscaler. שינוי גודל אוטומטי על סמך תעבורה תומך רק ביחס של אחד לאחד בין השירות לבין עומס העבודה שגודלו משתנה אוטומטית.
רזולוציה
כדי לפתור את הבעיה, מוודאים שרק בורר תוויות של שירות אחד תואם ל-Pods של עומס העבודה:
מאתרים את תוויות ה-Pod של עומס העבודה:
kubectl get deployment HPA_TARGET_DEPLOYMENT \ -n NAMESPACE \ -o jsonpath='{.spec.template.metadata.labels}'מחליפים את מה שכתוב בשדות הבאים:
-
HPA_TARGET_DEPLOYMENT: השם של הפריסה שה-HorizontalPodAutoscaler מכוון אליה. -
NAMESPACE: מרחב השמות של הפריסה.
הפלט אמור להיראות כך:
{"app":"my-app", "env":"prod"}-
כדי למצוא את כל השירותים שתואמים לתוויות האלה, בודקים את השדה
spec.selectorשל כל השירותים במרחב השמות.kubectl get services -n NAMESPACE -o yamlמזהים כל שירות שהסלקטור שלו תואם לתוויות מהשלב הקודם. לדוגמה, גם
{"app": "my-app"}וגם{"app": "my-app", "env": "prod"}תואמים לתוויות של ה-Pod בדוגמה.כדי לפתור את הבעיה, בוחרים באחת מהאפשרויות הבאות:
- כדי להפוך את הסלקטור של השירות המיועד לייחודי, מוסיפים תווית חדשה וייחודית לשדה
spec.template.metadata.labelsשל הפריסה. לאחר מכן, מעדכנים את השדהspec.selectorשל השירות הרצוי כדי לכלול את התווית החדשה הזו. - משנים את השדה
spec.selectorשל כל שאר השירותים שמתנגשים כדי שהם יהיו מגבילים יותר ולא יתאימו יותר ל-Pods של עומס העבודה.
- כדי להפוך את הסלקטור של השירות המיועד לייחודי, מוסיפים תווית חדשה וייחודית לשדה
מחילים את השינויים:
kubectl apply -f MANIFEST_NAMEמחליפים את
MANIFEST_NAMEבשם של קובץ ה-YAML שמכיל את המניפסט המעודכן של השירות או הפריסה.
פתרון בעיות שקשורות ל-Metrics API ולזמינות הנתונים
בקטעים הבאים מוסבר איך לפתור שגיאות שמתרחשות כש-HorizontalPodAutoscaler מנסה לתקשר עם API של מדדים או לשלוח שאילתה ל-backend של מדדים.
פתרון בעיות שקשורות למדדים מותאמים אישית ולמדדים חיצוניים
אם ה-HorizontalPodAutoscaler מסתמך על מדדים ממקורות אחרים ולא על מדדי ברירת המחדל של CPU או זיכרון, יכולות להתרחש בעיות בצינור של המדדים המותאמים אישית או החיצוניים. הצינור הזה מורכב מהבקר HorizontalPodAutoscaler, משרת ה-API של מדדי Kubernetes, ממתאם המדדים וממקור המדדים (לדוגמה, Cloud Monitoring או Prometheus), כמו שמוצג בתרשים הבא:
תסמינים
התסמינים הנפוצים ביותר לבעיה בצינור העברת הנתונים של המדדים הם:
- ערך המדד מוצג כ-
<unknown>. - באירועים של HorizontalPodAutoscaler מוצגות שגיאות כמו
FailedGetExternalMetricאוFailedGetCustomMetric.
מטרה
קיימת בעיה בצינור של מדדים מותאמים אישית או חיצוניים.
רזולוציה
כדי לנפות באגים בצינור:
בודקים אם מתאם המדדים רשום וזמין: מתאם המדדים צריך להירשם בשרת ה-API הראשי של Kubernetes כדי להציג מדדים. הפעולה הזו היא הדרך הכי ישירה לבדוק אם המתאם פועל ואם שרת ה-API יכול להגיע אליו:
kubectl get apiservice | grep -E 'NAME|metrics.k8s.io'בפלט אמורים להופיע הערכים
v1beta1.custom.metrics.k8s.ioאוv1beta1.external.metrics.k8s.io, וערך שלTrueבעמודהAvailable. לדוגמה:NAME SERVICE AVAILABLE AGE v1beta1.metrics.k8s.io kube-system/metrics-server True 18dאם הערך בעמודה
AvailableהואFalseאו חסר, סביר להניח שהמתאם קרס או שההגדרה שלו שגויה. בודקים את היומנים של ה-Pod של המתאם במרחב השמותkube-systemאוcustom-metricsכדי לראות אם יש שגיאות שקשורות להרשאות, לקישוריות לרשת למקור המדדים או להודעות שמציינות שלא ניתן למצוא את המדד.אם הערך הוא
True, עוברים לשלב הבא.
ביצוע שאילתה ישירות בממשק ה-API של המדדים: אם המתאם זמין, אפשר לעקוף את HorizontalPodAutoscaler ולבקש את המדד ישירות מממשק ה-API של Kubernetes. הפקודה הזו בודקת את הפייפליין כולו, משרת ה-API ועד למתאם המדדים ומקור הנתונים.
מהפקודות כדי לראות את תגובת ה-JSON הגולמית.כדי לשלוח שאילתה למדדים חיצוניים, מריצים את הפקודה הבאה:
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/METRIC_NAME" | jq .כדי לשלוח שאילתה לגבי מדדים מותאמים אישית של Pod, מריצים את הפקודה הבאה:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/pods/*/METRIC_NAME" | jq .מחליפים את מה שכתוב בשדות הבאים:
-
NAMESPACE_NAME: מרחב השמות שבו פועלים ה-Pods. -
METRIC_NAME: השם של מדד חיצוני או מותאם אישית שאתם מנסים לשלוח לגביו שאילתה. לדוגמה,requests_per_secondאוqueue_depth.
-
ניתוח פלט הפקודה: התוצאה של הפקודות הקודמות מציינת איפה הבעיה. בוחרים את התרחיש שמתאים לפלט:
- תגובת JSON מוצלחת עם ערך: צינור העברת הנתונים של המדדים פועל בצורה תקינה. הבעיה היא כנראה בעיה בהגדרות במניפסט של HorizontalPodAutoscaler. בודקים אם יש שגיאות איות בשם המדד או אם יש
matchLabelsשגוי.
Error: Error from server (Service Unavailable): השגיאה הזו מצביעה בדרך כלל על בעיה בקישוריות לרשת, ולרוב מדובר בבעיה בחומת האש באשכולות שמשתמשים בבידוד רשת.מזהים את שירות מתאם המדדים. בדרך כלל הוא נמצא במרחב השמות
custom-metricsאוkube-system:kubectl get service -n custom-metrics,kube-system | grep -E 'adapter|metrics'מחפשים את היציאה שהמתאם מאזין לה:
kubectl get service ADAPTER_SERVICE -n ADAPTER_NAMESPACE -o yamlמחליפים את מה שכתוב בשדות הבאים:
-
ADAPTER_SERVICE: השם של שירות Kubernetes שמשויך למתאם המדדים שפרסתם. This Service הוא השירות שמצאתם בשלב הקודם. השירות הזה חושף את הפונקציונליות של המתאם לחלקים אחרים באשכול, כולל שרת ה-API של Kubernetes. -
ADAPTER_NAMESPACE: מרחב השמות שבו נמצא שירות המתאם (לדוגמה,custom-metricsאוkube-system).
-
מחפשים את הכללים של חומת האש לשיחות נכנסות במישור הבקרה של האשכול:
gcloud compute firewall-rules list \ --filter="name~gke-CLUSTER_NAME-[0-9a-z]*-master"מחליפים את
CLUSTER_NAMEבשם האשכול.מוסיפים את
targetPortשל המתאם לכלל:כדי לראות את היציאות המותרות הקיימות, מתארים את הכלל הנוכחי:
gcloud compute firewall-rules describe FIREWALL_RULE_NAMEמחליפים את
FIREWALL_RULE_NAMEבשם של כלל חומת האש ששולט בתעבורת הרשת למישור הבקרה של אשכול Kubernetes.מעדכנים את הכלל כדי להוסיף את יציאת המתאם לרשימה:
gcloud compute firewall-rules update FIREWALL_RULE_NAME \ --allow tcp:443,tcp:10250,tcp:ADAPTER_PORTמחליפים את
ADAPTER_PORTביציאת הרשת שהמתאם של המדדים מאזין לה.
מוודאים שכללי המדיניות של רשת Kubernetes לא חוסמים תעבורה לקבוצות ה-Pod של מתאם המדדים:
kubectl get networkpolicy -n custom-metrics,kube-systemבודקים את כללי המדיניות כדי לוודא שהם מאפשרים תעבורת נתונים נכנסת (ingress) ממישור הבקרה או משרת ה-API אל
ADAPTER_SERVICEב-ADAPTER_PORT.
רשימה ריקה
[]: הפלט הזה מציין שהמתאם פועל, אבל לא יכול לאחזר את המדד הספציפי. זה מעיד על בעיה בהגדרת המתאם או במקור המדד עצמו.בעיות ב-Adapter Pod: בודקים את היומנים של ה-Adapter Pod או של ה-Pods של המדדים כדי למצוא שגיאות שקשורות לקריאות ל-API, לאימות או לאחזור מדדים. כדי לבדוק את היומנים:
מאתרים את השם של ה-Pod של המתאם:
kubectl get pods -n ADAPTER_NAMESPACEצפייה ביומנים:
kubectl logs ADAPTER_POD_NAME \ -n ADAPTER_NAMESPACEמחליפים את מה שכתוב בשדות הבאים:
-
ADAPTER_POD_NAME: השם של ה-Pod של המתאם שזיהיתם בשלב הקודם. -
ADAPTER_NAMESPACE: מרחב השמות שבו נמצא ה-Pod של המתאם (לדוגמה,custom-metricsאוkube-system).
-
אין נתונים במקור: יכול להיות שהמדד לא קיים במערכת המקורית. משתמשים בכלי מעקב, כמו Metrics Explorer, כדי לוודא שהמדד קיים ושהשם והתוויות שלו נכונים.
- תגובת JSON מוצלחת עם ערך: צינור העברת הנתונים של המדדים פועל בצורה תקינה. הבעיה היא כנראה בעיה בהגדרות במניפסט של HorizontalPodAutoscaler. בודקים אם יש שגיאות איות בשם המדד או אם יש
לא נמצאו גרסאות של מדדים או שהמתאם לא זמין
תסמינים
השגיאה הבאה מופיעה:
unable to fetch metrics from custom metrics API: no known available metric versions found
מטרה
השגיאה הזו מציינת שיש בעיה בתקשורת בתוך האשכול, ולא בעיה במקור המדדים (כמו Cloud Monitoring). הנה כמה סיבות נפוצות:
- שרת ה-API של Kubernetes לא זמין זמנית (לדוגמה, במהלך שדרוג של אשכול או תיקון של מישור הבקרה).
- ה-Pods של מתאם המדדים (לדוגמה,
custom-metrics-stackdriver-adapter) לא תקינים, לא פועלים או לא רשומים בצורה נכונה בשרת ה-API.
רזולוציה
לרוב מדובר בבעיה זמנית. אם הבעיה נמשכת, אפשר לנסות את הפתרונות הבאים:
בדיקת התקינות של מישור הבקרה של Kubernetes:
במסוף Google Cloud , אפשר לראות את הסטטוס והתקינות של האשכול.
עוברים לדף Kubernetes clusters.
בודקים את העמודות סטטוס והתראות של האשכול.
לוחצים על התראות כדי לבדוק אם יש פעולות שמתבצעות כרגע, כמו שדרוגים או תיקונים. יכול להיות ששרת ה-API לא יהיה זמין לזמן קצר במהלך התקופות האלה.
בודקים ביומני הביקורת של Cloud אם יש שגיאות שקשורות לרכיבי מישור הבקרה. מידע על צפייה ביומנים של GKE
בודקים את התקינות ואת היומנים של ה-Pods של מתאם המדדים: מוודאים שהסטטוס של ה-Pods של מתאם המדדים הוא
Runningושלא בוצעו הפעלות מחדש לאחרונה:kubectl get pods -n custom-metrics,kube-system -o wideאם הסטטוס של ה-Pod הוא כל דבר אחר מלבד
Running, או אם יש לו ספירה גבוהה של הפעלות מחדש, צריך לבדוק את ה-Pod כדי למצוא את הסיבה הבסיסית. טיפים לפתרון בעיות זמינים במאמר Debug Pods (ניפוי באגים ב-Pods) במסמכי התיעוד של Kubernetes.מוודאים שממשקי ה-API של המדדים רשומים וזמינים:
kubectl get apiservice | grep metrics.k8s.ioאם ממשקי ה-API של המדדים תקינים, הפלט דומה לפלט הבא:
NAME SERVICE AVAILABLE AGE v1beta1.custom.metrics.k8s.io custom-metrics/custom-metrics-stackdriver-adapter True 18d v1beta1.external.metrics.k8s.io custom-metrics/custom-metrics-stackdriver-adapter True 18d v1beta1.metrics.k8s.io kube-system/metrics-server True 18dאם בעמודה
AVAILABLEמופיע הערךFalse, יכול להיות שבעמודהMessageבמניפסט המלא של APIService יופיעו פרטים נוספים.כדי לראות את המניפסט המלא, מריצים את הפקודה הבאה:
kubectl get apiservice API_SERVICE_NAME -o yamlמחליפים את
API_SERVICE_NAMEבשם של אובייקט ה-APIService, כמוv1beta1.custom.metrics.k8s.io.
שאילתת מדד לא מחזירה סדרת זמן
תסמינים
השגיאה הבאה מופיעה:
unable to fetch metrics from custom or external metrics API: googleapi: Error
400: The supplied filter [...] query will not return any time series
מטרה
השאילתה שנשלחה אל Cloud Monitoring הייתה תקינה, אבל היא לא החזירה נתונים. המשמעות היא שאין נקודות נתונים שתואמות למסנן (שונה ממדד עם ערך של 0). הסיבה הסבירה ביותר לבעיה הזו היא שהאפליקציה או עומס העבודה שאחראים ליצירת המדד המותאם אישית לא כתבו נתונים ל-Cloud Monitoring בזמן שהשגיאות דווחו.
רזולוציה
אפשר לנסות את הפתרונות הבאים:
- אימות ההגדרה: מוודאים ששמות המדדים והתוויות באובייקט HorizontalPodAutoscaler זהים בדיוק לאלה שמופקים על ידי האפליקציה.
- בדיקת הרשאות: מוודאים שהאפליקציה מוגדרת בצורה נכונה עם ההרשאות הנדרשות ונקודות הקצה של ה-API לפרסום מדדים ב-Cloud Monitoring.
- אישור פעילות האפליקציה: מוודאים שהאפליקציה שאחראית למדד פעלה וניסתה לשלוח נתונים ל-Cloud Monitoring במהלך התקופה שבה התרחשו האזהרות של HorizontalPodAutoscaler.
- בדיקה אם יש שגיאות: בודקים ביומנים של האפליקציה מאותו פרק זמן אם יש שגיאות מפורשות שקשורות לפליטת מדדים, כמו כשלים בחיבור, פרטי כניסה לא תקינים או בעיות בפורמט.
פתרון בעיות שקשורות להתנהגויות של שינוי גודל לא צפויות אבל תקינות
בקטעים הבאים מתוארים תרחישים שבהם ההגדרה של HorizontalPodAutoscaler תקינה והמדדים זמינים, אבל פעולות שינוי הגודל לא מתבצעות כמצופה.
ה-HorizontalPodAutoscaler תקין אבל לא משנה את קנה המידה
תסמינים
ה-HorizontalPodAutoscaler נראה תקין, התנאים שלו מדווחים על True, ולא מוצגות שגיאות באירועים שלו. עם זאת, המערכת עדיין לא מבצעת פעולות שינוי גודל.
מטרה
יש כמה גורמים שיכולים לגרום להתנהגות הזו:
- מגבלות של רפליקות: המספר הנוכחי של הרפליקות כבר הגיע לגבול שהוגדר בשדה
minReplicasאוmaxReplicasבהגדרת HorizontalPodAutoscaler. - חלון סבילות: מערכת Kubernetes משתמשת בחלון סבילות של 10% כברירת מחדל כדי למנוע שינוי גודל בעקבות תנודות קלות במדדים. התאמה מתבצעת רק אם היחס בין המדד הנוכחי למדד היעד חורג מהטווח 0.9 עד 1.1. לדוגמה, אם יעד השימוש במעבד הוא 85% והשימוש הנוכחי הוא 93%, היחס הוא בערך 1.094 (93/85≈1.094). מכיוון שהערך הזה קטן מ-1.1, ה-HorizontalPodAutoscaler לא מבצע הגדלה.
- Pods שלא מוכנים: HorizontalPodAutoscaler כולל רק Pods עם סטטוס
Readyבחישובי ההתאמה שלו. המערכת מתעלמת מ-Pods שנתקעו בסטטוסPendingאו שלא הופכים ל-Ready(בגלל בדיקות תקינות שנכשלו או בעיות במשאבים), והם עלולים למנוע שינוי גודל. - השהיה של תקופת הסנכרון: בקר HorizontalPodAutoscaler בודק את המדדים באופן תקופתי. עיכוב של 15-30 שניות בין הרגע שבו ערך המדד חוצה את הסף לבין הרגע שבו מתחילה פעולת שינוי הגודל הוא נורמלי.
- השהיה במדד חדש: כש-HorizontalPodAutoscaler משתמש במדד מותאם אישית חדש בפעם הראשונה, יכול להיות שתהיה השהיה חד-פעמית של כמה דקות. העיכוב הזה קורה כי מערכת המעקב (כמו Cloud Monitoring) צריכה ליצור את סדרת הזמן החדשה כשנקודת הנתונים הראשונה נכתבת.
- חישוב של כמה מדדים: כשמגדירים כמה מדדים, ה-HorizontalPodAutoscaler מחשב את מספר הרפליקות הנדרש לכל מדד בנפרד, ואז בוחר את הערך המחושב הגבוה ביותר כמספר הרפליקות הסופי. בגלל ההתנהגות הזו, עומס העבודה שלכם מותאם כדי לעמוד בדרישות של המדד עם הצרכים הכי גבוהים. לדוגמה, אם מדדי CPU מחשבים שיש צורך ב-9 רפליקות, אבל מדד הבקשות לשנייה מחשב שיש צורך ב-15, הכלי HorizontalPodAutoscaler משנה את קנה המידה של הפריסה ל-15 רפליקות.
רזולוציה
אפשר לנסות את הפתרונות הבאים:
- מגבלות על רפליקות: בודקים את הערכים
minReplicasו-maxReplicasבמניפסט של HorizontalPodAutoscaler או בפלט של הפקודהkubectl describe. אם המגבלות האלה מונעות את ההרחבה הנדרשת, צריך לשנות אותן. - חלון הסבילות: אם נדרש שינוי גודל בתוך הסבילות שמוגדרת כברירת מחדל, צריך להגדיר ערך סבילות אחר. אחרת, צריך לחכות עד שהמדד יצא מהטווח של 0.9 עד 1.1.
- Unready Pods: בודקים למה סטטוס ה-Pods הוא
Pendingאו לאReadyופותרים את הבעיות הבסיסיות (למשל, מגבלות משאבים, בדיקות מוכנות שנכשלו). טיפים לפתרון בעיות אפשר למצוא במאמר Debug Pods במסמכי התיעוד של Kubernetes. - עיכוב בתקופת הסנכרון וחביון של מדדים חדשים: אלה הם חביונים רגילים. מחכים לסיום תקופת הסנכרון או ליצירת סדרת הזמן של המדד המותאם אישית החדש.
- חישוב של כמה מדדים: זו ההתנהגות הרצויה. אם ההרחבה מתבצעת על סמך מדד אחד (למשל, בקשות לשנייה), היא מבטלת בצורה נכונה את החישוב הנמוך יותר של מדד אחר (למשל, CPU).
הפחתה בהתאם לעומס נכשלת ב-HorizontalPodAutoscaler
תסמינים
ה-HorizontalPodAutoscaler מרחיב את עומס העבודה בהצלחה, אבל לא מצליח לצמצם אותו גם כשמדדים כמו ניצול המעבד נמוכים.
מטרה
ההתנהגות הזו נועדה למנוע הגדלה והקטנה מהירות של נפח האחסון או הקטנה שלו על סמך מידע חלקי. הסיבות העיקריות לכך הן:
- שימוש בכמה מדדים: ה-HorizontalPodAutoscaler מבצע שינוי גודל על סמך המדד שדורש את מספר הרפליקות הגדול ביותר. אם יש לכם כמה מדדים, עומס העבודה לא יצטמצם אלא אם כל המדדים יצביעו על כך שנדרשות פחות רפליקות. אם מדד אחד דורש מספר גבוה של עותקים, לא ניתן לצמצם את מספר העותקים, גם אם ערכי המדדים האחרים נמוכים.
- מדדים לא זמינים: אם מדד כלשהו לא זמין (לרוב מוצג כ-
<unknown>), ה-HorizontalPodAutoscaler מסרב באופן שמרני להקטין את קנה המידה של עומס העבודה. הכלי לא יכול לקבוע אם המדד חסר כי השימוש הוא אפס או כי צינור המדדים לא תקין. הבעיה הזו נפוצה במדדים מותאמים אישית שמבוססים על שיעורים (לדוגמה,messages_per_second), שיכולים להפסיק לדווח על נתונים כשאין פעילות, ולגרום ל-HorizontalPodAutoscaler לראות את המדד כלא זמין ולהפסיק את פעולות ההקטנה. - השהיית הקטנת הקיבולת ממדיניות שינוי הגודל: השדה
behaviorשל HorizontalPodAutoscaler מאפשר להגדיר מדיניות שינוי גודל. מדיניות ברירת המחדל לצמצום הקיבולת כוללת חלון ייצוב של 300 שניות (חמש דקות). במהלך החלון הזה, ה-HorizontalPodAutoscaler לא יקטין את מספר הרפליקות, גם אם ערכי המדדים ירדו מתחת לסף היעד. החלון הזה מונע תנודות מהירות, אבל הוא עלול להאט את ההקטנה בהשוואה למה שמצפים.
רזולוציה
אפשר לנסות את הפתרונות הבאים:
אם יש כמה מדדים או מדדים לא זמינים, צריך לאבחן את המדד שגורם לבעיות:
kubectl describe hpa HPA_NAME -n NAMESPACE_NAMEבפלט, בודקים בקטע
Metricsאם יש מדד עם סטטוס<unknown>, ובקטעEventsאם יש אזהרות כמוFailedGetCustomMetricאוFailedGetExternalMetric. למידע על ניפוי באגים מפורט בצינורות, אפשר לעיין בקטע פתרון בעיות במדדים חיצוניים ומותאמים אישית.אם מדד מסוים לא זמין, והוא הופך ללא זמין בתקופות של תנועה נמוכה (תופעה שכיחה במדדים שמבוססים על שיעורים), אפשר לנסות את אחד מהפתרונות הבאים:
- אם אפשר, כדאי להשתמש במדדים שמבוססים על מדד במקום במדדים שמבוססים על שיעור. מדד של מד, כמו המספר הכולל של הודעות בתור (לדוגמה,
subscriptionאוnum_undelivered_messages), מדווח באופן עקבי על ערך, גם אם הערך הוא0, וכך מאפשר ל-HorizontalPodAutoscaler לקבל החלטות לגבי שינוי גודל באופן מהימן. - מוודאים שמקור המדד מדווח על ערכים אפסיים. אם אתם שולטים במדד המותאם אישית, כדאי להגדיר אותו כך שיפרסם
0בתקופות של חוסר פעילות, במקום לא לשלוח נתונים בכלל.
- אם אפשר, כדאי להשתמש במדדים שמבוססים על מדד במקום במדדים שמבוססים על שיעור. מדד של מד, כמו המספר הכולל של הודעות בתור (לדוגמה,
אם חלון הייצוב של חמש דקות שמוגדר כברירת מחדל לצמצום הקיבולת ארוך מדי, אפשר להתאים אותו אישית. בודקים את הקטע
spec.behavior.scaleDownבמניפסט של HorizontalPodAutoscaler. אפשר להקטין את הערך שלstabilizationWindowSecondsכדי לאפשר למנגנון לשינוי גודל הקבוצה להקטין את הקבוצה מהר יותר אחרי שהמדדים יורדים. מידע נוסף על הגדרת כללי המדיניות האלה זמין במאמר Scaling Policies במסמכי העזרה של Kubernetes.
המאמרים הבאים
אם לא מצאתם פתרון לבעיה שלכם במסמכים, תוכלו לקבל עזרה נוספת במאמר בנושא קבלת תמיכה, כולל עצות בנושאים הבאים:
- פתיחת בקשת תמיכה באמצעות פנייה אל Cloud Customer Care.
- קבלת תמיכה מהקהילה על ידי פרסום שאלות ב-StackOverflow ושימוש בתג
google-kubernetes-engineכדי לחפש בעיות דומות. אפשר גם להצטרף לערוץ Slack#kubernetes-engineכדי לקבל תמיכה נוספת מהקהילה. - פתיחת דיווחים על בעיות או בקשות להוספת תכונות באמצעות הכלי הציבורי למעקב אחר בעיות.