הטמעה של מערכת לתור משימות עם שיתוף מכסות בין מרחבי שמות ב-GKE

במדריך הזה נשתמש ב-Kueue כדי להראות לכם איך להטמיע מערכת לתזמון משימות בתור, להגדיר שיתוף של משאבי עומס עבודה ומכסות בין מרחבי שמות שונים ב-Google Kubernetes Engine‏ (GKE), ולמקסם את השימוש באשכול.

רקע

מהנדסי תשתית ואדמינים של אשכולות צריכים להקפיד על ניצול מקסימלי של מרחבי שמות. יכול להיות שקבוצה של משימות במרחב שמות אחד לא תנצל את כל המכסה שהוקצתה למרחב השמות, בעוד שבמרחב שמות אחר יהיו כמה משימות בהמתנה. כדי להשתמש ביעילות במשאבי האשכול בין משימות במרחבי שמות שונים, וכדי להגדיל את הגמישות של ניהול המכסות, אפשר להגדיר קבוצות ב-Kueue. קבוצה בעלת מאפיינים משותפים היא קבוצה של תורים של אשכולות שיכולים להשתמש במכסת נפח אחסון שלא נעשה בה שימוש אחד מהשני. תור ClusterQueue שולט במאגר משאבים כמו מעבד (CPU), זיכרון ומאיצי חומרה.

הסבר מפורט יותר על כל המושגים האלה זמין במסמכי Kueue.

מטרות

המדריך הזה מיועד למהנדסי תשתית או לאדמינים של אשכולות שרוצים להטמיע מערכת להוספת משימות לתור ב-Kubernetes באמצעות Kueue עם שיתוף מכסות.

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

אפשר להשתמש ב-Prometheus operator כדי לעקוב אחרי משימות והקצאת משאבים במרחבי שמות שונים.

במדריך הזה מוסבר איך לבצע את השלבים הבאים:

  1. יצירת אשכול GKE
  2. יצירת ResourceFlavors
  3. לכל צוות, יוצרים ClusterQueue ו-LocalQueue
  4. יצירת משרות ומעקב אחרי עומסי העבודה שאושרו
  5. השאלה של מכסה שלא נעשה בה שימוש באמצעות קבוצות
  6. הוספת ClusterQueue לשליטה במכונות וירטואליות מסוג Spot

עלויות

במדריך הזה השתמשנו ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

השתמשו במחשבון עלויות כדי להעריך את העלויות בהתאם לשימוש הצפוי.

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

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

הגדרת הפרויקט

  1. נכנסים לחשבון Google Cloud . אנחנו ממליצים למשתמשים חדשים ב- Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to create a project

    To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the GKE API, if it is not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Roles required to create a project

    To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the GKE API, if it is not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

הגדרת ברירות מחדל ל-Google Cloud CLI

  1. במסוף Google Cloud , מפעילים מכונה של Cloud Shell:
    פותחים את Cloud Shell

  2. מורידים את קוד המקור של האפליקציה לדוגמה:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/batch/kueue-cohort
    
  3. מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

    מחליפים את הערכים הבאים:

