在 Kubernetes 集群中启动 GPU 节点
参考文章:
本文目的是运行在集群中的POD使用节点上的GPU资源。Kubernetes 实现了设备插件(Device Plugins) 以允许 Pod 访问类似 GPU 这类特殊的硬件功能特性。我们需要在 GPU 节点上安装来自对应硬件厂商的 GPU 驱动程序,并运行来自 GPU 厂商的对应的设备插件。
实验环境
./+o+- ubuntu@netlab-529-GPU1
yyyyy- -yyyyyy+ OS: Ubuntu 18.04 bionic
://+//////-yyyyyyo Kernel: x86_64 Linux 5.4.0-81-generic
.++ .:/++++++/-.+sss/` Uptime: 1d 18h 16m
.:++o: /++++++++/:--:/- Packages: 1655
o:+o+:++.`..```.-/oo+++++/ Shell: bash 4.4.20
.:+o:+o/. `+sssoo+/ Resolution: 1536x864
.++/+:+oo+o:` /sssooo. DE: GNOME
/+++//+:`oo+o /::--:. WM: Not Found
\+/+o+++`o++o ++////. GTK Theme: Adwaita [GTK2/3]
.++.o+++oo+:` /dddhhh. Icon Theme: Adwaita
.+.o+oo:. `oddhhhh+ Font: Cantarell 11
\+.++o+o``-````.:ohdhhhhh+ CPU: 11th Gen Intel Core i7-11700KF @ 16x 4.9GHz [27.8°C]
`:o+++ `ohhhhhhhhyo++os: GPU: NVIDIA GeForce RTX 3080 Ti
.o:`.syhhhhhhh/.oo++o` RAM: 2143MiB / 47934MiB
/osyyyyyyo++ooo+++/
````` +oo+++o\:
`oo++.
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02 Driver Version: 470.57.02 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
安装设备插件
目前 kubernetes 集群支持 Nvidia 和 AMD 两个厂商的显卡。本文环境使用的是 Nvidia 显卡,所以在此介绍安装 Nvidia 设备插件。
安装 Nvidia 设备插件的前提条件
官方的 NVIDIA GPU 设备插件 有以下要求:
- Kubernetes 的节点必须预先安装了 NVIDIA 驱动
- Kubernetes 的节点必须预先安装 nvidia-docker 2.0
- Docker 的默认运行时必须设置为 nvidia-container-runtime,而不是 runc
- NVIDIA 驱动版本 ~= 384.81
Docker 的默认运行时设置示例, 确保在docker配置文件中(
/etc/docker/daemon.json
)中存在以下片段:{ "default-runtime": "nvidia", "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } } }
如果集群已经启动并且满足上述要求,则可以部署 NVIDIA 设备插件,部署命令如下:
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml
安装完成后的变化
安装设备插件后,Kubernetes 将暴露 nvidia.com/gpu 为可调度的资源。
可以通过请求 nvidia.com/gpu 资源来使用 GPU 设备,就像申请 CPU 和内存资源一样。 不过,申请 GPU 资源还是有一些限制:
- GPUs 只能设置在 limits 部分
- 可以指定 GPU 的 limits 而不能指定 requests,Kubernetes 将使用限制值作为默认的请求值
- 可以同时指定 limits 和 requests,不过这两个值必须相等
- 不可以仅指定 requests 而不指定 limits
- 容器(以及 Pod)之间是不共享 GPU 的。GPU 也不可以过量分配(Overcommitting)。
- 每个容器可以请求一个或者多个 GPU,但是用小数值来请求部分 GPU 是不允许的
部署示例
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPU
注意
目前k8s只支持卡级别的调度,并且显卡资源是独占,无法在多个容器之间分享,这一点在使用过程中需要特别注意。