Topology Aware Scheduling (TAS)으로 GKE 워크로드 예약

AI 및 ML 워크로드에는 상당한 포드 간 통신이 필요합니다. 이 요구사항으로 인해 포드 간 네트워크 대역폭은 워크로드 실행 시간과 비용에 직접적인 영향을 미칩니다. 이 대역폭은 클러스터의 가상 머신 (VM) 인스턴스 배치에 따라 달라집니다.

이 문서에서는 성능과 안정성을 모두 고려하여 Google Kubernetes Engine (GKE) 클러스터에서 대규모 AI 또는 ML 워크로드의 일정을 최적화하는 방법을 설명합니다. 특히 짧은 지연 시간 통신을 위해 토폴로지 인식 스케줄링 (TAS)을 사용하도록 클러스터를 구성합니다. 이 접근 방식은 통신 오버헤드를 최소화하고 워크로드의 성능을 극대화하는 데 도움이 됩니다.

Topology Aware Scheduling (TAS)이란 무엇인가요?

TAS는 대규모 언어 모델 (LLM) 학습의 효율성을 크게 개선할 수 있습니다. TAS는 경사도 집계 중에 통신 오버헤드를 최소화하기 위해 네트워크 토폴로지에 작업자를 전략적으로 배치합니다. 경사도 집계에는 작업자가 특정 순위 순서로 통신해야 합니다. TAS는 순차적으로 통신하는 작업자 간의 네트워크 홉을 최소화하여 네트워크 경합을 줄이고 대역폭 사용률을 최적화하므로 수렴 속도가 빨라지고 학습 시간이 단축됩니다. LLM 모델이 점점 커짐에 따라 TAS는 분산 학습의 성능과 확장성을 극대화하는 데 필수적입니다.

TAS는 예약을 통해 확보할 수 있는 밀도 높은 용량과 함께 사용할 때 가장 효과적입니다. Flex-start VM 또는 스팟 VM을 사용하면 용량이 서로 가까이 할당될 가능성이 낮으므로 이 시나리오에서는 TAS가 제대로 작동하지 않을 수 있습니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
  • 클러스터에 연결하려면 다음 명령어를 실행합니다.

    gcloud container clusters get-credentials CLUSTER_NAME
    

    CLUSTER_NAME을 클러스터 이름으로 바꿉니다.

GKE 클러스터 준비

TAS로 워크로드를 실행하도록 GKE 클러스터를 준비하려면 다음 단계를 완료하세요.

  1. TAS가 사용 설정된 Kueue 설치

  2. GKE 클러스터의 토폴로지 보기

  3. Kueue 구성

TAS가 사용 설정된 Kueue 설치

할당량과 작업에서 이러한 할당량을 소비할 방식을 관리하는 Kubernetes 기반 시스템인 Kueue와 함께 TAS를 사용하는 것이 좋습니다. TAS에는 Kueue 버전 0.10.0 이상이 필요하며 명시적으로 사용 설정해야 합니다.

Kueue를 설치하고 TAS를 사용 설정하려면 다음 옵션 중 하나를 선택하세요.

Kueue 매니페스트

  1. Kueue를 설치합니다.

    kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.0/manifests.yaml
    
  2. Kueue에서 TAS를 사용 설정합니다.

    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 차트

Helm 차트를 사용하여 TAS가 사용 설정된 Kueue를 설치합니다.

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"

Kueke를 설치한 후 다음 섹션에 설명된 대로 관리하는 인프라를 이해하도록 구성해야 합니다.

GKE 클러스터의 토폴로지 보기

스팟 VM으로 프로비저닝된 A4X, A4, A3 Ultra, A3 Mega, A3 High (GPU 8개) 노드의 토폴로지를 확인하려면 먼저 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을 노드 풀의 이름으로 바꿉니다.

출력에서 VM의 GKE 노드의 실제 토폴로지를 확인하려면 다음 노드 라벨을 참고하세요.

  • cloud.google.com/gce-topology-block: VM이 있는 예약된 블록의 조직별 ID입니다.

  • cloud.google.com/gce-topology-subblock: VM이 있는 하위 블록의 조직별 ID입니다.

  • cloud.google.com/gce-topology-host: VM이 있는 호스트의 ID입니다.

  • kubernetes.io/hostname: Kubernetes 노드의 호스트 이름입니다. 이 호스트 이름은 일반적으로 GKE 노드 이름이기도 합니다.

두 VM이 공유하는 라벨 값이 많을수록 VM이 서로 더 가깝게 배치됩니다. 이러한 용어에 대한 자세한 내용은 용어를 참고하세요.

Kueue 구성

Kueue를 설치한 후에는 관리하는 인프라를 지정하도록 Kueue를 구성해야 합니다. 일반적으로 Kueue에는 정적 인프라 또는 클러스터 자동 확장 기능이 사용 설정된 동적 인프라의 ClusterQueue 리소스 할당량 정의가 필요합니다. ClusterQueue는 워크로드가 요청하는 리소스가 ClusterQueue에 정의된 리소스 풀보다 작거나 같은 경우에만 워크로드를 허용합니다. 이 섹션에 설명된 대로 Kueue를 구성하면 Kueue는 다음과 같이 TAS를 사용하여 워크로드를 허용합니다.

  • TAS 워크로드: Kueue는 물리적 인프라의 토폴로지와 현재 사용량을 모두 확인합니다.

  • 비TAS 워크로드: Kueue는 물리적 인프라의 토폴로지를 확인하지 않습니다. Kueue는 구성에 정의된 전체 할당량을 관리하고 노드 할당은 kube-scheduler에 맡깁니다.

