שליטה במאפייני צמתים שמתבצעת בהם התאמה אוטומטית של גודלם באמצעות ComputeClasses מותאמים אישית

במאמר הזה נסביר איך להשתמש בComputeClasses בהתאמה אישית כדי לשלוט בתשתית המחשוב ובהתאמה האוטומטית לעומס של אשכולות Google Kubernetes Engine ‏ (GKE) בהתאם לצרכים הספציפיים של עומסי העבודה.

המסמך הזה מיועד למנהלי פלטפורמות שרוצים להגדיר באופן הצהרתי פרופילים של התאמה אוטומטית לעומס (autoscaling) לצמתים, ולמפעילי אשכולות שרוצים להריץ את עומסי העבודה שלהם ב-ComputeClasses ספציפיים.

מידע על ComputeClasses בהתאמה אישית

‫ComputeClasses בהתאמה אישית הם משאבים בהתאמה אישית של Kubernetes, שמאפשרים להגדיר את סדרי העדיפויות של GKE בהקצאת צמתים להרצת עומסי העבודה. אתם יכולים להשתמש ב-ComputeClass בהתאמה אישית כדי:

  • נותנים ל-GKE קבוצה של עדיפויות שצריך לפעול לפיהן ברצף כשמקצים צמתים, לכל אחד מהם פרמטרים ספציפיים כמו סדרת מכונות של Compute Engine או קיבולת משאבים מינימלית.
  • הגדרת ספים ופרמטרים להתאמה לעומס (autoscaling) כדי להסיר צמתים שלא מנוצלים מספיק ולאחד עומסי עבודה ביעילות בקיבולת המחשוב הקיימת
  • אפשר להגדיר ל-GKE להחליף באופן אוטומטי הגדרות צומת פחות מועדפות בהגדרות צומת מועדפות יותר, כדי לשפר את הביצועים של עומס העבודה.

במאמר מידע על ComputeClasses בהתאמה אישית מוסבר על כל אפשרויות ההגדרה ואיך הן פועלות ביחד ועם מצב Autopilot ומצב Standard ב-GKE.

תמחור

המשאב המותאם אישית ComputeClass מסופק בלי עלות נוספת ב-GKE. אלה שיקולי התמחור שרלוונטיים:

מגבלות

השם של ComputeClass לא יכול להתחיל ב-gke או ב-autopilot.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:

  • מפעילים את Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-Google Cloud CLI למשימה הזו, מתקינים ואז מאתחלים את ה-CLI של gcloud. אם כבר התקנתם את ה-CLI של gcloud, הריצו את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שבגרסאות קודמות של ה-CLI של gcloud אי אפשר להריץ את הפקודות שבמסמך הזה.

תרחיש לדוגמה ל-ComputeClasses

במאמר הזה מוצג תרחיש לדוגמה שבו מגדירים ComputeClass בהתאמה אישית. בפועל, כדאי להביא בחשבון את הדרישות של עומסי העבודה והארגון הספציפיים שלכם, ולהגדיר ComputeClasses שעומדים בדרישות האלה. תיאורים מלאים של כל האפשרויות של ComputeClasses ושיקולים מיוחדים מפורטים במאמר מידע על ComputeClasses בהתאמה אישית.

לדוגמה:

  • המטרה שלכם היא לבצע אופטימיזציה של עלויות התפעול של עומסי העבודה (workloads)
  • עומסי העבודה שלכם עמידים בפני תקלות ולא דורשים כיבוי מבוקר או זמן ריצה ארוך יותר.
  • כדי שעומסי העבודה יפעלו בצורה אופטימלית, צריך לפחות 64 vCPU
  • אתם מוגבלים לסדרת המכונות N4 של Compute Engine

לפי התרחיש לדוגמה, אתם מחליטים שאתם רוצים ComputeClass שמבצע את הפעולות הבאות:

  • מתעדף צומתי N4 Spot עם לפחות 64 vCPU
  • מאפשר ל-GKE לחזור לכל צומת N4 Spot, בלי קשר לקיבולת המחשוב
  • אם אין צומתי N4 Spot זמינים, GKE יכול להשתמש בצומתי N4 על פי דרישה
  • מורה ל-GKE להעביר את עומסי העבודה לצומתי Spot בכל פעם שהם זמינים שוב.

