Alloca dinamicamente i dispositivi ai carichi di lavoro con DRA


Questa pagina spiega come eseguire il deployment dei carichi di lavoro di allocazione dinamica delle risorse (DRA) sui cluster Google Kubernetes Engine. In questa pagina creerai un ResourceClaimTemplate per richiedere hardware con DRA e poi eseguirai il deployment di un carico di lavoro di base per dimostrare in che modo Kubernetes alloca in modo flessibile l'hardware sui tuoi pod.

Questa pagina è destinata agli operatori di applicazioni e agli ingegneri dei dati che eseguono workload come AI/ML o computing ad alte prestazioni (HPC).

Informazioni sull'allocazione dinamica delle risorse

DRA è una funzionalità integrata di Kubernetes che ti consente di richiedere, allocare e condividere in modo flessibile l'hardware nel tuo cluster tra pod e container. Per saperne di più, consulta Informazioni sull'allocazione dinamica delle risorse.

Informazioni sulla richiesta di dispositivi con DRA

Quando configuri l'infrastruttura GKE per DRA, i driver DRA sui nodi creano oggetti DeviceClass nel cluster. Una DeviceClass definisce una categoria di dispositivi, ad esempio le GPU, disponibili per le richieste per i carichi di lavoro. Un amministratore della piattaforma può, se vuole, eseguire il deployment di DeviceClass aggiuntive che limitano i dispositivi che puoi richiedere in carichi di lavoro specifici.

Per richiedere dispositivi all'interno di un DeviceClass, crea uno dei seguenti oggetti:

  • ResourceClaim: Una ResourceClaim consente a un pod o a un utente di richiedere risorse hardware filtrando determinati parametri all'interno di una DeviceClass.
  • ResourceClaimTemplate: un ResourceClaimTemplate definisce un modello che i pod possono utilizzare per creare automaticamente nuovi ResourceClaim per pod.

Per saperne di più sugli oggetti ResourceClaim e ResourceClaimTemplate, vedi Quando utilizzare ResourceClaims e ResourceClaimTemplates.

Gli esempi in questa pagina utilizzano un ResourceClaimTemplate di base per richiedere la configurazione del dispositivo specificata. Per informazioni più dettagliate, consulta la ResourceClaimTemplateSpec documentazione di Kubernetes.

Limitazioni

  • Il provisioning automatico dei nodi non è supportato.
  • I cluster Autopilot non supportano DRA.
  • Non puoi utilizzare le seguenti funzionalità di condivisione della GPU:
    • GPU in time-sharing
    • GPU multi-istanza
    • Servizio multi-processo (MPS)

Requisiti

Per utilizzare DRA, la versione di GKE deve essere la 1.32.1-gke.1489001 o successive.

Devi inoltre conoscere i seguenti requisiti e limitazioni:

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:

  • Attiva l'API Google Kubernetes Engine.
  • Attiva l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo gcloud components update.

Utilizzare DRA per eseguire il deployment dei carichi di lavoro

Per richiedere l'allocazione di dispositivi per pod, devi prima creare un ResourceClaimTemplate che produce un ResourceClaim per descrivere la tua richiesta di GPU o TPU, che Kubernetes utilizza come modello per creare nuovi oggetti ResourceClaim per ogni pod in un carico di lavoro. Quando specifichi ResourceClaimTemplate in un carico di lavoro, Kubernetes alloca le risorse richieste e pianifica i pod sui nodi corrispondenti.

