Allouer dynamiquement des appareils à des charges de travail avec DRA


Cette page explique comment déployer des charges de travail d'allocation dynamique des ressources (DRA, Dynamic Resource Allocation) sur vos clusters Google Kubernetes Engine. Sur cette page, vous allez créer un ResourceClaimTemplate pour demander du matériel avec DRA, puis déployer une charge de travail de base pour montrer comment Kubernetes alloue de manière flexible du matériel à vos pods.

Cette page est destinée aux opérateurs d'applications et aux ingénieurs en données qui exécutent des charges de travail telles que l'IA/ML ou le calcul hautes performances (HPC).

À propos de l'allocation dynamique des ressources

DRA est une fonctionnalité Kubernetes intégrée qui vous permet de demander, d'allouer et de partager du matériel de manière flexible dans votre cluster entre les pods et les conteneurs. Pour en savoir plus, consultez À propos de l'allocation dynamique des ressources.

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 un DeviceClass, vous devez créer l'un des objets suivants :

  • ResourceClaim : Une 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 objets ResourceClaim et ResourceClaimTemplate, consultez Quand utiliser ResourceClaims et ResourceClaimTemplates.

Les exemples de cette page utilisent un ResourceClaimTemplate de base pour demander la configuration d'appareil spécifiée. Pour en savoir plus, consultez la documentation Kubernetes ResourceClaimTemplateSpec.

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
    • Service multiprocessus (MPS)

Conditions requises

Pour utiliser DRA, votre version de GKE doit être la version 1.32.1-gke.1489001 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 gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.

Utiliser DRA pour déployer des charges de travail

Pour demander l'allocation d'appareils par pod, vous devez d'abord créer un ResourceClaimTemplate qui produit un ResourceClaim pour décrire votre demande de GPU ou de TPU. Kubernetes utilise ce ResourceClaim comme modèle pour créer des objets ResourceClaim pour chaque pod d'une charge de travail. Lorsque vous spécifiez ResourceClaimTemplate dans une charge de travail, Kubernetes alloue les ressources demandées et planifie les pods sur les nœuds correspondants.

GPU

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

    kubectl create -f claim-template.yaml
    
  3. Pour créer une charge de travail qui référence le 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: ["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. 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/v1beta1
    kind: ResourceClaimTemplate
    metadata:
      name: tpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: all-tpus
            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 sous-réseau ResourceClaimTemplate :

    kubectl create -f claim-template.yaml
    
  3. Pour créer une charge de travail qui référence le 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

Pour vérifier que du matériel a été alloué à vos charges de travail, consultez ResourceClaim ou les journaux de votre pod.

GPU

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

    kubectl get resourceclaims
    

    La sortie doit ressembler à ceci :

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

    kubectl describe resourceclaims RESOURCECLAIM
    

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

    La sortie doit ressembler à ceci :

    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. Pour obtenir les journaux de la charge de travail que vous avez déployée, exécutez la commande suivante :

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

    La sortie doit ressembler à ceci :

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

    La sortie de ces étapes montre que GKE a alloué un GPU au pod.

TPU

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

    kubectl get resourceclaims | grep dra-tpu-example
    

    La sortie doit ressembler à ceci :

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

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

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

    La sortie doit ressembler à ceci :

    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. Pour obtenir les journaux de la charge de travail que vous avez déployée, exécutez la commande suivante :

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

    La sortie doit ressembler à ceci :

    [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