הגדרת ComputeClass במצב אוטומטי

ב-GKE Autopilot, מגדירים ComputeClass, פורסים אותו באשכול ומבקשים את ה-ComputeClass בעומסי העבודה. ‫GKE מבצע בשבילכם את כל שלבי ההגדרה של הצומת, כמו החלת תוויות ו-taints.

שומרים את המניפסט הבא בתור compute-class.yaml:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: cost-optimized
spec:
  priorities:
  - machineFamily: n4
    spot: true
    minCores: 64
  - machineFamily: n4
    spot: true
  - machineFamily: n4
    spot: false
  activeMigration:
    optimizeRulePriority: true
  nodePoolAutoCreation:
    enabled: true

הגדרת ComputeClass במצב רגיל

באשכולות במצב GKE Standard, יכול להיות שתצטרכו לבצע הגדרה ידנית כדי לוודא שהפודים של ComputeClass מתוזמנים כמו שצריך. ההגדרה הידנית תלויה בשאלה אם מאגרי הצמתים נוצרים באופן אוטומטי, באופן הבא:

כדי לאפשר ל-GKE ליצור באופן אוטומטי מאגרי צמתים ל-ComputeClass:

  1. באשכולות במצב Standard שפועלים בגרסה שקודמת ל-1.33.3-gke.1136000 ולא רשומים לערוץ ההפצה המהירה, מפעילים הקצאת צמתים אוטומטית ברמת האשכול.
  2. שומרים את המניפסט לדוגמה הבא בתור compute-class.yaml:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: cost-optimized
    spec:
      priorities:
      - machineFamily: n4
        spot: true
        minCores: 64
      - machineFamily: n4
        spot: true
      - machineFamily: n4
        spot: false
      activeMigration:
        optimizeRulePriority: true
      nodePoolAutoCreation:
        enabled: true
    

    כשפורסים Pods שמבקשים את ה-ComputeClass לדוגמה וצריך ליצור צמתים חדשים, GKE נותן עדיפות ליצירת צמתים לפי סדר הפריטים בשדה priorities. אם צריך, GKE יוצר מאגרי צמתים חדשים שעומדים בדרישות החומרה של ComputeClass.

אפשר גם לציין סוג מכונה בהתאמה אישית מדויק בעדיפויות. כדי להשתמש בסוגי מכונות בהתאמה אישית, צריך להשתמש בגרסה 1.33.2-gke.1111000 או בגרסה חדשה יותר של GKE. בדוגמה הבאה מוגדר ComputeClass שנותן עדיפות למכונות וירטואליות במודל Spot לסוג המכונה בהתאמה אישית n4-custom-8-20480, וחוזר למכונות וירטואליות על פי דרישה מאותו סוג אם הקיבולת של Spot לא זמינה:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: custom-machine-type
spec:
  priorities:
  - machineType: n4-custom-8-20480
    spot: true
  - machineType: n4-custom-8-20480
    spot: false
  nodePoolAutoCreation:
    enabled: true

כדי לשפר את זמינות הקיבולת כשיש מגבלות קיבולת, הגדירו ComputeClass שכולל כמה סדרות ודורות של מכונות. בעומסי עבודה ללא שמירת מצב (stateless) או בעומסי עבודה שעמידים בפני שיבושים, אפשר גם להפעיל העברה פעילה כדי להחזיר את עומסי העבודה לחומרה המועדפת כשהקיבולת מתאוששת:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: multi-family-fallback
spec:
  priorities:
  - machineFamily: c4d
  - machineFamily: c3d
  - machineFamily: c4
  - machineFamily: c3
  - machineFamily: n4
  - machineFamily: n2d
  activeMigration:
    optimizeRulePriority: true
  nodePoolAutoCreation:
    enabled: true

