踢掉 Docker 后,Kubernetes 还能欢快地跑 GPU?
The following article is from 云原生实验室 Author 米开朗基杨
前两天闹得沸沸扬扬的事件不知道大家有没有听说,Google 竟然将 Docker 踢出了 Kubernetes 的群聊,不带它玩了。
我这里简单描述下,Kubernetes 是通过 CRI 来对接容器运行时的,而 Docker 本身是没有实现 CRI 的,所以 Kubernetes 内置了一个 “为 Docker 提供 CRI 支持” 的 dockershim 组件。现在 Kubernetes 宣布不再维护这个组件了。
Nvidia 驱动
安装 gcc 和 kernel-dev(如果没有) sudo apt install gcc kernel-dev -y。
访问官网下载。
选择操作系统和安装包,并单击【SEARCH】搜寻驱动,选择要下载的驱动版本
下载对应版本安装脚本,在宿主机上执行:
$ wget https://www.nvidia.com/content/DriverDownload-March2009/confirmation.php?url=/tesla/450.80.02/NVIDIA-Linux-x86_64-450.80.02.run&lang=us&type=Tesla
安装,执行脚本安装:
$ chmod +x NVIDIA-Linux-x86_64-450.80.02.run && ./NVIDIA-Linux-x86_64-450.80.02.run
验证,使用如下命令验证是否安装成功 nvidia-smi ,如果输出类似下图则驱动安装成功。
访问官网下载
下载对应版本如下:
$ echo 'export PATH=/usr/local/cuda/bin:$PATH' | sudo tee /etc/profile.d/cuda.sh $ source /etc/profile
nvidia-container-runtime
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | sudo apt-key add -$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/$(. /etc/os-release;echo $ID$VERSION_ID)/nvidia-container-runtime.list | sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
安装:
$ apt install nvidia-container-runtime -y
配置 Containerd 使用 Nvidia container runtime
$ mkdir /etc/containerd
$ containerd config default > /etc/containerd/config.toml
...
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
default_runtime_name = "runc"
no_pivot = false
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runtime.v1.linux" # 将此处 runtime_type 的值改成 io.containerd.runtime.v1.linux
...
[plugins."io.containerd.runtime.v1.linux"]
shim = "containerd-shim"
runtime = "nvidia-container-runtime" # 将此处 runtime 的值改成 nvidia-container-runtime
...
$ systemctl restart containerd
部署 NVIDIA GPU 设备插件
$ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.7.1/nvidia-device-plugin.yml
查看日志:
$ kubectl -n kube-system logs nvidia-device-plugin-daemonset-xxx
2020/12/04 06:30:28 Loading NVML
2020/12/04 06:30:28 Starting FS watcher.
2020/12/04 06:30:28 Starting OS watcher.
2020/12/04 06:30:28 Retreiving plugins.
2020/12/04 06:30:28 Starting GRPC server for 'nvidia.com/gpu'
2020/12/04 06:30:28 Starting to serve 'nvidia.com/gpu' on /var/lib/kubelet/device-plugins/nvidia-gpu.sock
2020/12/04 06:30:28 Registered device plugin for 'nvidia.com/gpu' with Kubelet
$ ll /var/lib/kubelet/device-plugins/
total 12
drwxr-xr-x 2 root root 4096 Dec 4 01:30 ./
drwxr-xr-x 8 root root 4096 Dec 3 05:05 ../
-rw-r--r-- 1 root root 0 Dec 4 01:11 DEPRECATION
-rw------- 1 root root 3804 Dec 4 01:30 kubelet_internal_checkpoint
srwxr-xr-x 1 root root 0 Dec 4 01:11 kubelet.sock=
srwxr-xr-x 1 root root 0 Dec 4 01:11 kubevirt-kvm.sock=
srwxr-xr-x 1 root root 0 Dec 4 01:11 kubevirt-tun.sock=
srwxr-xr-x 1 root root 0 Dec 4 01:11 kubevirt-vhost-net.sock=
srwxr-xr-x 1 root root 0 Dec 4 01:30 nvidia-gpu.sock=
首先测试本地命令行工具 ctr,这个应该没啥问题:且显卡资源是独占,无法在多个容器之间分享。
$ ctr images pull docker.io/nvidia/cuda:9.0-base
$ ctr run --rm -t --gpus 0 docker.io/nvidia/cuda:9.0-base nvidia-smi nvidia-smi
Fri Dec 4 07:01:38 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.95.01 Driver Version: 440.95.01 CUDA Version: 10.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce RTX 208... Off | 00000000:A1:00.0 Off | N/A |
| 30% 33C P8 9W / 250W | 0MiB / 11019MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
cuda-vector-add 0/1 Completed 0 3s
$ kubectl logs cuda-vector-add
[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
参考资料
[1]官网: https://www.nvidia.com/Download/Find.aspx
[2] 官网: https://developer.nvidia.com/cuda-toolkit-archive
[3] 设备插件(Device Plugins): https://v1-18.docs.kubernetes.io/zh/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/
[4] 容器中使用 GPU 的基础环境搭建: https://lxkaka.wang/docker-nvidia/