תזמון עומסי עבודה ב-GKE באמצעות TAS

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

במאמר הזה מוסבר איך לבצע אופטימיזציה לתזמון של עומסי עבודה גדולים של AI או ML באשכול Google Kubernetes Engine ‏ (GKE), כדי לשפר את הביצועים והמהימנות. באופן ספציפי, אתם מגדירים את האשכול כך שישתמש בתזמון מודע לטופולוגיה (TAS) כדי לאפשר תקשורת עם השהיה נמוכה. הגישה הזו מצמצמת את התקורה של התקשורת ועוזרת למקסם את הביצועים של עומסי העבודה.

מהו תזמון מודעות בהתאם לטופולוגיה (TAS)?

TAS יכול לשפר באופן משמעותי את היעילות של אימון מודלים גדולים של שפה (LLM). ‫TAS ממקם עובדים באופן אסטרטגי בטופולוגיית הרשת כדי למזער את התקורה של התקשורת במהלך צבירת הגרדיאנט, שדורשת תקשורת בין העובדים בסדר דירוג ספציפי. על ידי צמצום מספר הצעדים ברשת בין תהליכי Worker שמתקשרים ברצף, TAS מפחיתה את התחרות על משאבי הרשת ומבצעת אופטימיזציה של השימוש ברוחב הפס, וכך משיגה התכנסות מהירה יותר וזמני אימון קצרים יותר. ככל שמודלי ה-LLM גדלים, TAS הופך לחיוני למיקסום הביצועים והמדרגיות של אימון מבוזר.

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

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

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

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

    gcloud container clusters get-credentials CLUSTER_NAME
    

    מחליפים את CLUSTER_NAME בשם האשכול.

הכנת אשכול GKE

כדי להכין את אשכול GKE להרצת עומסי עבודה עם TAS, פועלים לפי השלבים הבאים:

  1. התקנת Kueue עם TAS מופעל
  2. איך צופים בטופולוגיה של אשכול GKE

  3. הגדרת Kueue

התקנת Kueue עם TAS מופעל

מומלץ להשתמש ב-TAS עם Kueue, מערכת מבוססת-Kubernetes שמנהלת את המכסות ואת האופן שבו המשימות צורכות אותן. כדי להשתמש ב-TAS, צריך גרסה 0.10.0 ואילך של Kueue, וצריך להפעיל אותו באופן מפורש.

כדי להתקין את Kueue ולהפעיל את TAS, בוחרים באחת מהאפשרויות הבאות:

מניפסט Kueue

  1. מתקינים את Kueue:

    kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.0/manifests.yaml
    
  2. מפעילים את TAS ב-Kueue:

    kubectl -n kueue-system patch deployment kueue-controller-manager \
        --type json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=TopologyAwareScheduling=true"}]'
    

תרשים Helm

כדי להתקין את Kueue עם TAS מופעל באמצעות תרשים Helm:

helm install kueue oci://us-central1-docker.pkg.dev/k8s-staging-images/charts/kueue \
    --version="v0.10.0" \
    --create-namespace \
    --namespace=kueue-system \
    --set="controllerManager.featureGates[0].name=TopologyAwareScheduling,controllerManager.featureGates[0].enabled=true"

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

הצגת הטופולוגיה של אשכול GKE

לפני שצופים בטופולוגיה של צמתי A4X,‏ A4,‏ A3 Ultra,‏ A3 Mega ו-A3 High (עם 8 יחידות GPU) שהוקצו כמכונות וירטואליות מסוג Spot, צריך להגדיר מיקום קומפקטי בצמתי GKE כדי לחשוף את הטופולוגיה הפיזית שלהם ל-TAS. אחרת, תקבלו שגיאות.

כדי לראות את הטופולוגיה של הצמתים באשכול GKE במאגר צמתים ספציפי, מריצים את הפקודה הבאה:

