在k8s中调用NVIDIA-GPU
概述
本次实践的环境:
Ubuntu18.04
docker version : 18.09.5
查看nvidia-docker版本命令
dpkg -l |grep nvidia-docker
nvidia-docker2 : 2.2.2 > 注意nvdia-docker1和2是不兼容的
nvidia-docker调用GPU
在docker中调用英伟达的gpu可以通过nvidia-docker调用,nvidia-docker是一个可以使用GPU的docker,nvidia-docker是在docker上做了一层封装,通过nvidia-docker-plugin,然后调用到docker上,其最终实现的还是在docker的启动命令上指定runtimes为nvidia-container-runtime,具体的参数在可以通过查看/etc/docker/daemon.json这个路径。
cat /etc/docker/daemon.json
{
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
}
}
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
可以看到具体的配置,其中registry-mirrors是配置的镜像源。
当我们用nvidia-docker命令生成并启动容器时,会自动的指定runtimes为nvidia并加上一系列的参数。
k8s中调用GPU
k8s在v1.8版本后推荐使用NVIDIA/k8s-device-plugin来调用GPU。其实就是集群版的nvidia-docker...都是暴露gpu分配调度接口,并进行监听。原理参照k8s插件原理。
预准备
- NVIDIA drivers ~= 361.93
- nvidia-docker version > 2.0 (see how to install and it's prerequisites)
- Kubernetes version >= 1.10
- 接下来设置默认runtime.
vim /etc/docker/daemon.json
添加 "default-runtime": "nvidia"
重启docker使配置生效
systemctl restart docker
- 安装k8s-device-plugin
在master节点上运行
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml
返回提示
daemonset.apps/nvidia-device-plugin-daemonset created
查看安装后是否有可用gpu资源
kubectl describe nodes
gpu资源
image.png
可以看到在有GPU的node上,守护Pods中多了nvidia-device-plugin-daemonset用于监听和分配gpu,在Allocated resources(可分配资源)中多了gpu。
测试k8s中gpu的使用
- 编写资源清单
vim gpu_test.yaml
内容的组织形式类似docker file
apiVersion: v1
kind: Pod
metadata:
name: ffmpeg-pod
spec:
nodeName: wangzishen-ms-7846 #指定有gpu的节点
containers:
- name: ffmpeg-container
image: nightseas/ffmpeg:latest #k8s中配置阿里的私有仓库遇到一些问题,暂时用公共镜像
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
resources:
limits:
nvidia.com/gpu: 1 # 请求分配 1个 GPU
- 创建Pod
kubectl create -f gpu_test.yaml
启动成功
启动的过程中会去docker hub拉取nightseas/ffmpeg:latest这个镜像,在启动过程中可以通过
kubectl describe pod ffmpeg-pod
查看当前的执行情况
当前情况
- 进入Pod调用gpu进行视频转码
kubectl exec ffmpeg-pod -it -- bash
- 下载视频
wget http://xxxxxxxx/tmp/00000000088000000.mp4
- 进行转码
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 00000000088000000.mp4 -vf scale_npp=1280:720 -vcodec h264_nvenc out.mp4
-
查看gpu调用情况
在有gpu的节点上watch nvidia-smi,可以看到gpu已经被运行在k8s中的容器通过k8s-device-plugin调用。
调用情况
多个pod共享一张GPU
不行,pod在创建的时候请求gpu最低是卡级别,一张显卡只能分配给一个pod。但是一个pod是由多个容器组成的,所以同一个pod的容器可以共享分配给当前pod的所有GPU。
多个docker容器共享一张GPU
可以。通过nvidia-docker启动的容器可以共享一张GPU。因为容器是进程级的程序所以分配GPU可以达到显存级。