Freigeben über


Verwenden von GPUs für computeintensive Workloads in Azure Kubernetes Service (AKS)

GPUs (Graphical Processing Units) werden häufig für computeintensive Workloads (also etwa für grafikintensive und visualisierungsorientierte Workloads) verwendet. AKS unterstützt GPU-fähige Linux-Knotenpools, um computeintensive Kubernetes-Workloads auszuführen.

Dieser Artikel unterstützt Sie beim Bereitstellen von Knoten mit planbaren GPUs auf neuen und vorhandenen AKS-Clustern.

Unterstützte GPU-fähige VMs

Informationen zum Anzeigen unterstützter GPU-aktivierter VMs finden Sie unter GPU-optimierte VM-Größen in Azure. Für AKS-Knotenpools wird die Mindestgröße Standard_NC6s_v3 empfohlen. Die NVv4-Serie (basierend auf AMD-GPUs) wird von AKS nicht unterstützt.

Hinweis

GPU-fähige virtuelle Computer verfügen über spezielle Hardware, für die höhere Preise gelten und die möglicherweise nicht in allen Regionen verfügbar ist. Weitere Informationen finden Sie in der Preisübersicht sowie auf der Website zur regionalen Verfügbarkeit.

Begrenzungen

  • Bei Verwendung eines Azure Linux-GPU-Knotenpools werden keine automatischen Sicherheitspatches angewendet, und das Standardverhalten für den Cluster ist Nicht verwaltet. Weitere Informationen finden Sie unter Automatisches Upgrade.
  • Die NVadsA10 v5-Serie ist keine empfohlene SKU für GPU-VHD.
  • Das Aktualisieren eines vorhandenen Knotenpools zum Hinzufügen von GPU wird nicht unterstützt.

Voraussetzungen

  • In diesem Artikel wird vorausgesetzt, dass Sie über einen AKS-Cluster verfügen. Wenn Sie keinen Cluster haben, erstellen Sie einen mithilfe der Azure CLI, der Azure PowerShell oder im Azure-Portal.
  • Azure CLI Version 2.0.64 oder höher muss installiert und konfiguriert sein. Führen Sie az --version aus, um die Version zu ermitteln. Informationen zum Durchführen einer Installation oder eines Upgrades finden Sie bei Bedarf unter Installieren der Azure CLI.

Abrufen der Anmeldeinformationen für Ihren Cluster

  • Laden Sie die Anmeldeinformationen für den AKS-Cluster mit dem Befehl az aks get-credentials. Im folgenden Beispiel werden die Anmeldeinformationen für den Cluster myAKSCluster in der Ressourcengruppe myResourceGroup abgerufen:

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

Optionen für die Verwendung von NVIDIA GPUs

Die Verwendung von NVIDIA-GPUs umfasst die Installation verschiedener NVIDIA-Softwarekomponenten wie des NVIDIA-Geräte-Plug-Ins für Kubernetes, des GPU-Treibers u. v. m.

Überspringen der GPU-Treiberinstallation (Vorschau)

AKS bietet standardmäßig eine automatische Installation von GPU-Treibern. In einigen Fällen, z. B. bei der Installation eigener Treiber oder der Verwendung des NVIDIA-GPU-Operators, sollten Sie die Installation des GPU-Treibers überspringen.

Wichtig

AKS-Previewfunktionen stehen gemäß dem Self-Service- und Aktivierungsprinzip zur Verfügung. Vorschauversionen werden „wie besehen“ und „wie verfügbar“ bereitgestellt und sind von Service Level Agreements und der Herstellergarantie ausgeschlossen. AKS-Vorschauversionen werden teilweise vom Kundensupport auf Grundlage der bestmöglichen Leistung abgedeckt. Daher sind diese Funktionen nicht für die Verwendung in der Produktion vorgesehen. Weitere Informationen finden Sie in den folgenden Supportartikeln:

  1. Registrieren oder aktualisieren Sie die Erweiterung „aks-preview“ mithilfe des Befehls az extension add oder 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. Erstellen Sie einen Knotenpool mit dem Befehl az aks nodepool add und dem Flag --skip-gpu-driver-install, um die automatische Installation des GPU-Treibers zu überspringen.

    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
    

    Durch das Hinzufügen des Flags --skip-gpu-driver-install während der Erstellung des Knotenpools wird die automatische Installation des GPU-Treibers übersprungen. Vorhandene Knoten werden nicht geändert. Sie können den Knotenpool auf null skalieren und dann sichern, um die Änderung anzuwenden.