kubectl get nodes -l cloud.google.com/gke-nodepool=NODE_POOL_NAME \
    -ocustom-columns='NAME:.metadata.name,BLOCK:.metadata.labels.cloud\.google\.com/gce-topology-block,SUBBLOCK:.metadata.labels.cloud\.google\.com/gce-topology-subblock,HOST:.metadata.labels.cloud\.google\.com/gce-topology-host' | sort -k2,4

מחליפים את NODE_POOL_NAME בשם של מאגר הצמתים.

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

  • cloud.google.com/gce-topology-block: המזהה הספציפי לארגון של הבלוק השמור שבו נמצאת המכונה הווירטואלית.

  • cloud.google.com/gce-topology-subblock: המזהה הספציפי לארגון של תת-הבלוק שבו נמצאת המכונה הווירטואלית.

  • cloud.google.com/gce-topology-host: המזהה של המארח שבו נמצאת המכונה הווירטואלית.

  • kubernetes.io/hostname: שם המארח של צומת Kubernetes. שם המארח הזה הוא בדרך כלל גם שם הצומת ב-GKE.

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

הגדרת Kueue

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

  • עומסי עבודה של TAS: ‏ Kueue בודק את הטופולוגיה של התשתית הפיזית ואת השימוש הנוכחי בה.

  • עומסי עבודה שאינם TAS: ‏ Kueue לא בודק את הטופולוגיה של התשתית הפיזית. מערכת Kueue מנהלת את כל המכסה שמוגדרת בקובץ ההגדרות, ומקצה את הצמתים ל-kube-scheduler.

כדי להבין איך מספקים הגדרה של מכסת משאבים מסוג ClusterQueue ל-Kueue, כדאי לעיין בדוגמאות הבאות:

  • מכסת משאבים גבוהה מאוד: Kueue כמעט אף פעם לא מפסיק את ההרשאה של עומס עבודה על סמך המשאבים המבוקשים. בהתאם להגדרות של TAS, יכול להיות ש-Kueue יאשר או לא יאשר עומסי עבודה על סמך טופולוגיית התשתית. מידע נוסף מופיע במאמר בנושא מכסת משאבים גבוהה מאוד.

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

כל ההפניות למכסת משאבים בקטעים הבאים מתייחסות למכסת משאבים של ClusterQueue.

מכסת משאבים גבוהה מאוד

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

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

  1. פותחים כלי לעריכת קבצים לבחירתכם. לאחר מכן, כוללים את הגדרת המכסה הבאה בקובץ YAML בשם kueue-tas-config-very-high-quota.yaml:

      apiVersion: kueue.x-k8s.io/v1alpha1
      kind: Topology
      metadata:
        name: "gke-default"
      spec:
        levels:
        - nodeLabel: "cloud.google.com/gce-topology-block"
        - nodeLabel: "cloud.google.com/gce-topology-subblock"
        - nodeLabel: "cloud.google.com/gce-topology-host"
        - nodeLabel: "kubernetes.io/hostname"
    ---
      kind: ResourceFlavor
      apiVersion: kueue.x-k8s.io/v1beta1
      metadata:
        name: "tas-flavor"
      spec:
        nodeLabels:
          cloud.google.com/gke-nodepool: "NODE_POOL_NAME"
        topologyName: "gke-default"
        tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: NoSchedule
    ---
      apiVersion: kueue.x-k8s.io/v1beta1
      kind: ClusterQueue
      metadata:
        name: "tas-cluster-queue"
      spec:
        namespaceSelector: {}
        resourceGroups:
        - coveredResources: ["nvidia.com/gpu"]
          flavors:
          - name: "tas-flavor"
            resources:
            - name: "nvidia.com/gpu"
              nominalQuota: 10000000
    ---
      apiVersion: kueue.x-k8s.io/v1beta1
      kind: LocalQueue
      metadata:
        namespace: "default"
        name: "tas-user-queue"
      spec:
        clusterQueue: "tas-cluster-queue"
    

    מחליפים את NODE_POOL_NAME בשם של מאגר הצמתים.

  2. יוצרים ומחילים את הגדרת מכסת המשאבים עבור מערכת התורים של Kueue:

    kubectl create -f kueue-tas-config-very-high-quota.yaml
    

