你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure Kubernetes 服务 (AKS) 上将 GPU 用于计算密集型工作负荷
图形处理单元 (GPU) 通常用于计算密集型工作负荷,例如图形和可视化工作负载。 AKS 支持启用 GPU 的 Linux 节点池来运行计算密集型 Kubernetes 工作负载。
本文帮助你在新的和现有 AKS 群集上预配具有可计划 GPU 的节点。
要查看受支持的启用了 GPU 的 VM,请参阅《Azure 中优化了 GPU 的 VM 大小。 对于 AKS 节点池,建议的最小大小为 Standard_NC6s_v3。 AKS 不支持 NVv4 系列(基于 AMD GPU)。
备注
启用 GPU 的 VM 包含专用硬件,这些硬件定价较高,其可用性受区域限制。 有关详细信息,请参阅定价工具和区域可用性。
- 如果使用 Azure Linux 已启用 GPU 的节点池,则不会应用自动安全修补程序。 有关节点 OS 升级通道的默认行为,请参阅当前的 AKS API 版本。
备注
对于 AKS API 版本 2023-06-01 或更高版本,节点 OS 升级的默认通道是 NodeImage。 对于以前的版本,默认通道是“无”。 要了解详细信息,请参阅“自动升级”。
- NVadsA10 v5 系列不是推荐用于 GPU VHD 的 SKU。
- 不支持通过更新现有节点池来添加 GPU。
使用 az aks get-credentials
命令获取 AKS 群集的凭据。 以下示例命令获取 myResourceGroup 资源组中 myAKSCluster 的凭据:
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
使用 NVIDIA GPU 涉及各种 NVIDIA 软件组件(例如适用于 Kubernetes 的 NVIDIA 设备插件)的安装、GPU 驱动程序的安装,等等。
备注
默认情况下,Microsoft 会在节点映像部署过程中自动维护 NVidia 驱动程序的版本,并且 AKS 将会支持和管理它。 虽然 NVidia 驱动程序默认安装在支持 GPU 的节点上,但你需要安装设备插件。
在 AKS 上使用 GPU 时,需要安装 NVIDIA 设备插件。 在某些情况下,安装会自动进行,例如在使用 NVIDIA GPU Operator 或 AKS GPU 映像(预览版)时就是如此。 也可手动安装 NVIDIA 设备插件。
可以为 NVIDIA 设备插件部署 DaemonSet,该插件会在每个节点上运行一个 Pod,为 GPU 提供所需的驱动程序。 这是为 Azure Linux 使用支持 GPU 的节点池时推荐使用的方法。
若要使用默认 OS SKU,请在不指定 OS SKU 的情况下创建节点池。 节点池是根据群集的 Kubernetes 版本为默认操作系统配置的。
使用 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 大小,但随时可以更新自动缩放程序的设置。
若要使用 Azure Linux,请在节点池创建期间通过将 os-sku
设置为 AzureLinux
来指定 OS SKU。 os-type
默认设置为 Linux
。
使用 az aks nodepool add
命令将节点池添加到群集,并将 --os-sku
标志设置为 AzureLinux
。
az aks nodepool add \
--resource-group myResourceGroup \
--cluster-name myAKSCluster \
--name gpunp \
--node-count 1 \
--os-sku AzureLinux \
--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 大小,但随时可以更新自动缩放程序的设置。 某些 SKU(包括 A100 和 H100 VM SKU)不适用于 Azure Linux。 有关详细信息,请参阅 Azure 中经过 GPU 优化的 VM 大小。
使用 kubectl create namespace
命令创建命名空间。
kubectl create namespace gpu-resources
创建名为 nvidia-device-plugin-ds.yaml 的文件,并粘贴适用于 Kubernetes 项目的 NVIDIA 设备插件中的以下 YAML 清单:
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
使用 kubectl apply
命令创建 DaemonSet 并确认已成功创建 NVIDIA 设备插件。
kubectl apply -f nvidia-device-plugin-ds.yaml
成功安装 NVIDIA 设备插件后,就可以检查 GPU 是否可调度并运行 GPU 工作负荷了。
如果要控制 NVidia 驱动程序的安装或使用 NVIDIA GPU 运营商,则可以跳过默认的 GPU 驱动程序安装。 Microsoft 不支持,也不会在节点映像部署过程中管理 NVidia 驱动程序的维护和兼容性。
重要
AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
使用 az extension add
或 az 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
使用带有 --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 GPU Operator 与 AKS 配合使用
NVIDIA GPU Operator 可自动管理预配 GPU 所需的所有 NVIDIA 软件组件,包括驱动程序安装、适用于 Kubernetes 的 NVIDIA 设备插件、NVIDIA 容器运行时等。 由于 GPU Operator 会处理这些组件,因此无需手动安装 NVIDIA 设备插件。 这也意味着不再需要在 AKS 上自动安装 GPU 驱动程序。
通过使用带 --skip-gpu-driver-install
的 az aks nodepool add
命令创建节点池,跳过自动 GPU 驱动程序安装。 在节点池创建期间添加 --skip-gpu-driver-install
标志会跳过自动 GPU 驱动程序安装。 不会更改任何现有节点。 可以将节点池缩放至零,然后进行备份,以使更改生效。
按照 NVIDIA 文档安装 GPU Operator。
成功安装 GPU Operator 后,就可以检查 GPU 是否可调度并运行 GPU 工作负荷了。
警告
不建议使用 AKS GPU 映像手动安装具有群集的 NVIDIA 设备插件守护程序集。
备注
AKS GPU 映像(预览版)将于 2025 年 1 月 10 日停用。 下面的自定义标头将不再可用,这意味着无法使用 AKS GPU 映像创建新的已启用 GPU 的节点池。 建议迁移到或使用默认 GPU 配置,而不是专用 GPU 映像,因为专用 GPU 映像不再受支持。 有关详细信息,请参阅 AKS 发行说明,或在 AKS 公共路线图中查看此停用公告。
AKS 提供了配置完全的 AKS 映像,其中包含适用于 Kubernetes 的 NVIDIA 设备插件。 AKS GPU 映像目前仅在 Ubuntu 18.04 上可用。
重要
AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
使用 az extension add
命令安装 aks-preview
Azure CLI 扩展。
az extension add --name aks-preview
使用 az extension update
命令更新到扩展的最新版本。
az extension update --name aks-preview
使用 az feature register
命令注册 GPUDedicatedVHDPreview
功能标志。
az feature register --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
状态显示为“已注册”需要几分钟时间。
使用 az feature show
命令验证注册状态。
az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
当状态反映为已注册时,使用 az provider register
命令刷新 Microsoft.ContainerService 资源提供程序的注册。
az provider register --namespace Microsoft.ContainerService
将群集更新为使用 AKS GPU 映像后,可以将 GPU 节点的节点池添加到你的群集。
使用 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 需要第二代 VM,请改为使用 --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true。
--enable-cluster-autoscaler
:启用群集自动缩放程序。
--min-count
:将群集自动缩放程序配置为在节点池中至少保留一个节点。
--max-count
:将群集自动缩放程序配置为在节点池中至多保留三个节点。
备注
只能在创建节点池期间为节点池设置污点和 VM 大小,但随时可以更新自动缩放程序的设置。
成功地使用 GPU 映像创建节点池后,就可以检查 GPU 是否可调度并运行 GPU 工作负荷了。
创建完群集后,确认 GPU 在 Kubernetes 中是可计划的。
使用 kubectl get nodes
命令列出群集中的节点。
kubectl get nodes
输出应类似于以下示例输出:
NAME STATUS ROLES AGE VERSION
aks-gpunp-28993262-0 Ready agent 13m v1.20.7
使用 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 的工作负载。 在此示例中,我们将针对 MNIST 数据集运行一个 Tensorflow 作业。
创建名为“samples-tf-mnist-demo.yaml”的文件并粘贴以下 YAML 清单,它包含 nvidia.com/gpu: 1
的资源限制:
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"
使用 kubectl apply
命令运行作业,该命令会分析清单文件并创建定义的 Kubernetes 对象。
kubectl apply -f samples-tf-mnist-demo.yaml
将 kubectl get jobs
命令与 --watch
标志配合使用,以监视作业的进度。 先拉取映像并处理数据集可能需要几分钟时间。
kubectl get jobs samples-tf-mnist-demo --watch
当 COMPLETIONS 列显示 1/1 时,作业已成功完成,如以下示例输出所示:
NAME COMPLETIONS DURATION AGE
samples-tf-mnist-demo 0/1 3m29s 3m29s
samples-tf-mnist-demo 1/1 3m10s 3m36s
使用 Ctrl-C 退出 kubectl --watch
进程。
使用 kubectl get pods
命令获取 pod 的名称。
kubectl get pods --selector app=samples-tf-mnist-demo
使用 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
适用于 AKS 的容器见解监视以下 GPU 使用情况指标:
指标名称 |
指标维度(标记) |
说明 |
containerGpuDutyCycle |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、containerName 、gpuId 、gpuModel 、gpuVendor |
在刚过去的采样周期(60 秒)中,GPU 处于繁忙/积极处理容器的状态的时间百分比。 占空比是 1 到 100 之间的数字。 |
containerGpuLimits |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、containerName |
每个容器可以将限值指定为一个或多个 GPU。 不能请求或限制为 GPU 的一部分。 |
containerGpuRequests |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、containerName |
每个容器可以请求一个或多个 GPU。 不能请求或限制为 GPU 的一部分。 |
containerGpumemoryTotalBytes |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、containerName 、gpuId 、gpuModel 、gpuVendor |
可用于特定容器的 GPU 内存量(以字节为单位)。 |
containerGpumemoryUsedBytes |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、containerName 、gpuId 、gpuModel 、gpuVendor |
特定容器使用的 GPU 内存量(以字节为单位)。 |
nodeGpuAllocatable |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、gpuVendor |
节点中可供 Kubernetes 使用的 GPU 数。 |
nodeGpuCapacity |
container.azm.ms/clusterId 、container.azm.ms/clusterName 、gpuVendor |
节点中的 GPU 总数。 |