Installation des NVIDIA-Geräte-Plug-Ins

Bei Verwendung von GPUs in AKS ist die Installation des NVIDIA-Geräte-Plug-Ins erforderlich. In einigen Fällen erfolgt die Installation automatisch, z. B. bei Verwendung des NVIDIA-GPU-Operators oder des AKS-GPU-Image (Vorschau). Alternativ können Sie das NVIDIA-Geräte-Plug-In auch manuell installieren.

Manuelles Installieren des NVIDIA-Geräte-Plug-Ins

Sie können ein DaemonSet für das NVIDIA-Geräte-Plug-In bereitstellen, das einen Pod auf jedem Knoten ausführt, um die erforderlichen Treiber für die GPUs bereitzustellen. Dies ist der empfohlene Ansatz bei der Verwendung von GPU-fähigen Knotenpools für Azure Linux.

Um die Standardbetriebssystem-SKU zu verwenden, erstellen Sie den Knotenpool, ohne eine Betriebssystem-SKU anzugeben. Der Knotenpool wird basierend auf der Kubernetes-Version des Clusters für das Standardbetriebssystem konfiguriert.

  1. Fügen Sie Ihrem Cluster mithilfe des Befehls az aks nodepool add einen Knotenpool hinzu.

    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
    

    Dieser Beispielbefehl fügt myAKSCluster in myResourceGroup einen Knotenpool namens gpunp hinzu und verwendet Parameter, um die folgenden Knotenpooleinstellungen zu konfigurieren:

    • --node-vm-size: legt die VM-Größe für den Knoten im Knotenpool auf Standard_NC6s_v3 fest.
    • --node-taints: Gibt einen sku=gpu:NoSchedule-Taint für den Knotenpool an.
    • --enable-cluster-autoscaler: Aktiviert die Autoskalierung für Cluster.
    • --min-count: Konfiguriert die automatische Clusterskalierung so, dass mindestens ein Knoten im Knotenpool beibehalten wird.
    • --max-count: Konfiguriert die automatische Clusterskalierung so, dass höchstens drei Knoten im Knotenpool beibehalten werden.

    Hinweis

    Taints und VM-Größen können für Knotenpools nur während ihrer Erstellung festgelegt werden, aber Sie können die Autoskalierungseinstellungen jederzeit aktualisieren.

  1. Erstellen Sie mithilfe des Befehls kubectl create namespace einen Namespace.

    kubectl create namespace gpu-resources
    
  2. Erstellen Sie eine Datei namens nvidia-device-plugin-ds.yaml, und fügen Sie das folgende YAML-Manifest ein, das als Teil des NVIDIA-Geräte-Plug-Ins für Kubernetes-Projekt bereitgestellt wird:

    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: nvidia.com/gpu
            operator: Exists
            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. Erstellen Sie das DaemonSet, und vergewissern Sie sich, dass das NVIDIA-Geräte-Plug-In erfolgreich erstellt wurde, mit dem Befehl kubectl apply.

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. Nachdem Sie das NVIDIA-Geräte-Plug-In erfolgreich installiert haben, können Sie überprüfen, ob Ihre GPUs planbar sind, und eine GPU-Workload ausführen.

Verwenden des NVIDIA GPU-Operators mit AKS

Der NVIDIA-GPU-Operator automatisiert die Verwaltung aller NVIDIA-Softwarekomponenten, die für die Bereitstellung von GPUs erforderlich sind, einschließlich der Installation des Treibers, des NVIDIA-Geräte-Plug-Ins für Kubernetes, der NVIDIA-Containerruntime u. v. m. Da der GPU-Operator diese Komponenten verarbeitet, ist es nicht erforderlich, das NVIDIA-Geräte-Plug-In manuell zu installieren. Dies bedeutet auch, dass in AKS keine automatische GPU-Treiberinstallation mehr erforderlich ist.

  1. Überspringen Sie die automatische GPU-Treiberinstallation, indem Sie mithilfe des Befehls az aks nodepool add mit --skip-gpu-driver-install einen Knotenpool erstellen. Durch das Hinzufügen des Flags --skip-gpu-driver-install während der Erstellung des Knotenpools wird die automatische Installation des GPU-Treibers übersprungen. Vorhandene Knoten werden nicht geändert. Sie können den Knotenpool auf null skalieren und dann sichern, um die Änderung anzuwenden.

  2. Befolgen Sie die NVIDIA-Dokumentation, um den GPU-Operator zu installieren.

  3. Nachdem Sie nun den GPU-Operator erfolgreich installiert haben, können Sie überprüfen, ob Ihre GPUs planbar sind, und eine GPU-Workload ausführen.

