Allouer dynamiquement des appareils aux charges de travail avec DRA

Vous pouvez demander des appareils de manière flexible pour vos charges de travail Google Kubernetes Engine (GKE) à l'aide de l'allocation dynamique des ressources (DRA). Ce document vous explique comment créer un ResourceClaimTemplate pour demander des appareils, puis comment créer une charge de travail pour observer comment Kubernetes alloue de manière flexible les appareils à vos pods.

Ce document s'adresse aux opérateurs d'applications et aux ingénieurs des données qui exécutent des charges de travail telles que l'IA/ML ou le calcul hautes performances (HPC).

Demander des appareils avec DRA

Lorsque vous configurez votre infrastructure GKE pour DRA, les pilotes DRA sur vos nœuds créent des objets DeviceClass dans le cluster. Une DeviceClass définit une catégorie d'appareils, tels que les GPU, qui peuvent être demandés pour les charges de travail. Un administrateur de plate-forme peut éventuellement déployer des DeviceClasses supplémentaires qui limitent les appareils que vous pouvez demander dans des charges de travail spécifiques.

Pour demander des appareils dans une DeviceClass, vous devez créer l'un des objets suivants :

  • ResourceClaim : ResourceClaim permet à un pod ou à un utilisateur de demander des ressources matérielles en filtrant certains paramètres dans une DeviceClass.
  • ResourceClaimTemplate : un ResourceClaimTemplate définit un modèle que les pods peuvent utiliser pour créer automatiquement des ResourceClaims par pod.

Pour en savoir plus sur les ResourceClaims et les ResourceClaimTemplates, consultez Quand utiliser les ResourceClaims et les ResourceClaimTemplates.

Les exemples de cette page utilisent un ResourceClaimTemplate de base pour demander la configuration d'appareil spécifiée. Pour en savoir plus sur tous les champs que vous pouvez spécifier, consultez la documentation de référence de l'API ResourceClaimTemplate.

Limites

  • Le provisionnement automatique des nœuds n'est pas compatible.
  • Les clusters Autopilot ne sont pas compatibles avec DRA.
  • Vous ne pouvez pas utiliser les fonctionnalités de partage de GPU suivantes :
    • GPU de partage de temps
    • GPU multi-instances
    • Multi-process Service (MPS)

Conditions requises

Pour utiliser DRA, votre version de GKE doit être la version 1.34 ou ultérieure.

Vous devez également connaître les exigences et les limites suivantes :

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez la gcloud CLI. Si vous avez déjà installé la gcloud CLI, obtenez la dernière version en exécutant la commande gcloud components update. Il est possible que les versions antérieures de la gcloud CLI ne permettent pas d'exécuter les commandes de ce document.

Utiliser DRA pour déployer des charges de travail

Pour demander l'allocation d'appareils par pod, vous devez créer un ResourceClaimTemplate qui contient la configuration d'appareil souhaitée, comme des GPU d'un type spécifique. Lorsque vous déployez une charge de travail qui référence ResourceClaimTemplate, Kubernetes crée des ResourceClaims pour chaque pod de la charge de travail en fonction de ResourceClaimTemplate. Kubernetes alloue les ressources demandées et planifie les pods sur les nœuds correspondants.

Pour demander des appareils dans une charge de travail avec DRA, sélectionnez l'une des options suivantes :

GPU

  1. Enregistrez le manifeste suivant sous le nom 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. Créez le ResourceClaimTemplate :

    kubectl create -f claim-template.yaml
    
  3. Pour créer une charge de travail qui fait référence à ResourceClaimTemplate, enregistrez le fichier manifeste suivant sous le nom 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. Déployer la charge de travail :

    kubectl create -f dra-gpu-example.yaml
    

TPU

  1. Enregistrez le manifeste suivant sous le nom 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
    

    Ce ResourceClaimTemplate demande à GKE d'allouer un pool de nœuds TPU entier à chaque ResourceClaim.

  2. Créez le ResourceClaimTemplate :

    kubectl create -f claim-template.yaml
    
  3. Pour créer une charge de travail qui fait référence à ResourceClaimTemplate, enregistrez le fichier manifeste suivant sous le nom 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. Déployer la charge de travail :

    kubectl create -f dra-tpu-example.yaml
    

Vérifier l'allocation du matériel

Vous pouvez vérifier que du matériel a été alloué à vos charges de travail en consultant la ResourceClaim ou les journaux de votre pod. Pour vérifier l'allocation des GPU ou des TPU, sélectionnez l'une des options suivantes :

GPU

  1. Obtenez le ResourceClaim associé à la charge de travail que vous avez déployée :

    kubectl get resourceclaims
    

    Le résultat ressemble à ce qui suit :

    NAME                                               STATE                AGE
    dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh   allocated,reserved   9s
    
  2. Obtenez plus d'informations sur le matériel attribué au pod :

    kubectl describe resourceclaims RESOURCECLAIM
    

    Remplacez RESOURCECLAIM par le nom complet de ResourceClaim que vous avez obtenu à l'étape précédente.

    Le résultat ressemble à ce qui suit :

       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. Obtenez les journaux de la charge de travail que vous avez déployée :

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

    Le résultat ressemble à ce qui suit :

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

    Le résultat de ces étapes montre que GKE a attribué un GPU au conteneur.

TPU

  1. Obtenez le ResourceClaim associé à la charge de travail que vous avez déployée :

    kubectl get resourceclaims | grep dra-tpu-example
    

    Le résultat ressemble à ce qui suit :

    NAME                                               STATE                AGE
    dra-tpu-example-64b75dc6b-x8bd6-all-tpus-jwwdh     allocated,reserved   9s
    
  2. Obtenez plus d'informations sur le matériel attribué au pod :

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

    Remplacez RESOURCECLAIM par le nom complet de ResourceClaim que vous avez obtenu à l'étape précédente.

    Le résultat ressemble à ce qui suit :

    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. Obtenez les journaux de la charge de travail que vous avez déployée :

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

    Le résultat ressemble à ce qui suit :

    [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
    

    Le résultat de ces étapes indique que toutes les TPU d'un pool de nœuds ont été attribuées au pod.

Étapes suivantes