יצירת אשכול GKE

  1. יוצרים אשכול GKE בשם kueue-cohort:

    תיצרו אשכול עם 6 צמתים (2 בכל אזור) במאגר ברירת המחדל, ללא שינוי גודל אוטומטי. אלה יהיו כל המשאבים הזמינים לקבוצות בהתחלה, ולכן הן יצטרכו להתחרות עליהם.

    בהמשך נראה איך Kueue מנהל את עומסי העבודה ששני הצוותים ישלחו לתורים המתאימים.

    ‫
      gcloud container clusters create kueue-cohort --location COMPUTE_REGION \
      --release-channel rapid --machine-type e2-standard-4 --num-nodes 2
    

    אחרי שיוצרים את האשכול, התוצאה אמורה להיראות כך:

      kubeconfig entry generated for kueue-cohort.
      NAME: kueue-cohort
      LOCATION: us-central1
      MASTER_VERSION: 1.26.2-gke.1000
      MASTER_IP: 35.224.108.58
      MACHINE_TYPE: e2-medium
      NODE_VERSION: 1.26.2-gke.1000
      NUM_NODES: 6
      STATUS: RUNNING
    

    כאשר STATUS הוא RUNNING עבור kueue-cluster.

  2. יוצרים מאגר צמתים בשם spot.

    מאגר הצמתים הזה משתמש ב-VM במודל Spot והתכונה 'שינוי גודל אוטומטי' מופעלת בו. בהתחלה יש בו 0 צמתים, אבל בהמשך תהפכו אותו לזמין לצוותים לשימוש כקיבולת עודפת.

    gcloud container node-pools create spot --cluster=kueue-cohort --location COMPUTE_REGION  \
    --spot --enable-autoscaling --max-nodes 20 --num-nodes 0 \
    --machine-type e2-standard-4
    
  3. מתקינים את גרסת ההפצה של Kueue באשכול:

    VERSION=VERSION
    kubectl apply -f \
      https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    

    מחליפים את VERSION באות v אחרי הגרסה האחרונה של Kueue, לדוגמה v0.4.0. מידע נוסף על גרסאות Kueue זמין במאמר Kueue releases.

    מחכים עד שהבקר Kueue יהיה מוכן:

    watch kubectl -n kueue-system get pods
    

    הפלט שאתם מקבלים אמור להיראות כך:

    NAME                                        READY   STATUS    RESTARTS   AGE
    kueue-controller-manager-6cfcbb5dc5-rsf8k   2/2     Running   0          3m
    
  4. יוצרים שני מרחבי שמות חדשים בשם team-a ו-team-b:

    kubectl create namespace team-a
    kubectl create namespace team-b
    

    המשרות ייווצרו בכל מרחב שמות.

יצירת ResourceFlavors

‫ResourceFlavor מייצג וריאציות של משאבים בצמתי האשכול, כמו מכונות וירטואליות שונות (למשל, מכונות וירטואליות מסוג Spot לעומת מכונות וירטואליות לפי דרישה), ארכיטקטורות (למשל, מעבדי x86 לעומת מעבדי ARM), מותגים ודגמים (למשל, מעבדי Nvidia A100 לעומת מעבדי T4 GPU).

המשאבים ResourceFlavors משתמשים בתוויות צמתים ובכתמים כדי להתאים לקבוצת צמתים באשכול.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: on-demand # This ResourceFlavor will be used for the CPU resource
spec:
  nodeLabels:
    cloud.google.com/gke-provisioning: standard # This label was applied automatically by GKE
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: spot # This ResourceFlavor will be used as added resource for the CPU resource
spec:
  nodeLabels:  
    cloud.google.com/gke-provisioning: spot # This label was applied automatically by GKE

במניפסט הזה:

  • התווית של ResourceFlavor on-demand מוגדרת כ-cloud.google.com/gke-provisioning: standard.
  • התווית של ResourceFlavor spot מוגדרת כ-cloud.google.com/gke-provisioning: spot.

כשמקצים ResourceFlavor לעומס עבודה, Kueue מקצה את ה-Pods של עומס העבודה לצמתים שתואמים לתוויות הצמתים שהוגדרו ל-ResourceFlavor.

פורסים את ResourceFlavor:

kubectl apply -f flavors.yaml

יצירת ClusterQueue ו-LocalQueue

יוצרים שתי ClusterQueues‏, cq-team-a ו-cq-team-b, ואת LocalQueues התואמות שלהן, lq-team-a ו-lq-team-b, בהתאמה, עם מרחבי שמות team-a ו-team-b.

תורי ClusterQueue הם אובייקטים בהיקף האשכול שמנהלים מאגר משאבים כמו מעבד (CPU), זיכרון ומאיצי חומרה. אדמינים של קבוצות יכולים להגביל את הנראות של האובייקטים האלה למשתמשים בקבוצה.

תורים מקומיים הם אובייקטים עם מרחב שמות שמשתמשים יכולים לראות את הרשימה שלהם. הם מצביעים על CluterQueues, שמתוכם מוקצים משאבים להרצת עומסי העבודה של LocalQueue.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: cq-team-a
spec:
  cohort: all-teams # cq-team-a and cq-team-b share the same cohort
  namespaceSelector:
    matchLabels:
      kubernetes.io/metadata.name: team-a #Only team-a can submit jobs direclty to this queue, but will be able to share it through the cohort
  resourceGroups:
  - coveredResources: ["cpu", "memory"]
    flavors:
    - name: on-demand
      resources:
      - name: "cpu"
        nominalQuota: 10
        borrowingLimit: 5
      - name: "memory"
        nominalQuota: 10Gi
        borrowingLimit: 15Gi
    - name: spot # This ClusterQueue doesn't have nominalQuota for spot, but it can borrow from others
      resources:
      - name: "cpu"
        nominalQuota: 0
      - name: "memory"
        nominalQuota: 0
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: team-a # LocalQueue under team-a namespace
  name: lq-team-a