מכסת משאבים ריאלית

בדוגמה הקודמת הוגדרו רק משאבי GPU. עם זאת, Kueue יכול לנהל את כל המשאבים שתואמים ל-Kubernetes.

בדוגמה הבאה מוגדרת מכסת משאבים מציאותית יותר, כולל מעבד (CPU), זיכרון ו-GPU. ההוראות האלה מיועדות ל-100 מכשירי a3-ultragpu-8g. למכונה אחת יש 224 vCPU, ‏ 2, 944GB של זיכרון ו-8 יחידות GPU. אותו עיקרון חל על סוגי מכונות של GPU כללי, באמצעות המפרטים המתאימים של יחידת העיבוד המרכזית (CPU) והזיכרון.

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

  1. פותחים כלי לעריכת קבצים לבחירתכם. לאחר מכן, כוללים את הגדרת המכסה הבאה בקובץ YAML בשם kueue-tas-config-real-quota.yaml:

      apiVersion: kueue.x-k8s.io/v1alpha1
      kind: Topology
      metadata:
        name: "gke-default"
      spec:
        levels:
        - nodeLabel: "cloud.google.com/gce-topology-block"
        - nodeLabel: "cloud.google.com/gce-topology-subblock"
        - nodeLabel: "cloud.google.com/gce-topology-host"
        - nodeLabel: "kubernetes.io/hostname"
    ---
      kind: ResourceFlavor
      apiVersion: kueue.x-k8s.io/v1beta1
      metadata:
        name: "tas-flavor"
      spec:
        nodeLabels:
          cloud.google.com/gke-nodepool: "NODE_POOL_NAME"
        topologyName: "gke-default"
        tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: NoSchedule
    ---
      apiVersion: kueue.x-k8s.io/v1beta1
      kind: ClusterQueue
      metadata:
        name: "tas-cluster-queue"
      spec:
        namespaceSelector: {} # match all
        resourceGroups:
        - coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
          flavors:
          - name: "tas-flavor"
            resources:
            # numbers below represent quota of 100 a3-ultragpu-8g machines
            - name: "cpu"
              nominalQuota: 22400
            - name: "memory"
              nominalQuota: 294400Gi
            - name: "nvidia.com/gpu"
              nominalQuota: 800
    ---
      apiVersion: kueue.x-k8s.io/v1beta1
      kind: LocalQueue
      metadata:
        namespace: "default"
        name: "tas-user-queue"
      spec:
        clusterQueue: "tas-cluster-queue"
    

    מחליפים את NODE_POOL_NAME בשם של מאגר הצמתים.

  2. יצירה והחלה של הגדרת מכסת משאבים עבור מערכת התורים של Kueue:

    kubectl create -f kueue-tas-config-real-quota.yaml
    

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

    topology.kueue.x-k8s.io/gke-default created
    resourceflavor.kueue.x-k8s.io/tas-flavor created
    clusterqueue.kueue.x-k8s.io/tas-cluster-queue created
    localqueue.kueue.x-k8s.io/tas-user-queue created
    

תזמון עומסי עבודה באמצעות TAS עם Kueue

