本文主要描述如何在k8s中管理GPU的节点和容器。
Kubernetes(K8s)对 GPU 的支持,适合用于机器学习、深度学习、图像处理等高性能计算场景。
1. 实现思路
K8s 本身不直接管理 GPU,而是通过 NVIDIA 的 GPU 设备插件(NVIDIA Device Plugin) 将 GPU 资源暴露给容器。整个流程如下:
1 | 物理 GPU → 安装驱动 + 宿主机工具 → 容器 runtime(如 containerd)→ Kubernetes 通过 device plugin 管理 → Pod 使用 GPU |
2. 实现步骤
2.1. 节点准备(仅 GPU 节点需要)
运行 NVIDIA 设备插件的先决条件如下:
- NVIDIA 驱动程序 ~= 384.81
- nvidia-docker >= 2.0 || nvidia-container-toolkit >= 1.7.0(>= 1.11.0 在基于 Tegra 的系统上使用集成 GPU)
- nvidia-container-runtime 配置为默认低级运行时
- Kubernetes 版本 >= 1.10
安装 NVIDIA 官方驱动。
1 | # 示例安装命令(Ubuntu) |
2.2. 安装容器运行时插件(containerd 支持)
安装 NVIDIA Container Toolkit,参考Installing the NVIDIA Container Toolkit
1 | curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ |
配置containerd
nvidia-ctk会修改containerd的配置使得containerd可以使用NVIDIA Container Runtime。
1 | sudo nvidia-ctk runtime configure --runtime=containerd |
2.3. 安装 NVIDIA Device Plugin(K8s 插件)
NVIDIA device plugin 通过k8s daemonset的方式部署到每个k8s的node节点上,实现了Kubernetes device plugin的接口。
提供以下功能:
- 暴露每个节点的GPU数量给集群
- 跟踪GPU的健康情况
- 使在k8s的节点可以运行GPU容器
1 | kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.17.1/deployments/static/nvidia-device-plugin.yml |
-
它会在每个 GPU 节点启动一个
nvidia-device-plugin
DaemonSet。 -
它会向节点注册一个
nvidia.com/gpu
资源。
2.4. 编写使用 GPU 的 Pod/Deployment
部署守护进程后,容器现在可以使用以下nvidia.com/gpu
资源类型请求 NVIDIA GPU:
1 | cat <<EOF | kubectl apply -f - |
3. nvidia-device-plugin内容
nvidia-device-plugin的daemonset yaml文件如下,具体参考:nvidia-device-plugin.yml
1 | apiVersion: apps/v1 |
4. 构建和运行nvidia-device-plugin
4.1. docker方式
4.1.1. 编译
- 直接拉取dockerhub的镜像
1 | $ docker pull nvidia/k8s-device-plugin:1.0.0-beta4 |
- 拉取代码构建镜像
1 | $ docker build -t nvidia/k8s-device-plugin:1.0.0-beta4 https://github.com/NVIDIA/k8s-device-plugin.git#1.0.0-beta4 |
- 修改nvidia-device-plugin后构建镜像
1 | $ git clone https://github.com/NVIDIA/k8s-device-plugin.git && cd k8s-device-plugin |
4.1.2. 运行
- docker本地运行
1 | $ docker run --security-opt=no-new-privileges --cap-drop=ALL --network=none -it -v /var/lib/kubelet/device-plugins:/var/lib/kubelet/device-plugins nvidia/k8s-device-plugin:1.0.0-beta4 |
- daemonset运行
1 | $ kubectl create -f nvidia-device-plugin.yml |
4.2. 非docker方式
4.2.1. 编译
1 | $ C_INCLUDE_PATH=/usr/local/cuda/include LIBRARY_PATH=/usr/local/cuda/lib64 go build |
4.2.2. 本地运行
1 | $ ./k8s-device-plugin |
参考:
赞赏一下