Preparar a infraestrutura do GKE para cargas de trabalho de DRA


Nesta página, explicamos como configurar sua infraestrutura do Google Kubernetes Engine (GKE) para oferecer suporte à alocação dinâmica de recursos (DRA, na sigla em inglês). Nesta página, você vai criar clusters que podem implantar cargas de trabalho de GPU ou TPU e instalar manualmente os drivers necessários para ativar o DRA.

Esta página é destinada a administradores de plataforma que querem reduzir a complexidade e a sobrecarga da configuração de infraestrutura com dispositivos de hardware especializados.

Sobre o DRA

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.

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, dependendo do tipo de hardware que quer usar:

Antes de começar

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

  • Ative 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.
  • Se você não estiver usando o Cloud Shell, instale a CLI do Helm:

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
    

Criar um cluster do GKE Standard

Crie um cluster no modo padrão que ative as APIs Beta do Kubernetes para DRA:

gcloud container clusters create CLUSTER_NAME \
    --quiet \
    --enable-kubernetes-unstable-apis="resource.k8s.io/v1beta1/deviceclasses,resource.k8s.io/v1beta1/resourceclaims,resource.k8s.io/v1beta1/resourceclaimtemplates,resource.k8s.io/v1beta1/resourceslices" \
    --release-channel=rapid \
    --enable-autoupgrade \
    --location CONTROL_PLANE_LOCATION \
    --num-nodes "1" \
    --cluster-version GKE_VERSION \
    --workload-pool="PROJECT_ID.svc.id.goog"

Substitua:

  • CLUSTER_NAME: um nome para o cluster.
  • CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Forneça uma região para clusters regionais ou uma zona para clusters zonais.
  • GKE_VERSION: a versão do GKE a ser usada para o cluster e os nós. Precisa ser 1.32.1-gke.1489001 ou mais recente.
  • PROJECT_ID: o ID do projeto.

Preparar seu ambiente do GKE para oferecer suporte ao DRA

No GKE, é possível usar o DRA com GPUs e TPUs. Ao criar seus pools de nós, use as seguintes configurações que funcionam com o DRA durante a prévia:

  • Para GPUs, desative a instalação automática de drivers.
  • Adicione os escopos de acesso necessários para os nós.
  • Adicione rótulos de nós para executar apenas cargas de trabalho de DRA nos nós.
  • Ative o escalonamento automático de cluster.

Todas as outras configurações de configuração do pool de nós, como tipo de máquina, tipo e contagem de acelerador, sistema operacional e locais dos nós, dependem dos seus requisitos.

