Condividi tramite


Usare le GPU per carichi di lavoro a elevato utilizzo di calcolo nel servizio Azure Kubernetes

Le unità di elaborazione grafica (GPU) sono spesso usate per carichi di lavoro a elevato utilizzo di calcolo, ad esempio i carichi di lavoro di visualizzazione o di grafica. Il servizio Azure Kubernetes supporta pool di nodi Linux abilitati per GPU per eseguire carichi di lavoro Kubernetes a elevato utilizzo di calcolo.

Questo articolo illustra come effettuare il provisioning dei nodi con GPU pianificabili in cluster del servizio Azure Kubernetes nuovi ed esistenti.

Macchine virtuali abilitate per GPU supportate

Per visualizzare le macchine virtuali abilitate per GPU supportate, vedere Dimensioni delle macchine virtuali ottimizzate per la GPU in Azure. Per i pool di nodi di Azure Kubernetes Service, si consiglia una dimensione minima di Standard_NC6s_v3. La serie NVv4 (basata sulle GPU AMD) non è supportata nel servizio Azure Kubernetes.

Annotazioni

Le macchine virtuali abilitate per la GPU contengono hardware specializzato soggetto a prezzi maggiori e alla disponibilità regionale. Per altre informazioni, vedere il calcolatore dei prezzi e la disponibilità a livello di area.

Limitazioni

  • Se si usa un pool di nodi abilitato per GPU Linux di Azure, le patch di sicurezza automatiche non vengono applicate. Per il comportamento predefinito del canale di aggiornamento del sistema operativo del nodo, fare riferimento alla versione corrente dell'API AKS.

Annotazioni

Per la versione dell'API Azure Kubernetes Service (AKS) 2023-06-01 o successiva, il canale predefinito per l'aggiornamento del sistema operativo del nodo è NodeImage. Per le versioni precedenti, il canale predefinito è Nessuno. Per altre informazioni, vedere Aggiornamento automatico.

  • L'aggiornamento di un pool di nodi esistente per aggiungere le dimensioni della macchina virtuale GPU non è supportato nel servizio Azure Kubernetes.

Annotazioni

L'immagine GPU del servizio Azure Kubernetes (anteprima) viene ritirata a partire dal 10 gennaio 2025. L'intestazione personalizzata non è più disponibile, ovvero non è possibile creare nuovi pool di nodi abilitati per GPU usando l'immagine GPU del servizio Azure Kubernetes. È consigliabile eseguire la migrazione a o usare la configurazione GPU predefinita anziché l'immagine GPU, perché l'immagine GPU non è più supportata. Per altre informazioni, vedere Note sulla versione del servizio Azure Kubernetes o visualizzare questo annuncio di ritiro nella roadmap pubblica del servizio Azure Kubernetes.

Prima di iniziare

Ottenere le credenziali per il cluster

Ottenere le credenziali per il cluster del servizio Azure Kubernetes usando il comando az aks get-credentials. Il comando di esempio seguente ottiene le credenziali per myAKSCluster nel gruppo di risorse myResourceGroup :

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

Opzioni per l'uso di GPU NVIDIA

L'uso di GPU NVIDIA prevede l'installazione di vari componenti software NVIDIA, ad esempio il plug-in del dispositivo NVIDIA per Kubernetes, l'installazione del driver GPU e altro ancora.

Annotazioni

Per impostazione predefinita, Microsoft gestisce automaticamente la versione dei driver NVIDIA come parte della distribuzione dell'immagine del nodo e AKS lo gestisce e supporta. Mentre i driver NVIDIA vengono installati per impostazione predefinita nei nodi con supporto gpu, è necessario installare il plug-in del dispositivo.

Installazione del plug-in del dispositivo NVIDIA

L'installazione del plug-in del dispositivo NVIDIA è necessaria quando si usano GPU su AKS. In alcuni casi, l'installazione viene gestita automaticamente, ad esempio quando si usa l'operatore GPU NVIDIA. In alternativa, è possibile installare manualmente il plug-in del dispositivo NVIDIA.

Installare manualmente il plug-in del dispositivo NVIDIA

È possibile distribuire un DaemonSet per il plug-in del dispositivo NVIDIA, che esegue un pod in ogni nodo per fornire i driver necessari per le GPU. Questo è l'approccio consigliato quando si usano pool di nodi abilitati per GPU per Azure Linux.