GPU

  1. Salva il seguente manifest come claim-template.yaml:

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaimTemplate
    metadata:
      name: gpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: single-gpu
            deviceClassName: gpu.nvidia.com
            allocationMode: ExactCount
            count: 1
    
  2. Crea ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Per creare un carico di lavoro che fa riferimento a ResourceClaimTemplate, salva il seguente manifest come dra-gpu-example.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dra-gpu-example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dra-gpu-example
      template:
        metadata:
          labels:
            app: dra-gpu-example
        spec:
          containers:
          - name: ctr
            image: ubuntu:22.04
            command: ["bash", "-c"]
            args: ["while [ 1 ]; do date; echo $(nvidia-smi -L || echo Waiting...); sleep 60; done"]
            resources:
              claims:
              - name: single-gpu
          resourceClaims:
          - name: single-gpu
            resourceClaimTemplateName: gpu-claim-template
          tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
    
  4. Esegui il deployment del carico di lavoro:

    kubectl create -f dra-gpu-example.yaml
    

TPU

  1. Salva il seguente manifest come claim-template.yaml:

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaimTemplate
    metadata:
      name: tpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: all-tpus
            deviceClassName: tpu.google.com
            allocationMode: All
    

    Questo ResourceClaimTemplate richiede a GKE di allocare un intero pool di nodi TPU a ogni ResourceClaim.

  2. Crea ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Per creare un carico di lavoro che fa riferimento a ResourceClaimTemplate, salva il seguente manifest come dra-tpu-example.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dra-tpu-example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dra-tpu-example
      template:
        metadata:
          labels:
            app: dra-tpu-example
        spec:
          containers:
          - name: ctr
            image: ubuntu:22.04
            command:
              - /bin/sh
              - -c
              - |
                echo "Environment Variables:"
                env
                echo "Sleeping indefinitely..."
                sleep infinity
            resources:
              claims:
              - name: all-tpus
          resourceClaims:
          - name: all-tpus
            resourceClaimTemplateName: tpu-claim-template
          tolerations:
          - key: "google.com/tpu"
            operator: "Exists"
            effect: "NoSchedule"
    
  4. Esegui il deployment del carico di lavoro:

    kubectl create -f dra-tpu-example.yaml
    

Verifica l'allocazione dell'hardware

Puoi verificare che ai tuoi carichi di lavoro sia stato allocato hardware controllando ResourceClaim o esaminando i log del pod.

GPU

  1. Recupera ResourceClaim associato al workload di cui hai eseguito il deployment:

    kubectl get resourceclaims
    

    L'output dovrebbe essere simile al seguente:

    NAME                                               STATE                AGE
    dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh   allocated,reserved   9s
    
  2. Per ottenere maggiori dettagli sull'hardware assegnato al pod, esegui il seguente comando:

    kubectl describe resourceclaims RESOURCECLAIM
    

    Sostituisci RESOURCECLAIM con il nome completo di ResourceClaim che hai ottenuto dall'output del passaggio precedente.

    L'output dovrebbe essere simile al seguente:

    Name:         dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh
    Namespace:    default
    Labels:       <none>
    Annotations:  resource.kubernetes.io/pod-claim-name: single-gpu
    API Version:  resource.k8s.io/v1beta1
    Kind:         ResourceClaim
    Metadata:
      Creation Timestamp:  2025-03-31T17:11:37Z
      Finalizers:
        resource.kubernetes.io/delete-protection
      Generate Name:  dra-gpu-example-64b75dc6b-x8bd6-single-gpu-
      Owner References:
        API Version:           v1
        Block Owner Deletion:  true
        Controller:            true
        Kind:                  Pod
        Name:                  dra-gpu-example-64b75dc6b-x8bd6
        UID:                   cb3cb1db-e62a-4961-9967-cdc7d599105b
      Resource Version:        12953269
      UID:                     3e0c3925-e15a-40e9-b552-d03610fff040
    Spec:
      Devices:
        Requests:
          Allocation Mode:    ExactCount
          Count:              1
          Device Class Name:  gpu.nvidia.com
          Name:               single-gpu
    Status:
      Allocation:
        Devices:
          Results:
            Admin Access:  <nil>
            Device:        gpu-0
            Driver:        gpu.nvidia.com
            Pool:          gke-cluster-gpu-pool-11026a2e-zgt1
            Request:       single-gpu
        Node Selector:
          # lines omitted for clarity
      Reserved For:
        Name:      dra-gpu-example-64b75dc6b-x8bd6
        Resource:  pods
        UID:       cb3cb1db-e62a-4961-9967-cdc7d599105b
    Events:        <none>
    
  3. Per ottenere i log del workload di cui hai eseguito il deployment, esegui questo comando:

    kubectl logs deployment/dra-gpu-example --all-pods=true | grep "GPU"
    

    L'output dovrebbe essere simile al seguente:

    [pod/dra-gpu-example-64b75dc6b-x8bd6/ctr] GPU 0: Tesla T4 (UUID: GPU-2087ac7a-f781-8cd7-eb6b-b00943cc13ef)
    

    L'output di questi passaggi mostra che GKE ha allocato una GPU al pod.