Kueue에 ClusterQueue 리소스 할당량 정의를 제공하는 방법을 알아보려면 다음 예시를 검토하세요.

  • 매우 높은 할당량: Kueue는 요청된 리소스를 기반으로 워크로드의 승인을 중지하지 않습니다. TAS 정의에 따라 Kueue는 인프라 토폴로지를 기반으로 워크로드를 허용할 수도 있고 허용하지 않을 수도 있습니다. 자세한 내용은 매우 높은 리소스 할당량을 참고하세요.

  • 현실적인 할당량: Kueue는 워크로드가 요청하는 리소스가 이러한 리소스 할당량 한도 내에 있는 경우에만 워크로드를 허용합니다. 그런 다음 Kueue는 TAS 정의를 기반으로 워크로드를 허용하기 전에 인프라 토폴로지를 확인합니다. 자세한 내용은 실제 리소스 할당량을 참고하세요.

다음 섹션의 리소스 할당량에 대한 모든 참조는 ClusterQueue 리소스 할당량을 나타냅니다.

매우 높은 리소스 할당량

다음 예에서는 사용 가능한 리소스 할당량을 기반으로 Kueue가 워크로드를 중지하지 않도록 매우 높은 리소스 할당량을 사용합니다. 대신 Kueue는 사용 가능한 노드의 토폴로지 정보를 사용하여 토폴로지를 워크로드의 요구사항과 일치시키려고 합니다.

다음 리소스 할당량 정의를 사용하려면 다음 단계를 완료하세요.

  1. 원하는 파일 편집기를 엽니다. 그런 다음 kueue-tas-config-very-high-quota.yaml이라는 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를 포함한 보다 현실적인 리소스 할당량을 정의합니다. a3-ultragpu-8g 머신 100대용입니다. 단일 머신에는 vCPU 224개, 메모리 2944GB, GPU 8개가 있습니다.

다음 리소스 할당량 정의를 사용하려면 다음 단계를 완료하세요.

  1. 원하는 파일 편집기를 엽니다. 그런 다음 kueue-tas-config-real-quota.yaml이라는 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
    

Kueue를 사용하여 TAS로 워크로드 예약

다음 시나리오에서는 토폴로지 요청 유형과 토폴로지 요청 수준을 사용하여 일반적인 워크로드 및 인프라 조합을 관리하도록 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 파일을 사용하세요.

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: 동시에 실행되는 포드 수입니다.

  • ANNOTATIONS_STRING: 다음 표를 참고하세요.

    요청된 토폴로지 유형 및 수준 설명 ANNOTATIONS_STRING
    호스트 이름 내에서 실행하는 것이 선호됩니다 (권장). 이 구성은 용량이 조각화되어 있더라도 워크로드의 리소스 요구사항을 충족할 수 있는 리소스가 충분히 있으면 워크로드를 허용합니다. Kueue는 포드를 최대한 콤팩트하게 예약합니다. kueue.x-k8s.io/podset-preferred-topology: "kubernetes.io/hostname"
    호스트 내에서 실행하려면 필수

    이 구성은 워크로드의 리소스 요구사항을 충족할 수 있는 충분한 리소스가 있는 호스트가 있는 경우에만 워크로드를 허용합니다.

    이는 호스트당 VM이 여러 개 (예: 더 작은 머신 유형) 있거나 단일 노드에서 여러 포드를 실행할 수 있는 경우에 유용합니다. 이 경우 워크로드가 허용되면 단일 호스트에서 실행됩니다.

    kueue.x-k8s.io/podset-required-topology: "cloud.google.com/gce-topology-host"
    호스트 내에서 실행하는 것이 선호됩니다. 이 구성은 용량이 조각화되어 있더라도 워크로드의 리소스 요구사항을 충족할 수 있는 리소스가 충분히 있으면 워크로드를 허용합니다. Kueue는 호스트 내에서 포드를 예약하려고 시도하며 필요한 경우 추가 호스트를 사용합니다. 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는 하위 블록 내에서 포드를 예약하려고 시도하며 필요한 경우 추가 하위 블록을 사용합니다. 이 경우 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는 블록 내에서 포드를 예약하려고 시도하며 필요한 경우 추가 블록을 사용합니다. kueue.x-k8s.io/podset-preferred-topology: "cloud.google.com/gce-topology-block"

Kueue를 사용하여 TAS로 PodGroup을 사용하여 워크로드 예약

PodGroup을 사용하는 경우 PodGroup의 모든 포드에 대해 세 개의 추가 필드를 지정해야 합니다.

사용하는 ML 프레임워크에 따라 PodGroup의 리더가 GPU를 요구할 수도 있고 요구하지 않을 수도 있습니다. Kueue의 제한사항으로 인해 이러한 사례는 다르게 처리해야 합니다. 다음 예에서는 리더 1개와 작업자 2개로 구성된 포드 3개의 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 제한으로 인해 리더가 작업자 중 하나가 아닌 경우 Kueue가 PodSet을 만드는 방식 때문에 리더는 PodGroup에서 마지막 색인을 가져야 합니다. 리더에 마지막 색인이 없고 첫 번째 작업자가 첫 번째 색인을 사용하지 않으면 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"

다음 단계