在 Azure Kubernetes Service (AKS) 上使用 GPU 處理計算密集型工作負載

圖形處理單元 (GPU) 通常用來處理計算密集型工作負載,例如,圖形和視覺效果工作負載。 AKS 支援已啟用 GPU 的 Linux 節點集區,以執行計算密集型 Kubernetes 工作負載。

本文可協助您在新的和現有的 AKS 叢集上,佈建具有可排程 GPU 的節點。

支援已啟用 GPU 的 VM

若要檢視支援的已啟用 GPU 的 VM,請參閱 Azure 中的 GPU 最佳化 VM 大小。 針對 AKS 節點集區,建議使用的大小下限為 Standard_NC6s_v3。 AKS 不支援 (以 AMD GPU 為基礎的) NVv4 系列。

注意

已啟用 GPU 的 VM 包含專用硬體,其受限於較高的價格和區域可用性。 如需詳細資訊,請參閱定價工具和區域可用性

限制

  • 如果您使用 Azure Linux 已啟用 GPU 的節點集區,則不會套用自動安全性修補檔,且叢集的預設行為是「非受控」。 如需詳細資訊,請參閱自動升級 (部分機器翻譯)。
  • NVadsA10 v5 系列「不是」建議針對 GPU VHD 使用的 SKU。
  • 不支援更新現有節點集區以新增 GPU。

開始之前

  • 本文假設您目前擁有 AKS 叢集。 若您沒有叢集,請使用 Azure CLI (部分機器翻譯)、Azure PowerShell (部分機器翻譯) 或 Azure 入口網站來建立一個。
  • 您必須安裝並設定 Azure CLI 2.0.64 版或更新版本。 執行 az --version 以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI

取得叢集的認證

  • 使用 az aks get-credentials 命令取得 AKS 叢集的認證。 下列範例命令會針對 myResourceGroup 資源群組中的 myAKSCluster 取得認證:

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

使用 NVIDIA GPU 的選項

使用 NVIDIA GPU 牽涉到安裝各種 NVIDIA 軟體元件,例如,適用於 Kubernetes 的 NVIDIA 裝置外掛程式 (英文)、GPU 驅動程式安裝等。

略過 GPU 驅動程式安裝 (預覽)

AKS 預設會啟用自動 GPU 驅動程式安裝。 在某些情況下,例如安裝您自己的驅動程式或使用 NVIDIA GPU 操作員,您可能會想要略過 GPU 驅動程式安裝。

重要

AKS 預覽功能可透過自助服務,以加入方式使用。 預覽會以「現狀」和「可供使用時」提供,其其不受服務等級協定和有限瑕疵擔保所保護。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:

  1. 使用 az extension addaz extension update 命令,註冊或更新 aks-preview 延伸模組。

    # Register the aks-preview extension
    az extension add --name aks-preview
    
    # Update the aks-preview extension
    az extension update --name aks-preview
    
  2. 使用具有 --skip-gpu-driver-install 旗標的 az aks nodepool add 命令來建立節點集區,以略過自動 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
    

    在節點集區建立期間新增 --skip-gpu-driver-install 旗標,會略過自動 GPU 驅動程式安裝。 所有現有節點都不會變更。 您可以將節點集區調整為零,然後進行備份,以讓變更生效。

NVIDIA 裝置外掛程式安裝

在 AKS 上使用 GPU 時,需要安裝 NVIDIA 裝置外掛程式。 在某些情況下,系統會自動處理安裝,例如使用 NVIDIA GPU Operator (英文) 或 AKS GPU 映像 (預覽) 時。 或者,您可以手動安裝 NVIDIA 裝置外掛程式。

手動安裝 NVIDIA 裝置外掛程式

您可以部署適用於 NVIDIA 裝置外掛程式的 DaemonSet,其會在每個節點上執行 Pod,以提供 GPU 所需的驅動程式。 這是在針對 Azure Linux 使用已啟用 GPU 的節點集區時的建議方法。

