כדי לנהל בצורה יעילה יותר את עלויות התשתית ואת המכסות, אתם יכולים להגדיר מגבלות מקסימליות למשאבים של הכלי להתאמה אוטומטית של קנה מידה באשכולות של Google Kubernetes Engine (GKE). במאמר הזה מוסבר איך להשתמש במשאב המותאם אישית CapacityQuota כדי לציין מגבלות של משאבים להתאמה אוטומטית לעומס עבור קבוצות משנה של צמתים. בניגוד למגבלות על משאבים ברמת האשכול, אתם יכולים לבחור צמתים ספציפיים ב-CapacityQuota באמצעות בוררי תוויות של Kubernetes.
המסמך הזה מיועד לאדמינים של פלטפורמות שמנהלים את התשתית ואת שינוי הגודל של אשכולות. מומלץ להכיר את תוויות הצמתים של Kubernetes ואת המידרוג האוטומטי של האשכול ב-GKE.
הסבר על מגבלות המשאבים של CapacityQuota
CapacityQuota הוא משאב בהתאמה אישית של Kubernetes בהיקף אשכול, שאתם מגדירים במניפסט ומחילים על האשכול. כדי לבחור צמתים ולציין מגבלות על משאבים, משתמשים בשדות הבאים במפרט של CapacityQuota:
-
selector: סינון של צמתים ספציפיים באמצעות בורר תוויות אחד או יותר. לדוגמה, אפשר לבחור את כל הצמתים של ComputeClass ספציפי או צמתים עם שתי תוויות ספציפיות. -
limits: מציינים את מגבלות המשאבים המקסימליות לצמתים שתואמים לסלקטורים. לדוגמה, אתם יכולים להגביל את כמות ה-CPU שאפשר להשתמש בה במחלקה ספציפית של מחשוב בהתאמה אישית, או להגביל את מספר ה-GPU מסוג מסוים.
כשהפעולה של הרחבה אנכית מתחילה, המידרוג האוטומטי של האשכול בודק את הצומת המוצע מול כל CapacityQuotas שתואמים לתוויות הצומת, ומול כל מגבלות המשאבים שהוגדרו ברמת האשכול. GKE יוצר את הצומת רק אם הוא לא חורג ממגבלות המשאבים שהוגדרו.
מגבלות
- GKE דוחה מכסות קיבולת שמציינות את בוררי התוויות
node.kubernetes.io/instance-typeו-beta.kubernetes.io/instance-type. כדי להגביל את הצמתים שמשתמשים בסוג מכונה ספציפי, יוצרים ComputeClass בהתאמה אישית עם כללי עדיפותmachineTypeובוחרים את ה-ComputeClass הזה ב-CapacityQuota. - בדומה למגבלות ברמת האשכול, יכול להיות שמכסות קיבולת ימנעו העברה פעילה של ComputeClass. העברה פעילה היא פעולה של הרחבה אנכית בהתאם לעומס (scale up), ולכן המידרוג האוטומטי של האשכול בודק את הצומת החדש הפוטנציאלי בהשוואה לכל מכסות הקיבולת (CapacityQuotas) הרלוונטיות ולמגבלות המשאבים ברמת האשכול. אם הצומת החדש חורג מאחת מהמגבלות האלה, GKE לא יוצר את הצומת וההעברה הפעילה לא מתבצעת. המצב הזה קורה רק אם הערך של CapacityQuota כבר הגיע למגבלות שהוגדרו או קרוב אליהן.
- מגבלות מכסת הקיבולת הן לא מגבלות מחמירות. בתרחישים נדירים, יכול להיות שתבחינו ש-GKE חורג מהמגבלות שהוגדרו בשיעור קטן.
- ההגבלות של CapacityQuota נאכפות רק על ידי המידרוג האוטומטי של האשכול. אפשר לחרוג מהמגבלות על ידי הרחבה ידנית של האשכול, או על ידי שינוי המגבלות כך שיהיו נמוכות מהשימוש הנוכחי.
- אם הצמתים באשכול חורגים מהמגבלות שהוגדרו ב-CapacityQuota, אז המידרוג האוטומטי חוסם את היצירה של צמתים חדשים שתואמים ל-CapacityQuota שחרגו ממנו. המידרוג האוטומטי של האשכול לא מקטין את מספר הצמתים הקיימים שתואמים ל-CapacityQuota.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם כבר התקנתם את ה-CLI של gcloud, הריצו את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם אשכול קיים במצב Autopilot או Standard שפועל בגרסה 1.36.2-gke.2064000 ואילך. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.
הגדרת מגבלות משאבים ב-CapacityQuota
כדי לבחור את הצמתים ש-CapacityQuota חלה עליהם, אפשר להשתמש באחת מהשיטות הבאות או בשתיהן:
בחירת צמתים באמצעות תוויות צומת מדויקות: מציינים צמד אחד או יותר של מפתח/ערך של תווית צומת בשדה
matchLabels. GKE מוצא צמתים שיש להם את כל התוויות שציינתם. השיטה הזו דומה לשימוש בשדהnodeSelectorבמפרט של Pod.בחירת צמתים באמצעות ביטויים: מציינים ביטוי אחד או יותר של סלקטור תוויות על ידי ציון מפתח התווית, אופרטורים וערכים. השיטה הזו דומה לשימוש בשדה
nodeAffinityבמפרט של Pod.
בחירת צמתים באמצעות תוויות צמתים
כדי ליצור CapacityQuota על סמך התאמה של תוויות צמתים באמצעות השדה matchLabels, פועלים לפי השלבים הבאים:
שומרים אחת מהדוגמאות הבאות של CapacityQuotas, שכל אחת מהן מיועדת לתרחיש שימוש ספציפי:
כדי להגדיר מגבלות משאבים לכל ComputeClass מותאם אישית, מציינים את התווית
cloud.google.com/compute-class:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityQuota metadata: name: capacity-quota-compute-class spec: selector: matchLabels: cloud.google.com/compute-class: my-class limits: resources: cpu: 12ה-CapacityQuota הזה מגביל את ה-Cluster Autoscaler למקסימום של 12 מעבדים בכל הצמתים ש-GKE יוצר עבור
my-classComputeClass.כדי להגדיר מגבלות על מספר ה-GPU מסוג מסוים, משתמשים בתווית
cloud.google.com/gke-acceleratorובשם המשאבnvidia.com/gpu:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityQuota metadata: name: capacity-quota-gpu spec: selector: matchLabels: cloud.google.com/compute-class: my-gpu-class cloud.google.com/gke-accelerator: nvidia-tesla-t4 limits: resources: nvidia.com/gpu: 16ה-CapacityQuota הזה מגביל את המידרוג האוטומטי של האשכול ל-16 מעבדי GPU מסוג NVIDIA Tesla T4 לכל היותר ב-ComputeClass
my-gpu-class. אם לא מציינים את בורר ComputeClass, המגבלה חלה על כל הצמתים של NVIDIA Tesla T4 GPU באשכול.כדי להגדיר מגבלות על מספר הצמתים ש-GKE יוצר באזור מסוים, משתמשים בתווית
topology.kubernetes.io/zoneובשם המשאבnodes:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityQuota metadata: name: capacity-quota-zone spec: selector: matchLabels: topology.kubernetes.io/zone: us-central1-b limits: resources: nodes: 64ההגבלה הזו מגבילה את המידרוג האוטומטי באשכול ל-64 צמתים באזור
us-central1-b.
יוצרים את מכסת הקיבולת:
kubectl apply -f PATH_TO_MANIFEST_FILEמחליפים את
PATH_TO_MANIFEST_FILEבנתיב לקובץ המניפסט CapacityQuota שיצרתם.
בחירת צמתים באמצעות ביטויים
לטירגוט מורכב יותר, אפשר להגדיר ב-CapacityQuota את השדה matchExpressions בנוסף לשדה matchLabels. האופרטור matchExpressions מאפשר שימוש באופרטורים כמו In, NotIn, Exists ו-DoesNotExist.
יוצרים מניפסט CapacityQuota שמשתמש בשדה
matchExpressions. בדוגמה הבאה של CapacityQuota מוגדרים מגבלות על מעבד וזיכרון לצמתים שפועלים במשפחות ספציפיות של מכונות עם ביצועים גבוהים, על ידי קיבוץ שלהם באמצעות האופרטורIn:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityQuota metadata: name: capacity-quota-high-perf-machines spec: selector: matchExpressions: - key: cloud.google.com/machine-family operator: In values: - c2 - c3 - c3d limits: resources: cpu: 64 memory: 128Giמחילים את המניפסט על האשכול:
kubectl apply -f PATH_TO_MANIFEST_FILEמחליפים את
PATH_TO_MANIFEST_FILEבנתיב לקובץ המניפסט CapacityQuota שיצרתם.
אימות ההגדרה של CapacityQuota
בקטע הזה נסביר איך לוודא ש-CapacityQuota אוכף מגבלות באופן פעיל, באמצעות פריסת עומס עבודה לדוגמה שמפר את המגבלות האלה. כדי לבצע את האימות:
שומרים את הדוגמה הבאה של ComputeClass בתור
test-capacityquota-class.yaml:apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: test-capacityquota-class spec: priorities: - machineFamily: n2 nodePoolAutoCreation: enabled: trueה-ComputeClass הזה יכול ליצור אוטומטית צמתים שמשתמשים בסדרת המכונות N2.
יוצרים את ComputeClass:
kubectl apply -f test-capacityquota-class.yamlשומרים את הדוגמה הבאה של CapacityQuota כ-
test-capacityquota.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityQuota metadata: name: test-capacityquota spec: selector: matchLabels: cloud.google.com/compute-class: test-capacityquota-class limits: resources: cpu: 8ההגדרה CapacityQuota מגבילה את קנה המידה האוטומטי למקסימום של 8 משאבי CPU עבור
test-capacityquota-classComputeClass.יוצרים את מכסת הקיבולת:
kubectl apply -f test-capacityquota.yamlשומרים את הפריסה הבאה בשם
test-capacityquota-workload.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: test-capacityquota-workload spec: replicas: 16 selector: matchLabels: app: test-capacityquota-workload template: metadata: labels: app: test-capacityquota-workload spec: containers: - name: test image: gcr.io/google_containers/pause resources: limits: cpu: 500m nodeSelector: cloud.google.com/compute-class: test-capacityquota-classהפריסה הזו יוצרת 16 פודים, שכל אחד מהם מבקש 500 mCPU. מכיוון שהצמתים שומרים חלק מהמעבד לרכיבי המערכת, סכום משאבי המעבד בכל הצמתים ש-GKE צריך ליצור כדי להפעיל את 16 ה-Pods גדול מ-
8.יוצרים את הפריסה:
kubectl apply -f test-capacityquota-workload.yamlממתינים כשתי דקות ואז מאמתים את סטטוס התזמון של ה-Pod:
kubectl get pods -l app=test-capacityquota-workloadהמידרוג האוטומטי באשכול מרחיב את הצמתים עד למגבלת CapacityQuota של 8 מעבדים. אחרי שמגיעים למגבלה הזו, המידרוג האוטומטי לא יוצר צמתים. כתוצאה מכך, חלק מה-Pods בפריסה נשארים במצב
Pending.כדי לוודא שהסטטוס
Pendingנגרם בגלל CapacityQuota, מתארים אחד מה-Pods בהמתנה:kubectl describe pod PENDING_POD_NAMEמחליפים את
PENDING_POD_NAMEבשם של Pod שנתקע במצבPending.הפלט אמור להיראות כך, ולציין שהגדלת הצומת נחסמה בגלל CapacityQuota:
Pod didn't trigger scale-up: 1 exceeded quota: "CapacityQuota/test-capacityquota", resources: cpuאפשר גם להציג את האירועים האלה באמצעות יומני החשיפה של המידרוג האוטומטי של האשכול. בודקים את האירוע
noScaleUp, כמו בדוגמה הבאה:{ "jsonPayload": { "noDecisionStatus": { "noScaleUp": { "skippedMigs": [ { "reason": { "parameters": [ "exceeded quota: \"CapacityQuota/test-capacityquota\", resources: cpu" ], "messageId": "no.scale.up.mig.skipped" }, "mig": { "name": "gke-test-grp", "zone": "us-central1-f", "nodepool": "nap-n2-highcpu-2-test" } } ] } } } }
בדיקת השימוש והתוקף של CapacityQuotas
השדה status במשאב CapacityQuota API מספק מידע על השימוש במשאבים של צמתים שתואמים ל-CapacityQuota, ועל התוקף של מפרט CapacityQuota.
כדי לבדוק את הסטטוס של CapacityQuota, מריצים את הפקודה הבאה:
kubectl describe capacityquota CAPACITY_QUOTA_NAME
מחליפים את CAPACITY_QUOTA_NAME בשם של מכסת הקיבולת שרוצים לבדוק.
בודקים את השדות הבאים בפלט:
כדי לבדוק את השימוש במשאבים של הצמתים התואמים, משתמשים בשדה
status.used:status: conditions: - lastTransitionTime: "2026-07-27T10:00:00Z" message: "CapacityQuota is valid" reason: "Valid" status: "True" type: "cluster-autoscaler.kubernetes.io/valid" used: resources: cpu: 32 memory: 128Giהשדה
status.usedמיועד לניראות (observability), והמידרוג האוטומטי של האשכול לא משתמש בו כדי לאכוף מגבלות. השדה הזה מציג את השימוש רק אחרי פעולת הרחבה מוצלחת. המידרוג האוטומטי של האשכול עוקב גם אחרי צמתים בהמתנה באופן פנימי, ומשקלל את הצמתים האלה בהמתנה בהערכות הבאות של הגדלת הקיבולת. המעקב הפנימי הזה עוזר למנוע חריגה מהמגבלות.כדי לבדוק את התוקף של CapacityQuota, משתמשים בשדה
status.conditions:status: conditions: - lastTransitionTime: "2026-07-27T10:00:00Z" message: "CapacityQuota is valid" reason: "Valid" status: "True" type: "cluster-autoscaler.kubernetes.io/valid" used: resources: cpu: 32 memory: 128Giהתנאי
cluster-autoscaler.kubernetes.io/validבודק אם מכסת הקיבולת משתמשת בהגדרה תקינה, כמו סלקטור בפורמט הנכון. אם הערך בשדהstatusשל התנאי הזה הואTrue, מכסת הקיבולת תקפה והמגבלות שלכם נאכפות. עם זאת, אם הערך בשדהstatusהואFalse, או אם התנאי עדיין לא קיים, המגבלות לא נאכפות. בשדהmessageמפורטות הסיבות לכך שהערך של CapacityQuota לא תקין.