Utiliser des GPU pour les charges de travail nécessitant beaucoup de ressources système sur Azure Kubernetes Service (AKS)

Les processeurs graphiques (GPU) sont souvent utilisés pour les charges de travail nécessitant beaucoup de ressources système, comme le traitement graphique et la visualisation. AKS prend en charge les pools de nœuds Linux avec GPU pour exécuter des charges de travail Kubernetes gourmandes en calcul.

Cet article vous aide à approvisionner des nœuds avec des GPU programmables sur des clusters AKS nouveaux et existants.

Machines virtuelles compatibles GPU prises en charge

Pour voir les machines virtuelles compatibles GPU prises en charge, consultez Tailles de machines virtuelles optimisées pour les GPU dans Azure. Pour les pools de nœuds AKS, nous recommandons une taille minimale Standard_NC6s_v3. La série NVv4 (basée sur des processeurs AMD) n’est pas prise en charge sur AKS.

Remarque

Les machines virtuelles avec GPU contiennent du matériel spécialisé, plus cher et dépendant de la disponibilité régionale. Pour plus d’informations, voir l’outil de tarification et la disponibilité régionale.

Limites

  • Si vous utilisez un pool de nœuds avec GPU Linux Azure, les correctifs de sécurité automatiques ne sont pas appliqués. Reportez-vous à votre version actuelle de l’API AKS pour le comportement par défaut du canal de mise à niveau du système d’exploitation de nœud.

Remarque

Pour l’API AKS version 2023-06-01 ou ultérieure, le canal par défaut pour la mise à niveau du système d’exploitation de nœud est NodeImage. Pour les versions précédentes, le canal par défaut est Aucun. Pour plus d’informations, consultez mise à niveau automatique.

  • La série NVadsA10 v5 n’est pas une référence SKU recommandée pour le disque dur virtuel GPU.
  • La mise à jour d’un pool de nœuds existant pour ajouter un GPU n’est pas prise en charge.

Avant de commencer

  • Cet article suppose que vous disposez d’un cluster AKS. Si vous avez besoin d’un cluster, créez-en un à l'aide d’Azure CLI, d’Azure PowerShell ou du Portail Azure.
  • La version 2.0.64 ou ultérieure d’Azure CLI doit être installée et configurée. Exécutez az --version pour trouver la version. Si vous devez installer ou mettre à niveau, voir Installer Azure CLI.

Obtenir les informations d’identification de votre cluster

Obtenez les informations d’identification de votre cluster AKS à l’aide de la commande az aks get-credentials. L’exemple de commande suivant récupère les informations d’identification du cluster myAKSCluster dans le groupe de ressources myResourceGroup :

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

Options d’utilisation des GPU NVIDIA

L’utilisation de GPU NVIDIA implique l’installation de différents composants logiciels NVIDIA, tels que le plug-in d’appareil NVIDIA pour Kubernetes, l’installation du pilote GPU, etc.

Remarque

Par défaut, Microsoft gère automatiquement la version des pilotes NVidia dans le cadre du déploiement d’images de nœud, et AKS prend en charge et gère cette fonctionnalité. Bien que les pilotes NVidia soient installés par défaut sur les nœuds compatibles du processeur graphique, vous devez installer le plug-in d’appareil.

Installation du plug-in d’appareil NVIDIA

L’installation du plug-in d’appareil NVIDIA est requise pour l’utilisation de GPU sur AKS. Dans certains cas, l’installation est gérée automatiquement, par exemple lors de l’utilisation de l’opérateur GPU NVIDIA ou de l’image GPU AKS (préversion). Vous pouvez également installer manuellement le plug-in d’appareil NVIDIA.

Installer manuellement le plug-in de périphérique NVIDIA

Vous pouvez déployer un DaemonSet pour le plug-in d’appareil NVIDIA, qui exécute un pod sur chaque nœud afin de fournir les pilotes requis pour les GPU. Il s’agit de l’approche recommandée lors de l’utilisation de pools de nœuds avec GPU pour Azure Linux.