spec:
  clusterQueue: cq-team-a # Point to the ClusterQueue team-a-cq

התכונה ClusterQueues מאפשרת להגדיר כמה סוגים של משאבים. במקרה הזה, לשני התורים ClusterQueue יש שני סוגים, on-demand ו-spot, וכל אחד מהם מספק cpu משאבים. המכסה של ResourceFlavor spot מוגדרת כ-0, ולא ייעשה בה שימוש כרגע.

שני התורים ClusterQueue חולקים את אותה קבוצה בעלת מאפיינים משותפים שנקראת all-teams, שמוגדרת ב-.spec.cohort. אם שתי ClusterQueues או יותר חולקות את אותה קבוצת משתמשים, הן יכולות להשתמש במכסת השימוש שלא נוצלה של כל אחת מהן.

בתיעוד של Kueue יש מידע נוסף על אופן הפעולה של קבוצות ועל הסמנטיקה של השאלה.

פריסת ClusterQueues ו-LocalQueues:

kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml

(אופציונלי) מעקב אחר עומסי עבודה באמצעות kube-prometheus

אתם יכולים להשתמש ב-Prometheus כדי לעקוב אחרי עומסי העבודה הפעילים והממתינים של Kueue. כדי לעקוב אחרי עומסי העבודה שמועלים ולבחון את העומס בכל ClusterQueue, צריך לפרוס את kube-prometheus באשכול בשטח השמות monitoring:

  1. מורידים את קוד המקור של Prometheus operator:

    cd
    git clone https://github.com/prometheus-operator/kube-prometheus.git
    
  2. יוצרים את CustomResourceDefinitions‏(CRD):

    kubectl create -f kube-prometheus/manifests/setup
    
  3. יוצרים את רכיבי המעקב:

    kubectl create -f kube-prometheus/manifests
    
  4. מאפשרים ל-prometheus-operator לגרד מדדים מרכיבי Kueue:

    kubectl apply -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/prometheus.yaml
    
  5. עוברים לספריית העבודה:

    cd kubernetes-engine-samples/batch/kueue-cohort
    
  6. מגדירים העברה ליציאה אחרת לשירות Prometheus שפועל באשכול GKE:

    kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
    
  7. פותחים את ממשק האינטרנט של Prometheus בכתובת localhost:9090 בדפדפן.

    ב-Cloud Shell:

    1. לוחצים על תצוגה מקדימה באינטרנט.

    2. לוחצים על שינוי יציאה ומגדירים את מספר היציאה ל-9090.

    3. לוחצים על שינוי ותצוגה מקדימה.

    מוצג ממשק האינטרנט הבא של Prometheus.

    צילום מסך של ממשק המשתמש של Prometheus בדפדפן

  8. בתיבת השאילתה Expression, מזינים את השאילתה הבאה כדי ליצור את החלונית הראשונה שבה מוצגים עומסי העבודה הפעילים עבור cq-team-a ClusterQueue:

    kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
    
  9. לוחצים על הוספת חלונית.

  10. בתיבת השאילתה Expression, מזינים את השאילתה הבאה כדי ליצור חלונית נוספת למעקב אחרי עומסי העבודה הפעילים עבור cq-team-b ClusterQueue:

    kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
    
  11. לוחצים על הוספת חלונית.

  12. בתיבת השאילתה Expression, מזינים את השאילתה הבאה כדי ליצור חלונית למעקב אחרי מספר הצמתים באשכול:

    count(kube_node_info)
    

(אופציונלי) מעקב אחרי עומסי עבודה באמצעות השירות המנוהל של Google Cloud ל-Prometheus

