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 tuoi 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 come Kubernetes alloca in modo flessibile l'hardware nei tuoi pod.

Questa pagina è rivolta a operatori di applicazioni e data engineer che eseguono carichi di lavoro come AI/ML o computing ad alte prestazioni (HPC).

Informazioni sull'allocazione dinamica delle risorse

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

Informazioni sulla richiesta di dispositivi con DRA

Quando configuri l'infrastruttura GKE per la replica dati in tempo reale, i relativi driver sui nodi creano oggetti DeviceClass nel cluster. Un DeviceClass definisce una categoria di dispositivi, ad esempio le GPU, che è possibile richiedere per i carichi di lavoro. Se vuoi, un amministratore della piattaforma può eseguire il deployment di altri DeviceClass 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 richiesta di risorse consente a un pod o a un utente di richiedere risorse hardware filtrando in base a determinati parametri all'interno di una classe di dispositivi.
  • ResourceClaimTemplate: un ResourceClaimTemplate definisce un modello che i pod possono utilizzare per creare automaticamente nuovi ResourceClaim per ogni pod.

Per ulteriori informazioni sugli oggetti ResourceClaim e ResourceClaimTemplate, consulta 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 ResourceClaimTemplateSpecdocumentazione di Kubernetes.

Limitazioni

  • Il provisioning automatico dei nodi non è supportato.
  • I cluster Autopilot non supportano la replica dinamica.
  • Non puoi utilizzare le seguenti funzionalità di condivisione della GPU:
    • GPU con condivisione del tempo
    • GPU a più istanze
    • Servizio multiprocesso (MPS)

Requisiti

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

Inoltre, devi 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à, installa e poi inizializza gcloud CLI. Se hai già installato l'interfaccia a riga di comando gcloud, ottieni la versione più recente eseguendo gcloud components update.

Utilizzare DRA per eseguire il deployment dei carichi di lavoro

Per richiedere l'allocazione dei dispositivi per pod, devi prima creare un ResourceClaimTemplate che genera 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 il ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Per creare un carico di lavoro che fa riferimento al file 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 il ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Per creare un carico di lavoro che fa riferimento al file 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. Ottieni il ResourceClaim associato al carico di lavoro 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 ulteriori 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:       
    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:  
            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:        
    
  3. Per ottenere i log per il carico di lavoro di cui hai eseguito il deployment, esegui il seguente 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. Ottieni il ResourceClaim associato al carico di lavoro 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 ulteriori 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 per il carico di lavoro di cui hai eseguito il deployment, esegui il seguente 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