בתרחישים הבאים מוצגות דוגמאות לאופן שבו אפשר להנחות את Kueue ואת TAS לנהל שילובים נפוצים של עומסי עבודה ותשתית באמצעות סוגים ורמות של בקשות טופולוגיה:

  • אלה הסוגים הזמינים של בקשות טופולוגיה (מומלץ או נדרש):

    • kueue.x-k8s.io/podset-preferred-topology: Kueue נותן עדיפות לתזמון של כל עומס העבודה ברמה נתונה של טופולוגיה, אבל עדיין מאשר עומס עבודה שלא מתאים לרמה הזו של הטופולוגיה. אם עומס עבודה יכול להתאים לרמה אחת של טופולוגיה, יכול להיות ש-Kueue יתזמן את עומס העבודה הזה בכמה מופעים של אותה רמה של טופולוגיה.

    • kueue.x-k8s.io/podset-required-topology: מערכת Kueue ממשיכה לנסות לאשר את עומס העבודה הזה עד שכל עומס העבודה יכול להתאים לרמת הטופולוגיה שנבחרה.

  • אלה הרמות הזמינות של בקשות טופולוגיה, שמאפשרות לכם להיות ספציפיים יותר או פחות לגבי התשתית הפיזית שבה אתם מעדיפים או צריכים להריץ את העבודה:

    • cloud.google.com/gce-topology-block

    • cloud.google.com/gce-topology-subblock

    • cloud.google.com/gce-topology-host

    • kubernetes.io/hostname

כדי לתזמן עומסי עבודה באמצעות הערכים האלה, משתמשים בקובץ ה-YAML הבא של Job:

apiVersion: batch/v1
kind: Job
metadata:
  generateName: JOB_NAME
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
spec:
  parallelism: NUMBER_OF_REPLICAS
  completions: NUMBER_OF_REPLICAS
  completionMode: Indexed
  template:
    metadata:
      annotations:
        ANNOTATIONS_STRING
    spec:
      containers:
      - name: dummy-job
        image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
        args: ["60s"]
        resources:
          requests:
            nvidia.com/gpu: "1"
          limits:
            nvidia.com/gpu: "1"
      restartPolicy: Never

מחליפים את המשתנים הבאים:

  • JOB_NAME: שם למשימה.

  • NUMBER_OF_REPLICAS: מספר ה-Pods שפועלים במקביל.

  • ANNOTATIONS_STRING: אפשר להיעזר בטבלה הבאה:

    סוג ורמה של טופולוגיה מבוקשת תיאור ANNOTATIONS_STRING
    מומלץ להריץ את הכלי בתוך שם מארח ההגדרה הזו תאפשר לעומס העבודה לפעול כל עוד יש מספיק משאבים זמינים כדי לעמוד בדרישות המשאבים של עומס העבודה, גם אם הקיבולת מפוצלת. מערכת Kueue תתזמן את ה-Pods בצורה קומפקטית ככל האפשר. kueue.x-k8s.io/podset-preferred-topology: "kubernetes.io/hostname"
    נדרש להפעלה בתוך מארח

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

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

    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-host"
    מועדף להפעלה בתוך מארח ההגדרה הזו תאפשר לעומס העבודה לפעול כל עוד יש מספיק משאבים זמינים כדי לעמוד בדרישות המשאבים של עומס העבודה, גם אם הקיבולת מפוצלת. מערכת Kueue תנסה לתזמן את ה-Pods שלכם בתוך מארח, ותשתמש במארחים נוספים אם יהיה צורך בכך. kueue.x-k8s.io/podset-preferred-topology: "cloud.google.com/gce-topology-host"
    נדרש להפעלה בתוך קבוצת משנה ההגדרה הזו תאפשר לעומס העבודה לפעול רק אם יש בלוק משנה עם מספיק משאבים כדי לענות על דרישות המשאבים של עומס העבודה. kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-subblock"
    מועדף להפעלה בתוך בלוק משנה ההגדרה הזו תאפשר לעומס העבודה לפעול כל עוד יש מספיק משאבים זמינים כדי לעמוד בדרישות המשאבים של עומס העבודה, גם אם הקיבולת מפוצלת. מערכת Kueue תנסה לתזמן את ה-Pods שלכם בתוך בלוק משנה, ותשתמש בבלוקי משנה נוספים אם יהיה צורך. במקרה כזה, Kueue ידרג גבוה יותר תת-בלוק עם קיבולת זמינה גדולה יותר, גם אם הוא מפוצל, לעומת תת-בלוק עם קיבולת שמספיקה בדיוק לדרישות. kueue.x-k8s.io/podset-preferred-topology: "cloud.google.com/gce-topology-subblock"
    חובה להפעיל את הפעולה בתוך בלוק ההגדרה הזו תאפשר לעומס העבודה לפעול אם ורק אם המשאבים שזמינים בבלוק עומדים בדרישות המשאבים של עומס העבודה. אם העבודה תתקבל, Kueue יצמצם את מספר בלוקי המשנה והמארחים כדי לתזמן את העבודה. הדבר עלול לגרום לפיצול של הקיבולת הזמינה. kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
    מומלץ להריץ בתוך בלוק ההגדרה הזו תאפשר לעומס העבודה לפעול כל עוד יש מספיק משאבים זמינים כדי לעמוד בדרישות המשאבים של עומס העבודה, גם אם הקיבולת מפוצלת. מערכת Kueue תנסה לתזמן את ה-Pods שלכם בתוך בלוק, ותשתמש בבלוקים נוספים אם יהיה צורך בכך. kueue.x-k8s.io/podset-preferred-topology: "cloud.google.com/gce-topology-block"