אתם יכולים להשתמש בשירות המנוהל של Google Cloud ל-Prometheus כדי לעקוב אחרי עומסי העבודה הפעילים והממתינים של Kueue. רשימה מלאה של מדדים זמינה במאמרי העזרה של Kueue.

  1. הגדרת זהות ו-RBAC לגישה למדדים:

    ההגדרה הבאה יוצרת 4 משאבי Kubernetes, שמספקים גישה למדדים עבור האוספים של השירות המנוהל של Google Cloud ל-Prometheus.

    • חשבון שירות בשם kueue-metrics-reader במרחב השמות kueue-system ישמש לאימות כשניגשים למדדים של Kueue.

    • ‫Secret שמשויך לחשבון השירות kueue-metrics-reader, מאחסן אסימון אימות שמשמש את האוסף לאימות בנקודת הקצה של המדדים שנחשפת על ידי הפריסה של Kueue.

    • תפקיד בשם kueue-secret-reader במרחב השמות kueue-system, שמאפשר לקרוא את הסוד שמכיל את אסימון חשבון השירות.

    • ‫ClusterRoleBinding שמעניק לחשבון השירות kueue-metrics-reader את ה-ClusterRole kueue-metrics-reader.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: kueue-metrics-reader
     namespace: kueue-system
    ---
    apiVersion: v1
    kind: Secret
    metadata:
     name: kueue-metrics-reader-token
     namespace: kueue-system
     annotations:
       kubernetes.io/service-account.name: kueue-metrics-reader
    type: kubernetes.io/service-account-token
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
     name: kueue-secret-reader
     namespace: kueue-system
    rules:
    -   resources:
     -   secrets
     apiGroups: [""]
     verbs: ["get", "list", "watch"]
     resourceNames: ["kueue-metrics-reader-token"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
     name: kueue-metrics-reader
    subjects:
    -   kind: ServiceAccount
     name: kueue-metrics-reader
     namespace: kueue-system
    roleRef:
     kind: ClusterRole
     name: kueue-metrics-reader
     apiGroup: rbac.authorization.k8s.io
    
  2. מגדירים RoleBinding בשירות המנוהל של Google Cloud ל-Prometheus:

    בהתאם לסוג האשכול שבו אתם משתמשים (Autopilot או Standard), תצטרכו ליצור את RoleBinding במרחב השמות gke-gmp-system או gmp-system. המשאב הזה מאפשר לחשבון השירות של שירות האיסוף לגשת לסוד kueue-metrics-reader-token כדי לבצע אימות ולגרד את מדדי Kueue.

    טייס אוטומטי

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: gmp-system:collector:kueue-secret-reader
        namespace: kueue-system
      roleRef:
        name: kueue-secret-reader
        kind: Role
        apiGroup: rbac.authorization.k8s.io
      subjects:
      -   name: collector
        namespace: gke-gmp-system
        kind: ServiceAccount
    

    רגילה

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: gmp-system:collector:kueue-secret-reader
        namespace: kueue-system
      roleRef:
        name: kueue-secret-reader
        kind: Role
        apiGroup: rbac.authorization.k8s.io
      subjects:
      -   name: collector
        namespace: gmp-system
        kind: ServiceAccount
    
  3. מגדירים את המשאב Pod Monitoring:

    המשאב הבא מגדיר את המעקב אחר הפריסה של Kueue. הוא מציין שהמדדים נחשפים בנתיב ‎ /metrics באמצעות HTTPS. הוא משתמש בסוד kueue-metrics-reader-token לאימות בזמן גירוד המדדים.

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
    name: kueue
    namespace: kueue-system
    spec:
    selector:
     matchLabels:
       control-plane: controller-manager
    endpoints:
    -   port: 8443
     interval: 30s
     path: /metrics
     scheme: https
     tls:
       insecureSkipVerify: true
     authorization:
       type: Bearer
       credentials:
         secret:
           name: kueue-metrics-reader-token
           key: token
    

ייצוא מדדים של שאילתות

דוגמאות לשאילתות ב-PromQL לניטור מערכות שמבוססות על Kueue

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

תפוקת משרות

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

שאילתה

sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)

ניצול משאבים

ההנחה היא שmetrics.enableClusterQueueResources מופעל. הוא מחשב את היחס בין השימוש הנוכחי במעבד לבין מכסת המעבד הנומינלית לכל תור. ערך שקרוב ל-1 מציין ניצול גבוה. אפשר לשנות את תווית המשאב כדי להתאים את הפקודה לזיכרון או למשאבים אחרים.