若要使用預設的 OS SKU,您需要在不指定 OS SKU 的情況下建立節點集區。 根據叢集的 Kubernetes 版本,為預設作業系統設定節點集區。

  1. 使用 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
    

    此命令會將名為 gpunp 的節點集區新增至 myResourceGroup 中的 myAKSCluster,並使用參數來設定下列節點集區設定:

    • --node-vm-size:將節點集區中節點的 VM 大小設定為 Standard_NC6s_v3
    • --node-taints:指定節點集區上的 sku=gpu:NoSchedule 污點。
    • --enable-cluster-autoscaler:啟用叢集自動調整程式。
    • --min-count:設定叢集自動調整程式,在節點集區中至少維持一個節點。
    • --max-count:設定叢集自動調整程式,在節點集區中最多維持三個節點。

    注意

    污點和 VM 大小只能在節點集區建立期間針對節點集區進行設定,但您隨時都可更新自動調整程式設定。

  1. 使用 kubectl create namespace 命令來建立命名空間。

    kubectl create namespace gpu-resources
    
  2. 建立名為 nvidia-device-plugin-ds.yaml 的檔案,並貼上提供的下列 YAML 資訊清單作為適用於 Kubernetes 專案的 NVIDIA 裝置外掛程式 (英文) 的一部分:

    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:
          # 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.  This annotation works in tandem with the toleration below.
          annotations:
            scheduler.alpha.kubernetes.io/critical-pod: ""
          labels:
            name: nvidia-device-plugin-ds
        spec:
          tolerations:
          # Allow this pod to be rescheduled while the node is in "critical add-ons only" mode.
          # This, along with the annotation above marks this pod as a critical add-on.
          - key: CriticalAddonsOnly
            operator: Exists
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
          containers:
          - image: mcr.microsoft.com/oss/nvidia/k8s-device-plugin:v0.14.1
            name: nvidia-device-plugin-ctr
            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. 建立 DaemonSet,並使用 kubectl apply (英文) 命令來確認已成功建立 NVIDIA 裝置外掛程式。

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. 您已成功安裝 NVIDIA 裝置外掛程式,現在您可以檢查您的 GPU 是否可排程,並執行 GPU 工作負載

搭配 AKS 使用 NVIDIA GPU Operator

NVIDIA GPU Operator 會自動管理佈建 GPU 所需的所有 NVIDIA 軟體元件,包括驅動程式安裝、適用於 Kubernetes 的 NVIDIA 裝置外掛程式 (英文)、NVIDIA 容器執行階段等。 由於 GPU Operator 會處理這些元件,因此不需要手動安裝 NVIDIA 裝置外掛程式。 這也表示不再需要在 AKS 上自動安裝 GPU 驅動程式。

  1. 使用具有 --skip-gpu-driver-installaz aks nodepool add 命令來建立節點集區,以略過自動 GPU 驅動程式安裝。 在節點集區建立期間新增 --skip-gpu-driver-install 旗標,會略過自動 GPU 驅動程式安裝。 所有現有節點都不會變更。 您可以將節點集區調整為零,然後進行備份,以讓變更生效。

  2. 遵循 NVIDIA 文件以安裝 GPU Operator (英文)。

  3. 您已成功安裝 GPU Operator,現在您可以檢查您的 GPU 是否可排程,並執行 GPU 工作負載

警告

不建議使用 AKS GPU 映像手動安裝具有叢集的 NVIDIA 裝置外掛程式精靈集。

使用 AKS GPU 映像 (預覽)

AKS 提供完整設定的 AKS 映像,其中包含適用於 Kubernetes 的 NVIDIA 裝置外掛程式 (英文)。 目前僅 Ubuntu 18.04 支援 AKS GPU 映像。

重要

AKS 預覽功能可透過自助服務,以加入方式使用。 預覽會以「現狀」和「可供使用時」提供,其其不受服務等級協定和有限瑕疵擔保所保護。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:

  1. 使用 az extension add (部分機器翻譯) 命令來安裝 aks-preview Azure CLI 延伸模組。

    az extension add --name aks-preview
    
  2. 使用 az extension update (部分機器翻譯) 命令,更新為最新版的延伸模組。

    az extension update --name aks-preview
    
  3. 使用 az feature register 命令註冊 GPUDedicatedVHDPreview 功能旗標。

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

    狀態需要幾分鐘的時間才會顯示「已註冊」

  4. 使用 az feature show 命令確認註冊狀態。

    az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    
  5. 當狀態反映「已註冊」時,使用 az provider register (部分機器翻譯) 命令,重新整理 Microsoft.ContainerService 資源提供者的註冊。

    az provider register --namespace Microsoft.ContainerService
    

    您已將叢集更新為使用 AKS GPU 映像,現在您可以將 GPU 節點的節點集區新增至叢集。

  6. 使用 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
    

    上一個範例命令會將名為 gpunp 的節點集區新增至 myResourceGroup 中的 myAKSCluster,並使用參數來設定下列節點集區設定:

    • --node-vm-size:將節點集區中節點的 VM 大小設定為 Standard_NC6s_v3
    • --node-taints:指定節點集區上的 sku=gpu:NoSchedule 污點。
    • --aks-custom-headers:指定特製化的 AKS GPU 映像 UseGPUDedicatedVHD=true。 如果您的 GPU SKU 需要第 2 代 VM,請改為使用 --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true
    • --enable-cluster-autoscaler:啟用叢集自動調整程式。
    • --min-count:設定叢集自動調整程式,在節點集區中至少維持一個節點。
    • --max-count:設定叢集自動調整程式,在節點集區中最多維持三個節點。

    注意

    污點和 VM 大小只能在節點集區建立期間針對節點集區進行設定,但您隨時都可更新自動調整程式設定。

  7. 您已使用 GPU 映像成功建立節點集區,現在您可以檢查您的 GPU 是否可排程,並執行 GPU 工作負載