Per utilizzare la SKU OS predefinita, creare il pool di nodi senza specificare una SKU OS. Il pool di nodi è configurato per il sistema operativo predefinito in base alla versione Kubernetes del cluster.

  1. Aggiungere un pool di nodi al cluster usando il comando az aks nodepool add.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --node-taints sku=gpu:NoSchedule \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    Questo comando aggiunge un pool di nodi denominato gpunp a myAKSCluster in myResourceGroup e usa i parametri per configurare le impostazioni del pool di nodi seguenti:

    • --node-vm-size: imposta le dimensioni della macchina virtuale per il nodo nel pool di nodi su Standard_NC6s_v3.
    • --node-taints: Specifica un taint sku=gpu:NoSchedule nel pool di nodi.
    • --enable-cluster-autoscaler: abilita il ridimensionamento automatico del cluster.
    • --min-count: configura il ridimensionamento automatico del cluster per mantenere almeno un nodo nel pool di nodi.
    • --max-count: configura il ridimensionamento automatico del cluster per mantenere un massimo di tre nodi nel pool di nodi.

    Annotazioni

    Le dimensioni di Taints e VM possono essere impostate solo per i pool di nodi durante la creazione del pool di nodi, ma è possibile aggiornare le impostazioni di scalabilità automatica in qualsiasi momento.

  1. Creare uno spazio dei nomi usando il comando kubectl create namespace.

    kubectl create namespace gpu-resources
    
  2. Creare un file denominato nvidia-device-plugin-ds.yaml e incollare il manifesto YAML seguente fornito come parte del progetto NVIDIA device plugin for Kubernetes:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nvidia-device-plugin-daemonset
      namespace: gpu-resources
    spec:
      selector:
        matchLabels:
          name: nvidia-device-plugin-ds
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            name: nvidia-device-plugin-ds
        spec:
          tolerations:
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
          # Mark this pod as a critical add-on; when enabled, the critical add-on
          # scheduler reserves resources for critical add-on pods so that they can
          # be rescheduled after a failure.
          # See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/
          priorityClassName: "system-node-critical"
          containers:
          - image: nvcr.io/nvidia/k8s-device-plugin:v0.17.2
            name: nvidia-device-plugin-ctr
            env:
              - name: FAIL_ON_INIT_ERROR
                value: "false"
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop: ["ALL"]
            volumeMounts:
            - name: device-plugin
              mountPath: /var/lib/kubelet/device-plugins
          volumes:
          - name: device-plugin
            hostPath:
              path: /var/lib/kubelet/device-plugins
    
  3. Creare il DaemonSet e verificare che il plug-in del dispositivo NVIDIA sia stato creato correttamente usando il comando kubectl apply.

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. Dopo aver installato correttamente il plug-in del dispositivo NVIDIA, è possibile verificare che le GPU siano pianificabili ed eseguano un carico di lavoro GPU.

Saltare l'installazione del driver GPU

Se si vuole controllare l'installazione dei driver NVIDIA o usare l'operatore GPU NVIDIA, è possibile ignorare l'installazione predefinita del driver GPU. Microsoft non supporta o gestisce la manutenzione e la compatibilità dei driver NVIDIA come parte della distribuzione dell'immagine del nodo.

  1. Creare un pool di nodi usando il comando az aks nodepool add e impostare il campo --gpu-driver su none per ignorare l'installazione predefinita del driver GPU.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --gpu-driver none \
        --node-vm-size Standard_NC6s_v3 \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    L'impostazione del campo API su --gpu-driver durante la none creazione del pool di nodi ignora l'installazione automatica del driver GPU. Tutti i nodi esistenti non vengono modificati. È possibile ridimensionare il pool di nodi a zero e quindi eseguire il backup per rendere effettiva la modifica.

    Se viene visualizzato l'errore unrecognized arguments: --gpu-driver none, aggiorna la versione dell'Azure CLI. Per altre informazioni, vedere Prima di iniziare.

  2. Facoltativamente, è possibile installare l'operatore GPU NVIDIA seguendo questa procedura.

Verificare che le GPU siano pianificabili

Dopo aver creato il cluster, verificare che le GPU siano pianificabili in Kubernetes.

  1. Elencare i nodi nel cluster usando il comando kubectl get nodes.

    kubectl get nodes
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. Verificare che le GPU siano pianificabili usando il comando kubectl describe node.

    kubectl describe node aks-gpunp-28993262-0
    

    Nella sezione Capacity (Capacità) la GPU deve comparire in elenco come nvidia.com/gpu: 1. L'output dovrebbe essere simile all'output di esempio condensato seguente:

    Name:               aks-gpunp-28993262-0
    Roles:              agent
    Labels:             accelerator=nvidia
    
    [...]
    
    Capacity:
    [...]
     nvidia.com/gpu:                 1
    [...]
    