תזמון עומסי עבודה באמצעות PodGroup עם TAS באמצעות Kueue

כשמשתמשים ב-PodGroups, צריך לציין שלושה שדות נוספים לכל Pod ב-PodGroup:

בהתאם למסגרת ה-ML שבה אתם משתמשים, יכול להיות שיהיה צורך ב-GPU לראש של PodGroup, ויכול להיות שלא. בגלל מגבלה ב-Kueue, צריך לטפל במקרים האלה בצורה שונה. בדוגמאות הבאות מוסבר איך ליצור PodGroup של שלושה פודים עם פוד אחד ראשי ושני פודי עובדים.

מקרה 1: המנהל הוא גם עובד ונדרש לו GPU

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

apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-leader-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group"
    kueue.x-k8s.io/pod-group-pod-index: "0"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  containers:
  - name: leader
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        nvidia.com/gpu: "1"
      limits:
        nvidia.com/gpu: "1"
  restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-worker-1-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group"
    kueue.x-k8s.io/pod-group-pod-index: "1"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  restartPolicy: Never
  containers:
  - name: worker
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        nvidia.com/gpu: "1"
      limits:
        nvidia.com/gpu: "1"
---
apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-worker-2-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group"
    kueue.x-k8s.io/pod-group-pod-index: "2"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  restartPolicy: Never
  containers:
  - name: worker
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        nvidia.com/gpu: "1"
      limits:
        nvidia.com/gpu: "1"

מקרה 2: המכונה הראשית היא לא מכונת עבודה ולא נדרש לה GPU

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

מקרה לדוגמה:

---
apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-leader-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group2"
    kueue.x-k8s.io/pod-group-pod-index: "2"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  containers:
  - name: leader
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        cpu: "1"
      limits:
        cpu: "1"
  restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-worker-0-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group2"
    kueue.x-k8s.io/pod-group-pod-index: "0"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  restartPolicy: Never
  containers:
  - name: worker
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        nvidia.com/gpu: "1"
      limits:
        nvidia.com/gpu: "1"
---
apiVersion: v1
kind: Pod
metadata:
  generateName: tas-podgroup-worker-1-
  labels:
    kueue.x-k8s.io/queue-name: tas-user-queue
    kueue.x-k8s.io/pod-group-name: "tas-podgroup-example-group2"
    kueue.x-k8s.io/pod-group-pod-index: "1"
  annotations:
    kueue.x-k8s.io/pod-group-total-count: "3"
    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-block"
spec:
  restartPolicy: Never
  containers:
  - name: worker
    image: gcr.io/k8s-staging-perf-tests/sleep:v0.1.0
    args: ["600s"]
    resources:
      requests:
        nvidia.com/gpu: "1"
      limits:
        nvidia.com/gpu: "1"

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