Pour utiliser la référence SKU de système d’exploitation par défaut, vous créez le pool de nœuds sans spécifier de référence SKU de système d’exploitation. Le pool de nœuds est configuré pour le système d’exploitation par défaut en fonction de la version Kubernetes du cluster.

  1. Ajoutez un pool de nœuds à votre cluster avec la commande 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
    

    Cette commande ajoute un pool de nœuds nommé gpunp à myAKSCluster dans myResourceGroup et utilise des paramètres pour configurer les paramètres de pool de nœuds suivants :

    • --node-vm-size : définit la taille de machine virtuelle du nœud dans le pool de nœuds sur Standard_NC6s_v3.
    • --node-taints : spécifie une teinte sku=gpu:NoSchedule sur le pool de nœuds.
    • --enable-cluster-autoscaler : active l’autoscaler de cluster.
    • --min-count : configure l’autoscaler de cluster pour conserver au minimum un nœud dans le pool de nœuds.
    • --max-count : configure l’autoscaler de cluster pour conserver un maximum de trois nœuds dans le pool de nœuds.

    Notes

    Les teintes et les tailles de machines virtuelles ne peuvent être définies pour les pools de nœuds uniquement lors de leur création, mais vous pouvez mettre à jour les paramètres de mise à l’échelle automatique à tout moment.

  1. Créez un espace de noms à l’aide de la commande kubectl create namespace.

    kubectl create namespace gpu-resources
    
  2. Créez un fichier nommé nvidia-device-plugin-ds.yaml et collez le manifeste YAML suivant fourni dans le cadre du projet de plug-in d’appareil NVIDIA pour Kubernetes :

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nvidia-device-plugin-daemonset
      namespace: kube-system
    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.15.0
            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. Créez le DaemonSet et vérifiez que le plug-in d’appareil NVIDIA a été créé à l’aide de la commande kubectl apply.

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. Maintenant que vous avez correctement installé le plug-in d’appareil NVIDIA, vous pouvez vérifier que vos GPU sont planifiables et exécuter une charge de travail GPU.

Ignorer l’installation du pilote GPU (préversion)

Si vous souhaitez contrôler l’installation des pilotes NVidia ou utiliser l’opérateur GPU NVIDIA, vous pouvez ignorer l’installation du pilote GPU par défaut. Microsoft ne prend pas en charge et ne gère pas la maintenance et la compatibilité des pilotes NVidia dans le cadre du déploiement d’images de nœud.

Important

Les fonctionnalités d’évaluation AKS sont disponibles en libre-service et font l’objet d’un abonnement. Les préversions sont fournies « en l’état » et « en fonction des disponibilités », et sont exclues des contrats de niveau de service et de la garantie limitée. Les préversions AKS sont, dans la mesure du possible, partiellement couvertes par le service clientèle. Telles quelles, ces fonctionnalités ne sont pas destinées à une utilisation en production. Pour plus d’informations, consultez les articles de support suivants :

  1. Inscrivez ou mettez à jour l’extension aks-preview à l’aide de la commande az extension add ou az extension update.

    # Register the aks-preview extension
    az extension add --name aks-preview
    
    # Update the aks-preview extension
    az extension update --name aks-preview
    
  2. Créez un pool de nœuds à l’aide de la commande az aks nodepool add avec l’indicateur --skip-gpu-driver-install pour ignorer l’installation automatique du pilote GPU.

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

    L’ajout de l’indicateur --skip-gpu-driver-install pendant la création du pool de nœuds permet d’ignorer l’installation automatique du pilote GPU. Les nœuds existants ne sont pas modifiés. Vous pouvez mettre à l’échelle le pool de nœuds sur zéro, puis sauvegarder pour que la modification prenne effet.

Utiliser l’opérateur GPU NVIDIA avec AKS

L’opérateur GPU NVIDIA automatise la gestion de tous les composants logiciels NVIDIA nécessaires à l’approvisionnement du GPU, notamment l’installation du pilote, le plug-in d’appareil NVIDIA pour Kubernetes, le runtime de conteneur NVIDIA, etc. Étant donné que l’opérateur GPU gère ces composants, il n’est pas nécessaire d’installer manuellement le plug-in d’appareil NVIDIA. Cela signifie également que l’installation automatique du pilote GPU sur AKS n’est plus nécessaire.

  1. Ignorez l’installation automatique du pilote GPU en créant un pool de nœuds à l’aide de la commande az aks nodepool add avec --skip-gpu-driver-install. L’ajout de l’indicateur --skip-gpu-driver-install pendant la création du pool de nœuds permet d’ignorer l’installation automatique du pilote GPU. Les nœuds existants ne sont pas modifiés. Vous pouvez mettre à l’échelle le pool de nœuds sur zéro, puis sauvegarder pour que la modification prenne effet.

  2. Suivez la documentation NVIDIA pour Installer l’opérateur GPU.

  3. Maintenant que vous avez correctement installé l’opérateur GPU, vous pouvez vérifier que vos GPU sont planifiables et exécuter une charge de travail GPU.