כדי להתקין באשכול גרסה שפורסמה של Kueue עם הגדרה בהתאמה אישית, פועלים לפי ההוראות במאמר בנושא Kueue.

שאילתה

sum(kueue_cluster_queue_resource_usage{resource="cpu"}) by (cluster_queue) / sum(kueue_cluster_queue_nominal_quota{resource="cpu"}) by (cluster_queue)

זמני המתנה בתור

המדד הזה מספק את זמן ההמתנה באחוזון ה-90 לעומסי עבודה בתור ספציפי. אפשר לשנות את ערך הכמותון (למשל 0.5 לחציון, 0.99 לאחוזון ה-99) כדי להבין את התפלגות זמני ההמתנה.

שאילתה

histogram_quantile(0.9, kueue_admission_wait_time_seconds_bucket{cluster_queue="QUEUE_NAME"})

יצירת משרות ומעקב אחרי עומסי העבודה שאושרו

בקטע הזה, יוצרים משימות Kubernetes במרחבי השמות team-a ו-team-b. ב-Kubernetes, בקר משימות יוצר פוד אחד או יותר ועוזר לוודא שהם מבצעים בהצלחה משימה ספציפית.

יצירת משימות לשני התורים של ClusterQueue שימתינו למשך 10 שניות, עם שלוש משימות מקבילות שיושלמו עם שלוש השלמות. הנתונים יימחקו אחרי 60 שניות.

apiVersion: batch/v1
kind: Job
metadata:
  namespace: team-a # Job under team-a namespace
  generateName: sample-job-team-a-
  labels:
    kueue.x-k8s.io/queue-name: lq-team-a # Point to the LocalQueue
spec:
  ttlSecondsAfterFinished: 60 # Job will be deleted after 60 seconds
  parallelism: 3 # This Job will have 3 replicas running at the same time
  completions: 3 # This Job requires 3 completions
  suspend: true # Set to true to allow Kueue to control the Job when it starts
  template:
    spec:
      containers:
      - name: dummy-job
        image: gcr.io/k8s-staging-perf-tests/sleep:latest
        args: ["10s"] # Sleep for 10 seconds
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
      restartPolicy: Never

‫job-team-a.yaml יוצרת משימות תחת מרחב השמות team-a ומפנה אל LocalQueue lq-team-a ו-ClusterQueue cq-team-a.

באופן דומה, הפקודה job-team-b.yaml יוצרת עבודות במרחב השמות team-b, ומפנה אל LocalQueue lq-team-b ו-ClusterQueue cq-team-b.

  1. פותחים טרמינל חדש ועוברים לספרייה kueue-cohort:

    cd ~/kubernetes-engine-samples/batch/kueue-cohort
    
  2. כדי ליצור משימה כל שנייה, מריצים את הסקריפט הבא:

    ./create_jobs.sh job-team-a.yaml 1
    
  3. מפעילים מסוף נוסף ומנווטים לספרייה kueue-cohort:

    cd ~/kubernetes-engine-samples/batch/kueue-cohort
    
  4. יוצרים משימות למרחב השמות team-b:

    ./create_jobs.sh job-team-b.yaml 1
    
  5. צופים בעבודות שמתווספות לתור ב-Prometheus. או באמצעות הפקודה הזו:

    watch -n 2 kubectl get clusterqueues -o wide
    

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

    NAME        COHORT      STRATEGY         PENDING WORKLOADS   ADMITTED WORKLOADS
    cq-team-a   all-teams   BestEffortFIFO   0                   5
    cq-team-b   all-teams   BestEffortFIFO   0                   4

