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

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

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

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

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

התכונה TAS פועלת בצורה הטובה ביותר עם קיבולת גבוהה, שאפשר להשיג באמצעות הזמנות. במכונות Flex-start VM או במכונות 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

כדי להבין את הטופולוגיה הפיזית של צמתי GKE במכונות A4X Max,‏ A4X, ‏ A4 ו-A3 Ultra Compute Engine, אפשר לעיין בתוויות הצמתים הבאות:

  • cloud.google.com/gce-topology-block: המזהה הספציפי לארגון של הבלוק השמור שבו נמצא ה-VM. בלוק הוא אוסף של תת-בלוקים שמחוברים באמצעות שכבה של רשת מבוזרת.
  • cloud.google.com/gce-topology-subblock: המזהה הספציפי לארגון של תת-הבלוק שבו נמצאת המכונה הווירטואלית. תת-בלוק הוא קבוצה של מארחים וציוד קישוריות משויך:
    • במכונות וירטואליות מסוג A4 ו-A3 Ultra, המארחים מתחברים דרך רשת Jupiter מבוזרת בקנה מידה גדול.
    • מכונות A4X Max ו-A4X Compute Engine מאורגנות בתת-בלוקים, שכל אחד מהם מהווה תחום NVIDIA NVLink (NVL72). בכל NVL72, מעבדי ה-GPU מחוברים זה לזה באופן הדוק באמצעות NVLink ייעודי עם רוחב פס גבוה. במקרים שבהם יש כמה תתי-בלוקים, יחידות ה-GPU יכולות להתחבר באמצעות כרטיסי RDMA NIC על ידי שימוש ב-RoCE fabric. תקשורת בין מארחים בין תת-בלוקים, וגם תעבורת נתונים אחרת ברשת כמו אחסון, מתבצעת באמצעות רשת Jupiter דרך כרטיסי רשת אתרנט של ממשק קצה במהירות גבוהה.
  • cloud.google.com/gce-topology-host: המזהה הספציפי לארגון של המארח שבו נמצאת המכונה הווירטואלית. מארח או צומת הם מכונת שרת פיזית אחת במרכז הנתונים. כל צומת GKE מוקצה במכונה וירטואלית שמוקצית על גבי מארח פיזי.
  • kubernetes.io/hostname: שם המארח של צומת Kubernetes. בדרך כלל זה גם שם הצומת ב-GKE.

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

מריצים את הפקודה הבאה כדי לקבל את תוויות הצמתים של צמתי אשכול GKE עם מאיץ ספציפי:

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

מחליפים את ACCELERATOR בשם של המאיץ, למשל nvidia-h200-141gb.

בפלט מוצגים הבלוק, תת-הבלוק והמארח של כל אחד מצמתי 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.

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

  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"

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