Warnung

Es wird nicht empfohlen, das DaemonSet des NVIDIA-Geräte-Plug-Ins manuell auf Clustern zu installieren, die das AKS GPU-Image verwenden.

Verwenden des AKS-GPU-Image (Vorschau)

AKS stellt ein vollständig konfiguriertes AKS-Image bereit, das das NVIDIA-Geräte-Plug-In für Kubernetes bereits enthält. Das AKS-GPU-Image wird derzeit nur für Ubuntu 18.04 unterstützt.

Wichtig

AKS-Previewfunktionen stehen gemäß dem Self-Service- und Aktivierungsprinzip zur Verfügung. Vorschauversionen werden „wie besehen“ und „wie verfügbar“ bereitgestellt und sind von Service Level Agreements und der Herstellergarantie ausgeschlossen. AKS-Vorschauversionen werden teilweise vom Kundensupport auf Grundlage der bestmöglichen Leistung abgedeckt. Daher sind diese Funktionen nicht für die Verwendung in der Produktion vorgesehen. Weitere Informationen finden Sie in den folgenden Supportartikeln:

  1. Installieren Sie die Azure CLI-Speichererweiterung aks-preview mit dem Befehl az extension add.

    az extension add --name aks-preview
    
  2. Führen Sie mit dem Befehl az extension update ein Update auf die neueste Version der Erweiterung aus.

    az extension update --name aks-preview
    
  3. Registrieren Sie das Featureflag GPUDedicatedVHDPreview mithilfe des Befehls az feature register.

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

    Es dauert einige Minuten, bis der Status Registered (Registriert) angezeigt wird.

  4. Überprüfen Sie den Registrierungsstatus mithilfe des Befehls az feature show.

    az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    
  5. Wenn der Zustand Registered (Registriert) lautet, aktualisieren Sie die Registrierung des Ressourcenanbieters Microsoft.ContainerService mithilfe des Befehls az provider register.

    az provider register --namespace Microsoft.ContainerService
    

    Nachdem Sie Ihren Cluster nun für die Verwendung des AKS-GPU-Images aktualisiert haben, können Sie Ihrem Cluster einen Knotenpool für GPU-Knoten hinzufügen.

  6. Fügen Sie einen Kontenpool mit dem Befehl az aks nodepool add hinzu.

    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
    

    Der vorherige Beispielbefehl fügt myAKSCluster in myResourceGroup einen Knotenpool namens gpunp hinzu und verwendet Parameter, um die folgenden Knotenpooleinstellungen zu konfigurieren:

    • --node-vm-size: legt die VM-Größe für den Knoten im Knotenpool auf Standard_NC6s_v3 fest.
    • --node-taints: Gibt einen sku=gpu:NoSchedule-Taint für den Knotenpool an.
    • --aks-custom-headers: Gibt ein spezialisiertes AKS-GPU-Image an, UseGPUDedicatedVHD=true. Verwenden Sie stattdessen --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true, wenn Ihre GPU-SKU VMs der 2. Generation erfordert.
    • --enable-cluster-autoscaler: Aktiviert die Autoskalierung für Cluster.
    • --min-count: Konfiguriert die automatische Clusterskalierung so, dass mindestens ein Knoten im Knotenpool beibehalten wird.
    • --max-count: Konfiguriert die automatische Clusterskalierung so, dass höchstens drei Knoten im Knotenpool beibehalten werden.

    Hinweis

    Taints und VM-Größen können für Knotenpools nur während ihrer Erstellung festgelegt werden, aber Sie können die Autoskalierungseinstellungen jederzeit aktualisieren.

  7. Nachdem Sie nun erfolgreich einen Knotenpool mit dem GPU-Image erstellt haben, können Sie überprüfen, ob Ihre GPUs planbar sind, und eine GPU-Workload ausführen.

Bestätigen, dass GPUs planbar sind