סדרות חדשות יותר של מכונות, כמו C4,‏ C4D ו-N4, תומכות רק ב-Hyperdisk, וסדרות ישנות יותר, כמו N2D, משתמשות ב-Persistent Disk. אם עומסי עבודה עם שמירת מצב משתמשים ב-ComputeClass שכולל את שני הדורות, צריך להשבית את ההעברה הפעילה, ובגרסה 1.35.3-gke.1290000 ואילך של GKE, להשתמש ב-StorageClass המובנה dynamic-rwo או ב-StorageClass בהתאמה אישית עם בחירה אוטומטית של סוג הדיסק (parameters.type: dynamic), use-allowed-disk-topology: "true" ו-volumeBindingMode: WaitForFirstConsumer. לאחר מכן, GKE בוחר סוג דיסק תואם כשמקצים נפחים חדשים, ומתזמן נפחים קיימים רק בסדרות מכונות תואמות.

שימוש ב-ComputeClasses עם מאגרי צמתים שנוצרו באופן ידני

בקטע הזה מוסבר איך להגדיר ComputeClass באשכול שמשתמש רק במאגרי צמתים שנוצרו באופן ידני.

  1. שומרים את המניפסט הבא בתור compute-class.yaml:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: cost-optimized
    spec:
      priorities:
      - machineFamily: n4
        spot: true
        minCores: 64
      - machineFamily: n4
        spot: true
      - machineFamily: n4
        spot: false
      activeMigration:
        optimizeRulePriority: true
    
  2. יוצרים מאגר צמתים חדש עם התאמה אוטומטית לעומס (autoscaling) שמשתמש ב-VM במודל Spot, ומשייכים אותו ל-ComputeClass:

    gcloud container node-pools create cost-optimized-pool \
        --location=LOCATION \
        --cluster=CLUSTER_NAME \
        --machine-type=n4-standard-64 \
        --spot \
        --enable-autoscaling \
        --max-nodes=9 \
        --node-labels="cloud.google.com/compute-class=cost-optimized" \
        --node-taints="cloud.google.com/compute-class=cost-optimized:NoSchedule"
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫LOCATION: המיקום של האשכול.
    • ‫CLUSTER_NAME: השם של האשכול הקיים.
  3. יוצרים מאגר צמתים חדש עם התאמה לעומס (autoscaling) ומכונות וירטואליות על פי דרישה, ומשייכים אותו ל-ComputeClass:

    gcloud container node-pools create on-demand-pool \
        --location=LOCATION \
        --cluster=CLUSTER_NAME \
        --machine-type=n4-standard-64 \
        --enable-autoscaling \
        --max-nodes=9 \
        --num-nodes=0 \
        --node-labels="cloud.google.com/compute-class=cost-optimized" \
        --node-taints="cloud.google.com/compute-class=cost-optimized:NoSchedule"
    

כשפורסים פודים שמבקשים את ה-ComputeClass הזה וצריך ליצור צמתים חדשים, GKE נותן עדיפות ליצירת צמתים במאגר הצמתים cost-optimized-pool. אם אי אפשר ליצור צמתים חדשים, GKE יוצר צמתים במאגר הצמתים on-demand-pool.

במאמר הגדרת מאגרי צמתים שנוצרו באופן ידני לשימוש ב-ComputeClass מוסבר איך מאגרי צמתים שנוצרו באופן ידני פועלים עם ComputeClasses בהתאמה אישית.

התאמה אישית של ספי ההתאמה לעומס (autoscaling) לאיחוד צמתים

כברירת מחדל, GKE מסיר צמתים שלא מנוצלים מספיק ומתזמן מחדש את עומסי העבודה לצמתים זמינים אחרים. אפשר להתאים אישית את ערכי הסף ואת התזמון להסרת צומת באמצעות השדה autoscalingPolicy בהגדרה של ComputeClass, כמו בדוגמה הבאה:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: cost-optimized
spec:
  priorities:
  - machineFamily: n4
    spot: true
    minCores: 64
  - machineFamily: n4
    spot: true
  - machineFamily: n4
    spot: false
  activeMigration:
    optimizeRulePriority: true
  autoscalingPolicy:
    consolidationDelayMinutes : 5
    consolidationThreshold    : 70