TPU

  1. Recupera ResourceClaim associato al workload di cui hai eseguito il deployment:

    kubectl get resourceclaims | grep dra-tpu-example
    

    L'output dovrebbe essere simile al seguente:

    NAME                                               STATE                AGE
    dra-tpu-example-64b75dc6b-x8bd6-all-tpus-jwwdh     allocated,reserved   9s
    
  2. Per ottenere maggiori dettagli sull'hardware assegnato al pod, esegui il seguente comando:

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

    Sostituisci RESOURCECLAIM con il nome completo di ResourceClaim che hai ottenuto dall'output del passaggio precedente.

    L'output dovrebbe essere simile al seguente:

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaim
    metadata:
      annotations:
        resource.kubernetes.io/pod-claim-name: all-tpus
      creationTimestamp: "2025-03-04T21:00:54Z"
      finalizers:
      - resource.kubernetes.io/delete-protection
      generateName: dra-tpu-example-59b8785697-k9kzd-all-gpus-
      name: dra-tpu-example-59b8785697-k9kzd-all-gpus-gnr7z
      namespace: default
      ownerReferences:
      - apiVersion: v1
        blockOwnerDeletion: true
        controller: true
        kind: Pod
        name: dra-tpu-example-59b8785697-k9kzd
        uid: c2f4fe66-9a73-4bd3-a574-4c3eea5fda3f
      resourceVersion: "12189603"
      uid: 279b5014-340b-4ef6-9dda-9fbf183fbb71
    spec:
      devices:
        requests:
        - allocationMode: All
          deviceClassName: tpu.google.com
          name: all-tpus
    status:
      allocation:
        devices:
          results:
          - adminAccess: null
            device: "0"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "1"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "2"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "3"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "4"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "5"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "6"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "7"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
        nodeSelector:
          nodeSelectorTerms:
          - matchFields:
            - key: metadata.name
              operator: In
              values:
              - gke-tpu-2ec29193-bcc0
      reservedFor:
      - name: dra-tpu-example-59b8785697-k9kzd
        resource: pods
        uid: c2f4fe66-9a73-4bd3-a574-4c3eea5fda3f
    
  3. Per ottenere i log del workload di cui hai eseguito il deployment, esegui questo comando:

    kubectl logs deployment/dra-tpu-example --all-pods=true | grep "TPU"
    

    L'output dovrebbe essere simile al seguente:

    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_CHIPS_PER_HOST_BOUNDS=2,4,1
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY_WRAP=false,false,false
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_SKIP_MDS_QUERY=true
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_RUNTIME_METRICS_PORTS=8431,8432,8433,8434,8435,8436,8437,8438
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_WORKER_ID=0
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_WORKER_HOSTNAMES=localhost
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY=2x4
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_ACCELERATOR_TYPE=v6e-8
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_HOST_BOUNDS=1,1,1
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY_ALT=false
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_DEVICE_0_RESOURCE_CLAIM=77e68f15-fa2f-4109-9a14-6c91da1a38d3
    

    L'output di questi passaggi indica che tutte le TPU in un pool di nodi sono state allocate al pod.

Passaggi successivi