将 GPU 遥测集成到 Kubernetes 中

GPU 遥测的优势

了解 GPU 使用情况为管理数据中心的 IT 管理员提供了重要的见解。GPU 指标的趋势与工作负载行为相关联,并使优化资源分配、诊断异常和提高整体数据中心效率成为可能。随着 GPU 在 Kubernetes 环境中变得越来越主流,用户希望像今天对 CPU 所做的那样,访问 GPU 指标以监控 GPU 资源。

本文档的目的是列举在 Kubernetes 环境中设置和使用 DCGM 的端到端 (e2e) 工作流程。

为了简单起见,本指南中使用的基础环境是 Ubuntu 18.04 LTS 以及在启用 GPU 的节点上原生安装 NVIDIA 驱动程序(即,本文档中未使用 NVIDIA GPU Operator 或容器化驱动程序)。

NVIDIA 驱动程序

本节概述了使用 Ubuntu LTS 上的 apt 包管理器安装驱动程序的步骤。

注意

有关设置 NVIDIA 驱动程序的完整说明,请访问快速入门指南:https://docs.nvda.net.cn/datacenter/tesla/tesla-installation-notes/index.html。该指南涵盖了许多预安装要求以及在受支持的 Linux 发行版上成功安装驱动程序的步骤。

安装当前运行内核的内核头文件和开发包

$ sudo apt-get install linux-headers-$(uname -r)

设置 CUDA 网络存储库,并确保 CUDA 网络存储库上的软件包优先于 Canonical 存储库

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed -e 's/\.//g') \
   && wget https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-$distribution.pin \
   && sudo mv cuda-$distribution.pin /etc/apt/preferences.d/cuda-repository-pin-600

安装 CUDA 存储库 GPG 密钥

$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/7fa2af80.pub \
   && echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64 /" | sudo tee /etc/apt/sources.list.d/cuda.list

更新 apt 存储库缓存,并使用 cuda-drivers 元软件包安装驱动程序。使用 --no-install-recommends 选项进行精简驱动程序安装,而不依赖于任何 X 软件包。这对于云实例上的无头安装尤其有用

$ sudo apt-get update \
   && sudo apt-get -y install cuda-drivers

安装 Docker

使用官方 Docker 脚本安装最新版本的 Docker

$ curl https://get.docker.com | sh
$ sudo systemctl --now enable docker

安装 NVIDIA Container Toolkit

要在 Docker 中运行 GPU 加速容器,需要 NVIDIA Container Toolkit for Docker。

设置 stable 存储库和 GPG 密钥

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

在更新软件包列表后,安装 NVIDIA 运行时软件包(及其依赖项)

$ sudo apt-get update \
   && sudo apt-get install -y nvidia-docker2

由于 Kubernetes 尚不支持 Docker 的 --gpus 选项,因此应将 nvidia 运行时设置为 GPU 节点上 Docker 的默认容器运行时。可以通过将 default-runtime 行添加到 Docker 守护程序配置文件来完成此操作,该文件通常位于系统上的 /etc/docker/daemon.json

{
   "default-runtime": "nvidia",
   "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
      }
   }
}

重启 Docker 守护程序以完成安装,并在设置默认运行时后生效

$ sudo systemctl restart docker

此时,可以通过运行基本 CUDA 容器来测试工作设置

$ sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi

您应该观察到如下所示的输出

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.51.06    Driver Version: 450.51.06    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
| N/A   34C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

安装 NVIDIA Device Plugin

要在 Kubernetes 中使用 GPU,需要 NVIDIA Device Plugin。NVIDIA Device Plugin 是一个守护程序集,可自动枚举集群每个节点上的 GPU 数量,并允许 Pod 在 GPU 上运行。

部署设备插件的首选方法是使用 helm 作为守护程序集。首先,安装 Helm

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \
   && chmod 700 get_helm.sh \
   && ./get_helm.sh

添加 nvidia-device-plugin helm 存储库

$ helm repo add nvdp https://nvidia.github.io/k8s-device-plugin \
   && helm repo update

部署设备插件

$ helm install --generate-name nvdp/nvidia-device-plugin

有关部署守护程序集时更多用户可配置的选项,请参阅文档

此时,应部署所有 Pod

$ kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS      RESTARTS   AGE
kube-system   calico-kube-controllers-5fbfc9dfb6-2ttkk   1/1     Running     3          9d
kube-system   calico-node-5vfcb                          1/1     Running     3          9d
kube-system   coredns-66bff467f8-jzblc                   1/1     Running     4          9d
kube-system   coredns-66bff467f8-l85sz                   1/1     Running     3          9d
kube-system   etcd-ip-172-31-81-185                      1/1     Running     4          9d
kube-system   kube-apiserver-ip-172-31-81-185            1/1     Running     3          9d
kube-system   kube-controller-manager-ip-172-31-81-185   1/1     Running     3          9d
kube-system   kube-proxy-86vlr                           1/1     Running     3          9d
kube-system   kube-scheduler-ip-172-31-81-185            1/1     Running     4          9d
kube-system   nvidia-device-plugin-1595448322-42vgf      1/1     Running     2          9d

要测试是否可以部署 CUDA 作业,请运行示例 CUDA vectorAdd 应用程序

Pod 规范如下所示,供参考,它请求 1 个 GPU

apiVersion: v1
kind: Pod
metadata:
  name: gpu-operator-test
spec:
  restartPolicy: OnFailure
  containers:
  - name: cuda-vector-add
    image: "nvidia/samples:vectoradd-cuda10.2"
    resources:
      limits:
         nvidia.com/gpu: 1

将此 Pod 规范另存为 gpu-pod.yaml。现在,部署应用程序

$ kubectl apply -f gpu-pod.yaml

检查日志以确保应用程序成功完成

$ kubectl get pods gpu-operator-test
NAME                READY   STATUS      RESTARTS   AGE
gpu-operator-test   0/1     Completed   0          9d

并检查 gpu-operator-test Pod 的日志

$ kubectl logs gpu-operator-test
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done