Preparar o ambiente para GPUs

  1. Crie um pool de nós com o hardware necessário:

    gcloud beta container node-pools create "gpu-pool" \
        --quiet \
        --project PROJECT_ID \
        --cluster CLUSTER_NAME \
        --location CONTROL_PLANE_LOCATION \
        --node-version KUBERNETES_VERSION \
        --machine-type "n1-standard-8" \
        --accelerator "type=nvidia-tesla-t4,count=2,gpu-driver-version=disabled" \
        --image-type "UBUNTU_CONTAINERD" \
        --disk-type "pd-standard" \
        --disk-size "100" \
        --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" \
        --num-nodes "1" \
        --enable-autoscaling \
        --min-nodes "1" \
        --max-nodes "6" \
        --location-policy "ANY" \
        --max-surge-upgrade 1 \
        --max-unavailable-upgrade 0 \
        --node-locations ZONE \
        --node-labels=gke-no-default-nvidia-gpu-device-plugin=true,nvidia.com/gpu.present=true
    

    Substitua:

    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Forneça uma região para clusters regionais ou uma zona para clusters zonais. Verifique se o local selecionado pertence à mesma região em que as GPUs especificadas estão disponíveis.
    • ZONE: uma zona em que as GPUs especificadas estão disponíveis.
  2. Instale manualmente os drivers no Container-Optimized OS ou nós do Ubuntu. Para instruções detalhadas, consulte Instale manualmente os drivers de GPU NVIDIA.

    • Se estiver usando o COS, execute os comandos a seguir para implantar o DaemonSet de instalação e instalar a versão padrão do driver da GPU:

      kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml
      
    • Se estiver usando o Ubuntu, o DaemonSet de instalação implantado dependerá da GPU e na versão do nó do GKE, conforme descrito nas Seção Ubuntu das instruções.

  3. Extraia e atualize o gráfico do Helm que contém o operador de GPU:

    helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
        && helm repo update
    
  4. Crie um namespace para o operador de GPU:

    kubectl create namespace gpu-operator
    
  5. Crie um ResourceQuota no namespace gpu-operator. O ResourceQuota permite que o operador de GPU implante pods com a mesma prioridade dos pods do sistema Kubernetes.

    kubectl apply -n gpu-operator -f - << EOF
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: gpu-operator-quota
    spec:
      hard:
        pods: 100
      scopeSelector:
        matchExpressions:
        - operator: In
          scopeName: PriorityClass
          values:
            - system-node-critical
            - system-cluster-critical
    EOF
    
  6. Instale o operador de GPU com o script do Helm:

    helm install --wait --generate-name -n gpu-operator nvidia/gpu-operator \
        --set driver.enabled=false \
        --set operator.repository=ghcr.io/nvidia \
        --set operator.version=6171a52d \
        --set validator.repository=ghcr.io/nvidia/gpu-operator \
        --set validator.version=6171a52d \
        --set toolkit.repository=ghcr.io/nvidia \
        --set toolkit.version=5d9b27f1-ubuntu20.04 \
        --set gfd.repository=ghcr.io/nvidia \
        --set gfd.version=f171c926-ubi9 \
        --set cdi.enabled=true \
        --set hostPaths.driverInstallDir=/home/kubernetes/bin/nvidia \
        --set toolkit.installDir=/home/kubernetes/bin/nvidia
    

Preparar o ambiente para TPUs

Crie um pool de nós que use TPUs. O exemplo a seguir cria um pool de nós da TPU Trillium:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster CLUSTER_NAME --num-nodes 1 \
    --location CONTROL_PLANE_LOCATION \
    --node-labels "gke-no-default-tpu-device-plugin=true,gke-no-default-tpu-dra-plugin=true" \
    --machine-type=ct6e-standard-8t \
    --enable-autoupgrade

Substitua o seguinte: * NODEPOOL_NAME: o nome do pool de nós. * CLUSTER_NAME: o nome do cluster. * CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Forneça uma região para clusters regionais ou uma zona para clusters zonais.

Acessar e instalar drivers do DRA

As seções a seguir mostram como instalar drivers de DRA para GPUs e TPUs. Os drivers da DRA permitem que o Kubernetes aloque dinamicamente os dispositivos conectados às cargas de trabalho. É possível instalar drivers DRA para GPUs e TPUs com o gráfico do Helm fornecido. Para acessar os gráficos do Helm, siga estas etapas:

  1. Clone o repositório ai-on-gke para acessar os gráficos do Helm que contêm os drivers DRA para GPUs e TPUs:

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke/common-infra.git
    
  2. Navegue até o diretório que contém os gráficos:

    cd common-infra/common/charts
    

Instalar drivers de DRA em GPUs

Depois de ter acesso ao gráfico do Helm que contém drivers DRA, instale o driver DRA para GPUs concluindo a seguinte etapa:

COS

helm upgrade -i --create-namespace --namespace nvidia nvidia-dra-driver-gpu nvidia-dra-driver-gpu/ \
    --set image.repository=ghcr.io/nvidia/k8s-dra-driver-gpu \
    --set image.tag=d1fad7ed-ubi9 \
    --set image.pullPolicy=Always \
    --set controller.priorityClassName="" \
    --set kubeletPlugin.priorityClassName="" \
    --set nvidiaDriverRoot="/home/kubernetes/bin/nvidia/" \
    --set nvidiaCtkPath=/home/kubernetes/bin/nvidia/toolkit/nvidia-ctk \
    --set deviceClasses="{gpu}" \
    --set gpuResourcesEnabledOverride=true \
    --set resources.computeDomains.enabled=false \
    --set kubeletPlugin.tolerations[0].key=nvidia.com/gpu \
    --set kubeletPlugin.tolerations[0].operator=Exists \
    --set kubeletPlugin.tolerations[0].effect=NoSchedule \
    --set kubeletPlugin.tolerations[1].key=cloud.google.com/compute-class \
    --set kubeletPlugin.tolerations[1].operator=Exists \
    --set kubeletPlugin.tolerations[1].effect=NoSchedule