Avertissement

Nous vous déconseillons d’installer manuellement le démon du plug-in d’appareil NVIDIA défini avec des clusters à l’aide de l’image GPU AKS.

Remarque

Il peut y avoir des considérations supplémentaires à prendre en compte lors de l’utilisation de l’opérateur GPU NVIDIA et du déploiement sur des instances SPOT. Veuillez consulter https://github.com/NVIDIA/gpu-operator/issues/577

Utiliser l’image GPU AKS (préversion)

Remarque

L’image GPU AKS (préversion) sera supprimée le 10 janvier 2025. L’en-tête personnalisé utilisé ci-dessous ne sera plus disponible, ce qui signifie que vous ne pourrez plus créer de pools de nœuds compatibles GPU à l’aide de l’image GPU AKS. Nous vous recommandons de migrer vers ou d’utiliser la configuration GPU par défaut plutôt que l’image GPU dédiée, car l’image GPU dédiée n’est plus prise en charge. Pour plus d’informations, consultez les notes de publication d’AKS ou consultez cette annonce de mise hors service dans notre feuille de route publique AKS.

AKS fournit une image AKS entièrement configurée qui contient le plug-in d’appareil NVIDIA pour Kubernetes. L’image GPU AKS est actuellement disponible uniquement sur Ubuntu 18.04.

Important

Les fonctionnalités d’évaluation AKS sont disponibles en libre-service et font l’objet d’un abonnement. Les préversions sont fournies « en l’état » et « en fonction des disponibilités », et sont exclues des contrats de niveau de service et de la garantie limitée. Les préversions AKS sont, dans la mesure du possible, partiellement couvertes par le service clientèle. Telles quelles, ces fonctionnalités ne sont pas destinées à une utilisation en production. Pour plus d’informations, consultez les articles de support suivants :

  1. Installez l’extension aks-preview Azure CLI à l’aide de la commande az extension add.

    az extension add --name aks-preview
    
  2. Mettez à jour vers la dernière version de l’extension à l’aide de la commande az extension update.

    az extension update --name aks-preview
    
  3. Inscrivez l’indicateur de fonctionnalité GPUDedicatedVHDPreview à l’aide de la commande az feature register.

    az feature register --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    

    Quelques minutes sont nécessaires pour que l’état s’affiche Registered (Inscrit).

  4. Vérifiez l’état de l’inscription en utilisant la commande az feature show.

    az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    
  5. Quand l’état reflète Inscrit, actualisez l’inscription du fournisseur de ressources Microsoft.ContainerService à l’aide de la commande az provider register.

    az provider register --namespace Microsoft.ContainerService
    

    Maintenant que vous avez mis à jour votre cluster pour utiliser l’image GPU AKS, vous pouvez ajouter un pool de nœuds pour les nœuds GPU à votre cluster.

  6. Ajoutez un pool de nœuds à l’aide de la commande 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 \
        --aks-custom-headers UseGPUDedicatedVHD=true \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    L’exemple de commande précédent ajoute un pool de nœuds nommé gpunp à myAKSCluster dans myResourceGroup et utilise des paramètres pour configurer les paramètres de pool de nœuds suivants :

    • --node-vm-size : définit la taille de machine virtuelle du nœud dans le pool de nœuds sur Standard_NC6s_v3.
    • --node-taints : spécifie une teinte sku=gpu:NoSchedule sur le pool de nœuds.
    • --aks-custom-headers : spécifie une image GPU AKS spécialisée, UseGPUDedicatedVHD=true. Si la référence SKU de votre GPU requiert la génération de deux machines virtuelles, utilisez plutôt --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true.
    • --enable-cluster-autoscaler : active l’autoscaler de cluster.
    • --min-count : configure l’autoscaler de cluster pour conserver au minimum un nœud dans le pool de nœuds.
    • --max-count : configure l’autoscaler de cluster pour conserver un maximum de trois nœuds dans le pool de nœuds.

    Notes

    Les teintes et les tailles de machines virtuelles ne peuvent être définies pour les pools de nœuds uniquement lors de leur création, mais vous pouvez mettre à jour les paramètres de mise à l’échelle automatique à tout moment.

  7. Maintenant que vous avez créé un pool de nœuds à l’aide de l’image GPU, vous pouvez vérifier que vos GPU sont planifiables et exécuter une charge de travail GPU.

