Allocare dinamicamente i dispositivi ai carichi di lavoro con DRA

Puoi richiedere in modo flessibile i dispositivi per i tuoi carichi di lavoro Google Kubernetes Engine (GKE) utilizzando l'allocazione dinamica delle risorse (DRA). Questo documento mostra come creare un ResourceClaimTemplate per richiedere dispositivi e poi creare un workload per osservare in che modo Kubernetes alloca in modo flessibile i dispositivi ai tuoi pod.

Questo documento è destinato agli operatori di applicazioni e ai data engineer che eseguono workload come AI/ML o computing ad alte prestazioni (HPC).

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 workload. Un amministratore della piattaforma può, se vuole, eseguire il deployment di DeviceClass aggiuntive che limitano i dispositivi che puoi richiedere in workload specifici.

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

  • ResourceClaim: un 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ù su ResourceClaim e ResourceClaimTemplate, consulta Quando utilizzare ResourceClaim e ResourceClaimTemplate.

Gli esempi in questa pagina utilizzano un ResourceClaimTemplate di base per richiedere la configurazione del dispositivo specificata. Per saperne di più su tutti i campi che puoi specificare, consulta il riferimento API ResourceClaimTemplate.

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.34 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 il comando gcloud components update. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.

Utilizza DRA per eseguire il deployment dei workload

Per richiedere l'allocazione di dispositivi per pod, crea un ResourceClaimTemplate che contenga la configurazione del dispositivo richiesta, ad esempio GPU di un tipo specifico. Quando deploy un workload che fa riferimento a ResourceClaimTemplate, Kubernetes crea ResourceClaim per ogni pod nel workload in base a ResourceClaimTemplate. Kubernetes alloca le risorse richieste e pianifica i pod sui nodi corrispondenti.

Per richiedere dispositivi in un workload con DRA, seleziona una delle seguenti opzioni:

GPU

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

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

    kubectl create -f claim-template.yaml
    
  3. Per creare un workload 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: ["echo $(nvidia-smi -L || echo Waiting...)"]
            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/v1
    kind: ResourceClaimTemplate
    metadata:
      name: tpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: all-tpus
            exactly:
              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 workload 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 hardware

Puoi verificare che ai tuoi workload sia stato allocato hardware controllando ResourceClaim o esaminando i log del pod. Per verificare l'allocazione per GPU o TPU, seleziona una delle seguenti opzioni:

GPU

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

    kubectl get resourceclaims
    

    L'output è simile al seguente:

    NAME                                               STATE                AGE
    dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh   allocated,reserved   9s
    
  2. Scopri di più sull'hardware assegnato al pod:

    kubectl describe resourceclaims RESOURCECLAIM
    

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

    L'output è simile al seguente:

       Name:         dra-gpu-example-68f595d7dc-prv27-single-gpu-qgjq5
       Namespace:    default
       Labels:       <none>
       Annotations:  resource.kubernetes.io/pod-claim-name: single-gpu
       API Version:  resource.k8s.io/v1
       Kind:         ResourceClaim
       Metadata:
       # Multiple lines are omitted here.
       Spec:
         Devices:
           Requests:
             Exactly:
               Allocation Mode:    ExactCount
               Count:              1
               Device Class Name:  gpu.nvidia.com
             Name:                 single-gpu
       Status:
         Allocation:
           Devices:
             Results:
               Device:   gpu-0
               Driver:   gpu.nvidia.com
               Pool:     gke-cluster-1-dra-gpu-pool-b56c4961-7vnm
               Request:  single-gpu
           Node Selector:
             Node Selector Terms:
               Match Fields:
                 Key:       metadata.name
                 Operator:  In
                 Values:
                   gke-cluster-1-dra-gpu-pool-b56c4961-7vnm
         Reserved For:
           Name:      dra-gpu-example-68f595d7dc-prv27
           Resource:  pods
           UID:       e16c2813-08ef-411b-8d92-a72f27ebf5ef
       Events:        <none>
       ```
    
  3. Recupera i log per il carico di lavoro di cui hai eseguito il deployment:

    kubectl logs deployment/dra-gpu-example --all-pods=true
    

    L'output è 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 container.

TPU

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

    kubectl get resourceclaims | grep dra-tpu-example
    

    L'output è simile al seguente:

    NAME                                               STATE                AGE
    dra-tpu-example-64b75dc6b-x8bd6-all-tpus-jwwdh     allocated,reserved   9s
    
  2. Scopri di più sull'hardware assegnato al pod:

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

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

    L'output è 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. Recupera i log per il carico di lavoro di cui hai eseguito il deployment:

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

    L'output è 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