Ubuntu

helm upgrade -i --create-namespace --namespace nvidia nvidia-dra-driver-gpu nvidia-dra-driver-gpu/ \
    --set image.repository=ghcr.io/nvidia/k8s-dra-driver-gpu \
    --set image.tag=d1fad7ed-ubi9 \
    --set image.pullPolicy=Always \
    --set controller.priorityClassName="" \
    --set kubeletPlugin.priorityClassName="" \
    --set nvidiaDriverRoot="/opt/nvidia" \
    --set nvidiaCtkPath=/home/kubernetes/bin/nvidia/toolkit/nvidia-ctk \
    --set deviceClasses="{gpu}" \
    --set gpuResourcesEnabledOverride=true \
    --set resources.computeDomains.enabled=false \
    --set kubeletPlugin.tolerations[0].key=nvidia.com/gpu \
    --set kubeletPlugin.tolerations[0].operator=Exists \
    --set kubeletPlugin.tolerations[0].effect=NoSchedule \
    --set kubeletPlugin.tolerations[1].key=cloud.google.com/compute-class \
    --set kubeletPlugin.tolerations[1].operator=Exists \
    --set kubeletPlugin.tolerations[1].effect=NoSchedule

Instalar drivers DRA em TPUs

Depois de ter acesso ao gráfico do Helm que contém os drivers, instale o driver de TPU concluindo a seguinte etapa:

./tpu-dra-driver/install-tpu-dra-driver.sh

Verificar se sua infraestrutura está pronta para o DRA

Confirme se o ResourceSlice lista os dispositivos de hardware que você adicionou:

kubectl get resourceslices -o yaml

Se você usou o exemplo na seção anterior, o ResourceSlice será semelhante ao seguinte, dependendo do tipo de hardware usado:

GPU

apiVersion: v1
items:
- apiVersion: resource.k8s.io/v1beta1
  kind: ResourceSlice
  metadata:
    # lines omitted for clarity
  spec:
    devices:
    - basic:
        attributes:
          architecture:
            string: Turing
          brand:
            string: Nvidia
          cudaComputeCapability:
            version: 7.5.0
          cudaDriverVersion:
            version: 12.2.0
          driverVersion:
            version: 535.230.2
          index:
            int: 0
          minor:
            int: 0
          productName:
            string: Tesla T4
          type:
            string: gpu
          uuid:
            string: GPU-2087ac7a-f781-8cd7-eb6b-b00943cc13ef
        capacity:
          memory:
            value: 15Gi
      name: gpu-0

TPU

apiVersion: v1
items:
- apiVersion: resource.k8s.io/v1beta1
  kind: ResourceSlice
  metadata:
    # lines omitted for clarity
  spec:
    devices:
    - basic:
        attributes:
          index:
            int: 0
          tpuGen:
            string: v6e
          uuid:
            string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
      name: "0"
    - basic:
        attributes:
          index:
            int: 1
          tpuGen:
            string: v6e
          uuid:
            string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
      name: "1"
    - basic:
        attributes:
          index:
            int: 2
          tpuGen:
            string: v6e
          uuid:
            string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
      name: "2"
    - basic:
        attributes:
          index:
            int: 3
          tpuGen:
            string: v6e
          uuid:
            string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
      name: "3"
    driver: tpu.google.com
    nodeName: gke-tpu-b4d4b61b-fwbg
    pool:
      generation: 1
      name: gke-tpu-b4d4b61b-fwbg
      resourceSliceCount: 1
kind: List
metadata:
  resourceVersion: ""

A seguir