בדוגמה הזו, צומת הופך למועמד להסרה אם הוא מנוצל פחות מ-70% מקיבולת המעבד והזיכרון הזמינה שלו במשך יותר מחמש דקות. רשימת הפרמטרים הזמינים להגדרה של התאמה אוטומטית לעומס לאיחוד צמתים

פריסת ComputeClass באשכול

אחרי שמגדירים ComputeClass, פורסים אותו באשכול:

kubectl apply -f compute-class.yaml

ה-ComputeClass הזה מוכן לשימוש באשכול. אתם יכולים לבקש את ComputeClass במפרטים של Pod, או להגדיר אותו כברירת המחדל של ComputeClass במרחב שמות ספציפי.

בקשה ל-ComputeClass בעומס עבודה

כדי לבקש ComputeClass בעומס עבודה, מוסיפים בורר צמתים ל-ComputeClass במניפסט, כמו בשלבים הבאים:

  1. שומרים את המניפסט הבא בתור cc-workload.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-workload
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: custom-workload
      template:
        metadata:
          labels:
            app: custom-workload
        spec:
          nodeSelector:
            cloud.google.com/compute-class: cost-optimized
          containers:
          - name: test
            image: registry.k8s.io/pause
            resources:
              requests:
                cpu: 1.5
                memory: "4Gi"
    
  2. פורסים את עומס העבודה:

    kubectl apply -f cc-workload.yaml
    

כשפורסים את עומס העבודה הזה, GKE מוסיף באופן אוטומטי ל-Pods טולרנטיות שתואמת ל-taint של הצומת ל-ComputeClass המבוקש. הסבילות הזו עוזרת לוודא שרק Pods שמבקשים את ComputeClass פועלים בצומתי ComputeClass.

סינון צמתים לפי ComputeClass

לכל הצמתים שמשויכים ל-ComputeClasses יש את התווית cloud.google.com/compute-class.

כדי לראות את כל הצמתים שמשויכים ל-ComputeClass מסוים, מריצים את הפקודה הבאה:

kubectl get nodes -l cloud.google.com/compute-class=COMPUTECLASS_NAME

מחליפים את COMPUTECLASS_NAME בשם של ComputeClass (לדוגמה, cost-optimized).

הפלט אמור להיראות כך:

NAME                                                  STATUS   ROLES    AGE   VERSION
gke-cluster-1-cost-optimized-pool-f213e529-rx7d       Ready    <none>   5m    v1.32.4-gke.1236007
gke-cluster-1-cost-optimized-pool-f213e529-ab12       Ready    <none>   5m    v1.32.4-gke.1236007

כדי להציג את כל הצמתים באשכול שמשויכים ל-ComputeClass, מריצים את הפקודה הבאה:

kubectl get nodes -L cloud.google.com/compute-class

עדכון של ComputeClass פעיל

כדי לעדכן ComputeClass שנפרס, משנים את מניפסט ה-YAML של ה-ComputeClass. לאחר מכן, פורסים את המניפסט ששונה באמצעות הפקודה הבאה:

kubectl apply -f PATH_TO_FILE

מחליפים את PATH_TO_FILE בנתיב למניפסט ששיניתם. חשוב לוודא שהערך בשדה name לא משתנה.

כשפורסים את ה-ComputeClass המעודכן, GKE משתמש בהגדרות המעודכנות כדי ליצור צמתים חדשים. ‫GKE לא משנה צמתים קיימים בהתאם להגדרה המעודכנת.

עם הזמן, יכול להיות ש-GKE יעביר פודים קיימים לצמתים שמשתמשים בהגדרה המעודכנת, אם ה-ComputeClass משתמש בהעברה פעילה ואם הפודים הקיימים עומדים בדרישות להעברה.

המאמרים הבאים