確認 GPU 可進行排程

建立叢集之後,確認 GPU 可在 Kubernetes 中進行排程。

  1. 使用 kubectl get nodes (英文) 命令,列出叢集中的節點。

    kubectl get nodes
    

    您的輸出看起來應類似下列的範例輸出:

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. 使用 kubectl describe node (英文) 命令,確認 GPU 可進行排程。

    kubectl describe node aks-gpunp-28993262-0
    

    在 [容量] 區段下,GPU 應顯示為 nvidia.com/gpu: 1。 您的輸出看起來應類似下列的緊縮範例輸出:

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

執行已啟用 GPU 的工作負載

若要查看 GPU 的運作情況,您可以使用適當的資源要求,對已啟用 GPU 的工作負載進行排程。 在此範例中,我們將針對 MNIST 資料集 (英文) 執行 Tensorflow (英文) 作業。

  1. 建立名為 samples-tf-mnist-demo.yaml 的檔案,並貼上下列 YAML 資訊清單,其中包括 nvidia.com/gpu: 1 的資源限制:

    注意

    如果您在呼叫驅動程式時收到版本不符的錯誤 (例如「CUDA 驅動程式版本並不足以執行 CUDA 執行階段版本」),請檢閱 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. 使用 kubectl apply (英文) 命令來執行作業,其會剖析資訊清單檔,並建立已定義的 Kubernetes 物件。

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

檢視已啟用 GPU 的工作負載狀態

  1. 使用 kubectl get jobs (英文) 命令搭配 --watch 旗標來監視作業進度。 這可能需要幾分鐘來執行第一次的影像提取和資料集處理。

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

    當「完成」資料行顯示 1/1 時,表示作業成功完成,如下列範例輸出中所示:

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. 使用 Ctrl-C 結束 kubectl --watch 處理序。

  3. 使用 kubectl get pods (英文) 命令,取得 Pod 的名稱。

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. 使用 kubectl logs (英文) 命令,檢視已啟用 GPU 的工作負載輸出。

    kubectl logs samples-tf-mnist-demo-smnr6
    

    下列扼要的 Pod 記錄範例輸出會確認已探索到適當的 GPU 裝置 Tesla K80

    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
    

使用容器深入解析來監視 GPU 使用量

使用 AKS 的容器見解會監視下列 GPU 使用計量:

度量名稱 計量維度 (標籤) 描述
containerGpuDutyCycle container.azm.ms/clusterId、、container.azm.ms/clusterNamecontainerNamegpuId、、gpuModelgpuVendor 過去範例期間 (60 秒) 容器 GPU 忙碌/主動處理的時間百分比。 工作週期是介於 1 與 100 之間的數字。
containerGpuLimits container.azm.ms/clusterId、 、 container.azm.ms/clusterNamecontainerName 每個容器都可以將限制指定為一或多個 GPU。 無法要求或限制 GPU 的小部分。
containerGpuRequests container.azm.ms/clusterId、 、 container.azm.ms/clusterNamecontainerName 每個容器都可以要求一或多個 GPU。 無法要求或限制 GPU 的小部分。
containerGpumemoryTotalBytes container.azm.ms/clusterId、、container.azm.ms/clusterNamecontainerNamegpuId、、gpuModelgpuVendor 可用於特定容器的 GPU 記憶體數量,以位元組為單位。
containerGpumemoryUsedBytes container.azm.ms/clusterId、、container.azm.ms/clusterNamecontainerNamegpuId、、gpuModelgpuVendor 特定容器所使用的 GPU 記憶體數量,以位元組為單位。
nodeGpuAllocatable container.azm.ms/clusterId、 、 container.azm.ms/clusterNamegpuVendor 節點中 Kubernetes 可以使用的 GPU 數目。
nodeGpuCapacity container.azm.ms/clusterId、 、 container.azm.ms/clusterNamegpuVendor 節點中的 GPU 總數。

清除資源

  • 使用 kubectl delete job (英文) 命令,移除您在本文中建立的相關聯 Kubernetes 物件。

    kubectl delete jobs samples-tf-mnist-demo
    

下一步