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

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

במאמר הזה מוסבר איך לבצע אופטימיזציה לתזמון של עומסי עבודה (workload) של 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. אותו עיקרון חל על סוגי מכונות General GPU (A2,‏ A3 Edge,‏ G2,‏ G4 ו-N1), באמצעות המפרטים המתאימים של יחידת העיבוד המרכזית והזיכרון.

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

  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"

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