Alocar dispositivos dinamicamente para cargas de trabalho com DRA


Nesta página, explicamos como implantar cargas de trabalho de alocação dinâmica de recursos (DRA, na sigla em inglês) nos clusters do Google Kubernetes Engine. Nesta página, você vai criar um ResourceClaimTemplate para solicitar hardware com DRA e implantar uma carga de trabalho básica para demonstrar como o Kubernetes aloca hardware de maneira flexível nos seus pods.

Esta página é destinada a operadores de aplicativos e engenheiros de dados que executam cargas de trabalho como IA/ML ou computação de alto desempenho (HPC).

Sobre a alocação dinâmica de recursos

O DRA é um recurso integrado do Kubernetes que permite solicitar, alocar e compartilhar hardware de maneira flexível no cluster entre pods e contêineres. Para mais informações, consulte Sobre a alocação dinâmica de recursos.

Sobre como solicitar dispositivos com a DRA

Ao configurar a infraestrutura do GKE para DRA, os drivers de DRA nos nós criam objetos DeviceClass no cluster. Uma DeviceClass define uma categoria de dispositivos, como GPUs, que estão disponíveis para solicitação de cargas de trabalho. Um administrador de plataforma pode implantar DeviceClasses adicionais que limitam os dispositivos que você pode solicitar em cargas de trabalho específicas.

Para solicitar dispositivos em um DeviceClass, crie um dos seguintes objetos:

  • ResourceClaim: uma ResourceClaim permite que um pod ou um usuário solicite recursos de hardware filtrando determinados parâmetros em uma DeviceClass.
  • ResourceClaimTemplate: um ResourceClaimTemplate define um modelo que os pods podem usar para criar automaticamente novos ResourceClaims por pod.

Para mais informações sobre objetos ResourceClaim e ResourceClaimTemplate, consulte Quando usar ResourceClaims e ResourceClaimTemplates.

Os exemplos nesta página usam um ResourceClaimTemplate básico para solicitar a configuração de dispositivo especificada. Para mais informações, consulte a documentação do Kubernetes ResourceClaimTemplateSpec.

Limitações

  • O provisionamento automático de nós não é compatível.
  • Os clusters do Autopilot não são compatíveis com DRA.
  • Não é possível usar os seguintes recursos de compartilhamento de GPU:
    • GPUs de compartilhamento de tempo
    • GPUs com várias instâncias
    • Serviço multiprocesso (MPS)

Requisitos

Para usar o DRA, a versão do GKE precisa ser 1.32.1-gke.1489001 ou mais recente.

Você também precisa conhecer os seguintes requisitos e limitações:

Antes de começar

Antes de começar, verifique se você realizou as seguintes tarefas:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a gcloud CLI anteriormente, instale a versão mais recente executando gcloud components update.

Usar o DRA para implantar cargas de trabalho

Para solicitar a alocação de dispositivos por pod, primeiro crie um ResourceClaimTemplate que produza um ResourceClaim para descrever sua solicitação de GPUs ou TPUs, que o Kubernetes usa como um modelo para criar novos objetos ResourceClaim para cada pod em uma carga de trabalho. Quando você especifica o ResourceClaimTemplate em uma carga de trabalho, o Kubernetes aloca os recursos solicitados e programa os pods nos nós correspondentes.

GPU

  1. Salve o seguinte manifesto como 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. Crie a ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Para criar uma carga de trabalho que faça referência ao ResourceClaimTemplate, salve o manifesto a seguir como 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. Implantar a carga de trabalho:

    kubectl create -f dra-gpu-example.yaml
    

TPU

  1. Salve o seguinte manifesto como 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
    

    Esse ResourceClaimTemplate solicita que o GKE aloque um pool de nós de TPU inteiro para cada ResourceClaim.

  2. Crie a ResourceClaimTemplate:

    kubectl create -f claim-template.yaml
    
  3. Para criar uma carga de trabalho que faça referência ao ResourceClaimTemplate, salve o manifesto a seguir como 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. Implantar a carga de trabalho:

    kubectl create -f dra-tpu-example.yaml
    

Verificar a alocação de hardware

Para verificar se as cargas de trabalho receberam hardware, confira o ResourceClaim ou os registros do seu pod.

GPU

  1. Receba o ResourceClaim associado à carga de trabalho que você implantou:

    kubectl get resourceclaims
    

    A saída será semelhante a esta:

    NAME                                               STATE                AGE
    dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh   allocated,reserved   9s
    
  2. Para mais detalhes sobre o hardware atribuído ao pod, execute o seguinte comando:

    kubectl describe resourceclaims RESOURCECLAIM
    

    Substitua RESOURCECLAIM pelo nome completo do ResourceClaim que você recebeu da saída da etapa anterior.

    A saída será semelhante a esta:

    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. Para receber os registros da carga de trabalho implantada, execute o seguinte comando:

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

    A saída será semelhante a esta:

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

    A saída dessas etapas mostra que o GKE alocou uma GPU para o pod.

TPU

  1. Receba o ResourceClaim associado à carga de trabalho que você implantou:

    kubectl get resourceclaims | grep dra-tpu-example
    

    A saída será semelhante a esta:

    NAME                                               STATE                AGE
    dra-tpu-example-64b75dc6b-x8bd6-all-tpus-jwwdh     allocated,reserved   9s
    
  2. Para mais detalhes sobre o hardware atribuído ao pod, execute o seguinte comando:

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

    Substitua RESOURCECLAIM pelo nome completo do ResourceClaim que você recebeu da saída da etapa anterior.

    A saída será semelhante a esta:

    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. Para receber os registros da carga de trabalho implantada, execute o seguinte comando:

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

    A saída será semelhante a esta:

    [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
    

    A saída dessas etapas indica que todas as TPUs em um pool de nós foram alocadas para o pod.

A seguir