Nach dem Erstellen Ihres Clusters bestätigen Sie, dass GPUs in Kubernetes planbar sind.

  1. Listen Sie die Knoten in Ihrem Cluster mit dem Befehl kubectl get nodes auf.

    kubectl get nodes
    

    Ihre Ausgabe sollte in etwa dem folgendem Beispiel entsprechen:

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. Vergewissern Sie sich, dass die GPUs planbar sind, mit dem Befehl kubectl describe node.

    kubectl describe node aks-gpunp-28993262-0
    

    Unter dem Abschnitt Capacity (Kapazität) sollte die GPU als nvidia.com/gpu: 1 aufgelistet werden. Ihre Ausgabe sollte der folgenden gekürzten Beispielausgabe entsprechen:

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

Ausführen einer GPU-fähigen Workload

Um die GPU in Aktion zu sehen, können Sie eine GPU-fähige Workload mit der entsprechenden Ressourcenanforderung planen. In diesem Beispiel führen wir einen TensorFlow-Auftrag für das MNIST-Dataset aus.

  1. Erstellen Sie eine Datei mit dem Namen samples-tf-mnist-demo.yaml, und fügen Sie das folgende YAML-Manifest ein, das ein Ressourcenlimit von nvidia.com/gpu: 1 enthält:

    Hinweis

    Wenn Sie beim Aufruf von Treibern einen Versionskonfliktfehler erhalten, z. B., dass die CUDA-Treiberversion für die CUDA-Laufzeitversion nicht ausreicht, überprüfen Sie das NVIDIA-Treibermatrix-Kompatibilitätsdiagramm.

    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. Führen Sie den Auftrag mithilfe des kubectl apply-Befehls aus, der die Manifestdatei analysiert und die definierten Kubernetes-Objekte erstellt.

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

Anzeigen des Status der GPU-fähigen Workload

  1. Überwachen Sie den Status des Auftrags mithilfe des Befehls kubectl get jobs mit dem Flag --watch. Es kann einige Minuten dauern, um zunächst das Image zu pullen und das Dataset zu verarbeiten.

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

    Wenn in der Spalte ABSCHLÜSSE der Wert 1/1 angezeigt wird, wurde der Auftrag erfolgreich abgeschlossen, wie in der folgenden Beispielausgabe gezeigt:

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. Beenden Sie den kubectl --watch-Prozess mit STRG+C.

  3. Rufen Sie den Namen des Pods mit dem Befehl kubectl get pods ab.

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. Zeigen Sie die Ausgabe der GPU-fähigen Workload mit dem Befehl kubectl logs an.

    kubectl logs samples-tf-mnist-demo-smnr6
    

    Die folgende komprimierte Beispielausgabe der Podprotokolle bestätigt, dass das entsprechende GPU-Gerät, Tesla K80, ermittelt wurde:

    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
    

Verwenden von Container Insights zum Überwachen der GPU-Nutzung

Container Insights mit AKS überwacht die folgenden GPU-Nutzungsmetriken:

Metrikname Metrikdimension (Tags) Beschreibung
containerGpuDutyCycle container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Der Prozentsatz der Zeit im Verlauf des letzten Beispielzeitraums (60 Sekunden), während dessen die GPU ausgelastet war/aktiv die Verarbeitung für einen Container ausgeführt hat. Der Arbeitszyklus ist eine Zahl zwischen 1 und 100.
containerGpuLimits container.azm.ms/clusterId, container.azm.ms/clusterName, containerName In jedem Container können Grenzwerte als eine oder mehrere GPUs angegeben werden. Es ist nicht möglich, einen Bruchteil einer GPU anzufordern oder einzuschränken.
containerGpuRequests container.azm.ms/clusterId, container.azm.ms/clusterName, containerName Jeder Container kann einen oder mehrere GPUs anfordern. Es ist nicht möglich, einen Bruchteil einer GPU anzufordern oder einzuschränken.
containerGpumemoryTotalBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Menge an GPU-Arbeitsspeicher in Bytes, die für einen bestimmten Container verwendet werden kann.
containerGpumemoryUsedBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor Menge an GPU-Arbeitsspeicher in Bytes, die für einen bestimmten Container verwendet wird.
nodeGpuAllocatable container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor Anzahl von GPUs in einem Knoten, die von Kubernetes verwendet werden können.
nodeGpuCapacity container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor Gesamtanzahl der GPUs in einem Knoten.

Bereinigen von Ressourcen

  • Entfernen Sie die zugeordneten Kubernetes-Objekte, die Sie in diesem Artikel erstellt haben, mit dem Befehl kubectl delete job.

    kubectl delete jobs samples-tf-mnist-demo
    

Nächste Schritte