Gerenciar dispositivos de GPU com alocação dinâmica de recursos

A alocação dinâmica de recursos é uma API do Kubernetes que permite solicitar e compartilhar recursos, como GPUs, em pods e contêineres nos clusters bare metal do Google Distributed Cloud. Drivers de terceiros gerenciam esses dispositivos, e o Kubernetes os aloca dinamicamente, de forma semelhante aos volumes de armazenamento. Suas cargas de trabalho de IA não precisam segmentar nós específicos ou solicitar o número exato de dispositivos conectados. Neste documento, mostramos como configurar as cargas de trabalho de GPU para usar a alocação dinâmica de recursos.

Antes de começar

Antes de configurar as cargas de trabalho de GPU para usar a alocação dinâmica de recursos, verifique se os seguintes pré-requisitos foram atendidos:

  • O cluster bare metal está na versão 1.33.0 ou mais recente.
  • Seu sistema operacional é o Ubuntu 22.04 ou o Red Hat Enterprise Linux (RHEL) 9.4.
  • Você atualizou o cluster para ativar a alocação dinâmica de recursos, conforme descrito em Ativar a alocação dinâmica de recursos.
  • Você tem pelo menos uma máquina de nó com uma GPU anexada e o driver de GPU NVIDIA instalado. Para mais informações, consulte Instalar ou desinstalar o operador de GPU NVIDIA em pacote.
  • Se você estiver usando o operador de GPU NVIDIA incluído, a versão 1.33.0 ou mais recente ativa a interface de dispositivo de contêiner (CDI) por padrão. Se você estiver usando um operador de GPU instalado manualmente, verifique se a CDI está ativada no ClusterPolicy.
  • Você seguiu as instruções em Driver DRA da NVIDIA para GPUs para instalar o driver DRA da NVIDIA em todos os nós com GPU.

Criar cargas de trabalho de GPU que usam a alocação dinâmica de recursos

Para que as cargas de trabalho de GPU aproveitem a alocação dinâmica de recursos para solicitar GPUs, elas precisam estar em um namespace compartilhado com um ResourceClaim que descreva a solicitação de alocação de dispositivos de GPU. Suas cargas de trabalho precisam referenciar o ResourceClaim para que o Kubernetes atribua recursos de GPU.

As etapas a seguir configuram um ambiente em que as cargas de trabalho usam a alocação dinâmica de recursos para solicitar recursos de GPU:

  1. Para criar recursos relacionados à alocação dinâmica de recursos, crie um novo Namespace no cluster:

    cat <<EOF | kubectl apply --kubeconfig=CLUSTER_KUBECONFIG -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      name: NAMESPACE_NAME
    EOF
    

    Substitua:

    • CLUSTER_KUBECONFIG: o caminho do arquivo kubeconfig do cluster de usuário.

    • NAMESPACE_NAME pelo nome do namespace de alocação dinâmica de recursos.

  2. Crie um ResourceClaim para descrever a solicitação de acesso à GPU:

    cat <<EOF | kubectl apply --kubeconfig=CLUSTER_KUBECONFIG -f -
    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaim
    metadata:
      namespace: NAMESPACE_NAME
      name: RESOURCE_CLAIM_NAME
    spec:
        devices:
          requests:
          - name: gpu
            deviceClassName: gpu.nvidia.com
    EOF
    

    Substitua RESOURCE_CLAIM_NAME pelo nome da declaração de recurso para solicitações de GPU.

  3. Crie cargas de trabalho que referenciem o ResourceClaim criado na etapa anterior.

    Os exemplos de carga de trabalho a seguir mostram como referenciar um ResourceClaim chamado gpu-claim no namespace dra-test. Os contêineres no pod pod1 são amostras de arquitetura de dispositivo de computação unificada (CUDA, na sigla em inglês) da NVIDIA projetadas para executar cargas de trabalho CUDA nas GPUs. Quando o pod pod1 é concluído com sucesso, isso indica que o recurso de alocação dinâmica de recursos está funcionando corretamente e está pronto para gerenciar recursos de GPU no cluster.

    Ubuntu

    1. Use o seguinte comando para aplicar o manifesto ao cluster:

      cat <<EOF | kubectl apply --kubeconfig=CLUSTER_KUBECONFIG -f -
      apiVersion: v1
      kind: Pod
      metadata:
        name: pod1
        namespace: dra-test
      spec:
        restartPolicy: OnFailure
        resourceClaims:
          - name: gpu
            resourceClaimName: gpu-claim
        containers:
          - name: ctr0
            image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda12.5.0
            resources:
              claims:
                - name: gpu
          - name: ctr1
            image: nvcr.io/nvidia/k8s/cuda-sample:devicequery
            resources:
              claims:
                - name: gpu
      EOF
      

    RHEL

    1. Use o seguinte comando para aplicar o manifesto ao cluster:

      cat <<EOF | kubectl apply --kubeconfig=CLUSTER_KUBECONFIG -f -
      apiVersion: v1
      kind: Pod
      metadata:
        name: pod1
        namespace: dra-test
      spec:
        restartPolicy: OnFailure
      
        resourceClaims:
          - name: gpu
            resourceClaimName: gpu-claim
        containers:
          - name: ctr0
            image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda12.5.0
            resources:
              claims:
                - name: gpu
          - name: ctr1
            image: nvcr.io/nvidia/k8s/cuda-sample:devicequery
            resources:
              claims:
                - name: gpu
      EOF
      

Limitações

Considere as seguintes limitações ao usar a alocação dinâmica de recursos:

  • Quando você usa o SO RHEL com uma versão compatível do operador de GPU NVIDIA, a interface de dispositivo de contêiner (CDI, na sigla em inglês) processa a injeção de dispositivos e a rotulagem do SELinux automaticamente. Não é necessário usar a configuração manual da política do SELinux ou definir o securityContext do pod.

  • Esse recurso usa o grupo de APIs resource.k8s.io/v1beta1, que é diferente do grupo de APIs de código aberto do Kubernetes para esse recurso, resource.k8s.io/v1. O grupo de APIs de código aberto v1 oferece mais recursos e melhor estabilidade do que o grupo de APIs v1beta1.

A seguir