Eseguire un carico di lavoro supportato da GPU

Per vedere la GPU in esecuzione, è possibile pianificare un carico di lavoro abilitato per la GPU con una richiesta di risorse appropriata. In questo esempio verrà eseguito un processo Tensorflow sul set di dati MNIST.

  1. Creare un file denominato samples-tf-mnist-demo.yaml e incollare il manifesto YAML seguente, che include un limite di risorse di nvidia.com/gpu: 1:

    Annotazioni

    Se si riceve un errore di mancata corrispondenza tra versioni quando si accede ai driver, come "la versione del driver CUDA non è sufficiente per la versione di runtime CUDA", esaminare la tabella di compatibilità dei driver NVIDIA.

    apiVersion: batch/v1
    kind: Job
    metadata:
      labels:
        app: samples-tf-mnist-demo
      name: samples-tf-mnist-demo
    spec:
      template:
        metadata:
          labels:
            app: samples-tf-mnist-demo
        spec:
          containers:
          - name: samples-tf-mnist-demo
            image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
            args: ["--max_steps", "500"]
            imagePullPolicy: IfNotPresent
            resources:
              limits:
               nvidia.com/gpu: 1
          restartPolicy: OnFailure
          tolerations:
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
    
  2. Eseguire il processo usando il comando kubectl apply, che analizza il file manifesto e crea gli oggetti Kubernetes definiti.

    kubectl apply -f samples-tf-mnist-demo.yaml
    

Visualizzare lo stato del carico di lavoro abilitato per la GPU

  1. Monitorare lo stato di avanzamento del processo usando il comando kubectl get jobs con il flag --watch. Il primo pull dell'immagine e l'elaborazione del set di dati possono richiedere alcuni minuti.

    kubectl get jobs samples-tf-mnist-demo --watch
    

    Quando la colonna COMPLETIONS mostra 1/1, il processo è stato completato correttamente, come illustrato nell'output di esempio seguente:

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. Uscire dal processo kubectl --watch con CTRL-C.

  3. Ottenere il nome del pod usando il comando kubectl get pods.

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. Visualizzare l'output del carico di lavoro abilitato per la GPU usando il comando kubectl logs.

    kubectl logs samples-tf-mnist-demo-smnr6
    

    L'output di esempio condensato seguente dei log dei pod conferma che il dispositivo GPU appropriato, Tesla K80, è stato individuato:

    2019-05-16 16:08:31.258328: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
    2019-05-16 16:08:31.396846: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Found device 0 with properties:
    name: Tesla K80 major: 3 minor: 7 memoryClockRate(GHz): 0.8235
    pciBusID: 2fd7:00:00.0
    totalMemory: 11.17GiB freeMemory: 11.10GiB
    2019-05-16 16:08:31.396886: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 2fd7:00:00.0, compute capability: 3.7)
    2019-05-16 16:08:36.076962: I tensorflow/stream_executor/dso_loader.cc:139] successfully opened CUDA library libcupti.so.8.0 locally
    Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
    Extracting /tmp/tensorflow/input_data/train-images-idx3-ubyte.gz
    Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
    Extracting /tmp/tensorflow/input_data/train-labels-idx1-ubyte.gz
    Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-images-idx3-ubyte.gz
    Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-labels-idx1-ubyte.gz
    Accuracy at step 0: 0.1081
    Accuracy at step 10: 0.7457
    Accuracy at step 20: 0.8233
    Accuracy at step 30: 0.8644
    Accuracy at step 40: 0.8848
    Accuracy at step 50: 0.8889
    Accuracy at step 60: 0.8898
    Accuracy at step 70: 0.8979
    Accuracy at step 80: 0.9087
    Accuracy at step 90: 0.9099
    Adding run metadata for 99
    Accuracy at step 100: 0.9125
    Accuracy at step 110: 0.9184
    Accuracy at step 120: 0.922
    Accuracy at step 130: 0.9161
    Accuracy at step 140: 0.9219
    Accuracy at step 150: 0.9151
    Accuracy at step 160: 0.9199
    Accuracy at step 170: 0.9305
    Accuracy at step 180: 0.9251
    Accuracy at step 190: 0.9258
    Adding run metadata for 199
    [...]
    Adding run metadata for 499
    

Pulire le risorse

Rimuovere gli oggetti Kubernetes associati creati in questo articolo usando il comando kubectl delete job.

kubectl delete jobs samples-tf-mnist-demo

Passaggi successivi