Vérifier que les GPU sont planifiables

Après avoir créé votre cluster, vérifiez que les GPU sont planifiables dans Kubernetes.

  1. Répertoriez les nœuds de votre cluster à l’aide de la commande kubectl get nodes.

    kubectl get nodes
    

    Vous devez obtenir un résultat semblable à l’exemple de sortie qui suit :

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. Vérifiez que les GPU peuvent être planifiés à l’aide de la commande kubectl describe node.

    kubectl describe node aks-gpunp-28993262-0
    

    Sous la section Capacité, le GPU doit apparaître ainsi : nvidia.com/gpu: 1. Le résultat doit être similaire à l’exemple condensé de sortie suivant :

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

Exécuter une charge de travail compatible GPU

Pour voir le GPU en action, vous pouvez planifier une charge de travail compatible GPU avec la demande de ressource correspondante. Dans cet exemple, nous exécutons une tâche Tensorflow sur le jeu de données MNIST.

  1. Créez un fichier nommé samples-tf-mnist-demo.yaml et collez le manifeste YAML suivant, qui inclut une limite de ressources de nvidia.com/gpu: 1 :

    Notes

    Si vous recevez une erreur d’incompatibilité de version lorsque vous appelez des pilotes (par exemple, la version du pilote CUDA est insuffisante pour la version du runtime CUDA), consultez la matrice de compatibilité des pilotes 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. Exécutez le travail à l’aide de la commande kubectl apply, qui analyse le fichier manifeste et crée les objets Kubernetes définis.

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

Afficher l’état de la charge de travail compatible GPU

  1. Supervisez la progression du travail à l’aide de la commande kubectl get jobs avec l’indicateur --watch. L’extraction de l’image, puis le traitement du jeu de données peuvent prendre quelques minutes.

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

    Lorsque la colonne COMPLETIONS affiche 1/1, le travail s’est terminé avec succès, comme indiqué dans l’exemple de sortie suivant :

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. Quittez le processus kubectl --watch avec Ctrl-C.

  3. Procurez-vous le nom du pod avec la commande kubectl get pods.

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. Affichez la sortie de la charge de travail avec GPU à l’aide de la commande kubectl logs.

    kubectl logs samples-tf-mnist-demo-smnr6
    

    L’exemple de sortie condensé suivant des journaux de pod confirme que l’appareil GPU approprié, Tesla K80, a été découvert :

    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
    

Utiliser Container Insights pour surveiller l’utilisation du GPU

Container Insights avec AKS supervise les métriques d’utilisation de GPU suivantes :

Nom de métrique Dimension de la métrique (balises) Description
containerGpuDutyCycle container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Pourcentage de temps durant lequel le GPU est resté occupé/en cours de traitement pour un conteneur au cours de la période d’échantillonnage passée (60 secondes). Le cycle d’utilisation est un nombre compris entre 1 et 100.
containerGpuLimits container.azm.ms/clusterId, container.azm.ms/clusterName, containerName Chaque conteneur peut spécifier des limites pour un ou plusieurs GPU. Il n’est pas possible de demander ou de limiter une partie d’un GPU.
containerGpuRequests container.azm.ms/clusterId, container.azm.ms/clusterName, containerName Chaque conteneur peut demander un ou plusieurs GPU. Il n’est pas possible de demander ou de limiter une partie d’un GPU.
containerGpumemoryTotalBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Quantité de mémoire de GPU en octets à disposition pour un conteneur spécifique.
containerGpumemoryUsedBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Quantité de mémoire de GPU en octets utilisée par un conteneur spécifique.
nodeGpuAllocatable container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor Nombre de GPU dans un nœud pouvant être utilisés par Kubernetes.
nodeGpuCapacity container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor Nombre total de GPU présents dans un nœud.

Nettoyer les ressources

  • Supprimez les objets Kubernetes associés que vous avez créés dans cet article à l’aide de la commande kubectl delete job.

    kubectl delete jobs samples-tf-mnist-demo
    

Étapes suivantes