שימוש במכסה לא מנוצלת באמצעות קבוצות

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

  1. אחרי שיהיו משימות בתור בשני התורים של ClusterQueues cq-team-a ו-cq-team-b, צריך להפסיק את הסקריפט של מרחב השמות team-b על ידי לחיצה על CTRL+c במסוף המתאים.

  2. אחרי שכל העבודות בהמתנה ממרחב השמות team-b יעברו עיבוד, העבודות ממרחב השמות team-a יוכלו להשתמש במשאבים הזמינים ב-cq-team-b:

    kubectl describe clusterqueue cq-team-a
    

    כי cq-team-a ו-cq-team-b חולקים את אותה קבוצת משתמשים שנקראת all-teams, התורים האלה של ClusterQueue יכולים לחלוק משאבים שלא נעשה בהם שימוש.

      Flavors Usage:
        Name:  on-demand
        Resources:
          Borrowed:  5
          Name:      cpu
          Total:     15
          Borrowed:  5Gi
          Name:      memory
          Total:     15Gi
    
  3. ממשיכים את הסקריפט עבור מרחב השמות team-b.

    ./create_jobs.sh job-team-b.yaml 3
    

    שימו לב איך המשאבים שהושאלו מ-cq-team-a חוזרים ל-0, בזמן שהמשאבים מ-cq-team-b משמשים לעומסי העבודה שלו:

    kubectl describe clusterqueue cq-team-a
    
      Flavors Usage:
        Name:  on-demand
        Resources:
          Borrowed:  0
          Name:      cpu
          Total:     9
          Borrowed:  0
          Name:      memory
          Total:     9Gi
    

הגדלת המכסה באמצעות מכונות וירטואליות מסוג Spot

כשצריך להגדיל את המכסה באופן זמני, למשל כדי לעמוד בביקוש גבוה בעומסי עבודה בהמתנה, אפשר להגדיר את Kueue כך שיתאים לביקוש על ידי הוספת עוד ClusterQueues לקוהורט. תורי ClusterQueue עם משאבים לא בשימוש יכולים לשתף את המשאבים האלה עם תורי ClusterQueue אחרים ששייכים לאותה קבוצה.

בתחילת המדריך יצרתם מאגר צמתים בשם spot באמצעות מכונות וירטואליות מסוג Spot ו-ResourceFlavor בשם spot עם התווית cloud.google.com/gke-provisioning: spot. יוצרים ClusterQueue כדי להשתמש במאגר הצמתים הזה וב-ResourceFlavor שמייצג אותו:

  1. יוצרים ClusterQueue חדש בשם cq-spot עם קבוצת cohort שמוגדרת ל-all-teams:

    apiVersion: kueue.x-k8s.io/v1beta1
    kind: ClusterQueue
    metadata:
      name: spot-cq
    spec:
      cohort: all-teams # Same cohort as cq-team-a and cq-team-b
      resourceGroups:
      - coveredResources: ["cpu", "memory"]
        flavors:
        - name: spot
          resources:
          - name: "cpu"
            nominalQuota: 40
          - name: "memory"
            nominalQuota: 144Gi

    מכיוון שהתור ClusterQueue הזה משתייך לאותה קבוצת משתמשים עם cq-team-a ועם cq-team-b, גם ClusterQueue cq-team-a וגם cq-team-b יכולים לשאול משאבים עד 15 בקשות למעבד ו-15 גיגה-בייט של זיכרון.

    cd ~/kubernetes-engine-samples/batch/kueue-cohort
    kubectl apply -f cq-spot.yaml
    
  2. ב-Prometheus, אפשר לראות את העלייה בעומסי העבודה שאושרו עבור cq-team-a וגם cq-team-b, בזכות המכסה שנוספה על ידי cq-spot שמשתף את אותה קבוצת משתמשים. או באמצעות הפקודה הזו:

    watch -n 2 kubectl get clusterqueues -o wide
    
  3. ב-Prometheus, צופים במספר הצמתים באשכול. או באמצעות הפקודה הזו:

    watch -n 2 kubectl get nodes -o wide
    
  4. כדי לעצור את שני הסקריפטים, מקישים על CTRL+c עבור מרחב השמות team-a ו-team-b.

הסרת המשאבים

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

מחיקת הפרויקט

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת המשאב הספציפי

  1. מוחקים את מערכת המכסות של Kueue:

    kubectl delete -n team-a localqueue lq-team-a
    kubectl delete -n team-b localqueue lq-team-b
    kubectl delete clusterqueue cq-team-a
    kubectl delete clusterqueue cq-team-b
    kubectl delete clusterqueue cq-spot
    kubectl delete resourceflavor default
    kubectl delete resourceflavor on-demand
    kubectl delete resourceflavor spot
    
  2. מוחקים את מניפסט Kueue:

    VERSION=VERSION
    kubectl delete -f \
      https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    
  3. מחיקת האשכול:

    gcloud container clusters delete kueue-cohort --location=COMPUTE_REGION
    

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