Docker容器中使用GPU的总结
Docker容器中使用GPU的总结
Docker容器中使用GPU的总结
一、Docker 19.03以前的使用方法
在Docker 19.03版本之前,使用GPU需要通过以下两种方式之一:
指定显卡硬件名
最初的容器中使用显卡,需要指定硬件名。经历了两种方式:
使用lxc驱动程序运行docker守护进程,以便能够修改配置并让容器访问显卡设备(非常麻烦,参考链接中最久远的回答)
Docker 0.9中放弃了lxc作为默认执行上下文,但是依然需要指定显卡的名字
(1)找到你的显卡设备
ls -la /dev | grep nvidia crw-rw-rw- 1 root root 195, 0 Oct 25 19:37 nvidia0 crw-rw-rw- 1 root root 195, 255 Oct 25 19:37 nvidiactl crw-rw-rw- 1 root root 251, 0 Oct 25 19:37 nvidia-uvm
(2)启动容器时,指定显卡设备
sudo docker run -ti --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm tleyden5iwx/ubuntu-cuda /bin/bash
使用nvidia-docker
英伟达公司开发了nvidia-docker,该软件是对docker的包装,使得容器能够看到并使用宿主机的nvidia显卡。本质上,他们找到了一种方法来避免在容器中安装CUDA/GPU驱动程序,并让它与主机内核模块匹配。
测试:
# Install nvidia-docker and nvidia-docker-plugin wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb sudo dpkg -i /tmp/nvidia-docker.deb && rm /tmp/nvidia-docker.deb # Test nvidia-smi nvidia-docker run --rm nvidia/cuda nvidia-smi
指定使用两张卡:
docker run --rm --gpus 2 nvidia/cuda nvidia-smi
更详细得得用法见:User Guide — NVIDIA Cloud Native Technologies documentation
另外要注意nvidia-docker包括nvidia-docker1 和 nvidia-docker2,两者命令有一定差异
二、Docker 19.03版本的使用方法
从Docker 19.03版本开始,使用GPU变得更加简单,只需要添加--gpus
参数即可。以下是具体步骤:
安装nvidia-container-toolkit
Ubuntu 16.04/18.04, Debian Jessie/Stretch/Buster:
# Add the package repositories $ 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 $ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit $ sudo systemctl restart docker
CentOS 7 (docker-ce), RHEL 7.4/7.5 (docker-ce), Amazon Linux 1/2:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo $ sudo yum install -y nvidia-container-toolkit $ sudo systemctl restart docker
测试安装是否成功
经过以上步骤,大部分Linux系统的docker toolkit应该都能安装成功。如不能安装成功,可参考github官网。查看是否安装成功:
(1) 查看
--gpus
参数是否安装成功:$ docker run --help | grep -i gpus --gpus gpu-request GPU devices to add to the container ('all' to pass all GPUs)
(2) 运行nvidia官网提供的镜像,并输入nvidia-smi命令,查看nvidia界面是否能够启动:
docker run --gpus all nvidia/cuda:9.0-base nvidia-smi
运行GPU的容器
从Docker 19.03开始,安装好docker之后,只需要使用
--gpus
即可指定容器使用显卡。
所有显卡都对容器可见:
docker run --gpus all --name 容器名 -d -t 镜像id
只有显卡1对容器可见:
docker run --gpus="1" --name 容器名 -d -t 镜像id
如果不指定
--gpus
,运行nvidia-smi会提示Command not found注意:
显卡驱动在所有方式中,都要先安装好,容器是不会有显卡驱动的,一台物理机的显卡只对应一个显卡驱动,当显卡驱动安装好后(即使未安装cuda),也可以使用命令nvidia-smi
nvidia-smi显示的是显卡驱动对应的cuda版本,nvcc -V显示的运行是cuda的版本
补充说明
启动容器时,容器如果想使用GPU,镜像里必须有CUDA环境,就是说,针对想使用GPU的容器,镜像在制作时必须把CUDA环境打进去
--gpus '"device=1,2"'
,这个的意思是,将物理机的第二块、第三块GPU卡映射给容器下面三个参数代表的都是容器内可以使用物理机的所有GPU卡:
--gpus all NVIDIA_VISIBLE_DEVICES=all --runtime=nvidia
NVIDIA_VISIBLE_DEVICES=2
只公开两个GPU,容器内只能用两个GPU举例如下:
# 使用所有GPU $ docker run --gpus all nvidia/cuda:9.0-base nvidia-smi # 使用两个GPU $ docker run --gpus 2 nvidia/cuda:9.0-base nvidia-smi # 指定GPU运行 $ docker run --gpus '"device=1,2"' nvidia/cuda:9.0-base nvidia-smi $ docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:9.0-base nvidia-smi
后续注意事项
参考资料:
需要注意的是:
docker在启动容器的时候添加的
--gpus
参数确实是给容器添加了新东西的。比如/usr/bin/nvidia-smi
这个可执行程序,如果你不添加--gpus
参数是不会给你放到容器中的!此外可以推测,不加--gpus
参数,宿主的GPU将对于容器不可见。还有一个需要注意的点是nvidia-smi的输出!CUDA Version: N/A
最后,拉一个GPU docker的正确姿势:
docker run -itd --gpus all --name 容器名 -e NVIDIA_DRIVER_CAPABILITIES=compute,utility -e NVIDIA_VISIBLE_DEVICES=all 镜像名
多出来的东西其实就是这个家伙:
NVIDIA_DRIVER_CAPABILITIES=compute,utility
也就是说,如果你不改这个环境变量,宿主机的nvidia driver在容器内是仅作为utility存在的,如果加上compute,宿主机的英伟达driver将对容器提供计算支持(所谓的计算支持也就是cuda支持)。问题:容器内执行nvidia-smi不显示pid
解决方法:
# 安装包 apt-get install psmisc # 用这条命令进行查看 fuser -v /dev/nvidia*
注:本方法针对docker不显示pid而选择的另外一种间接查看方法
可以利用sudo kill -9 pid将其终止以释放显卡资源.
参考文档:https://www.cnblogs.com/linhaifeng/p/16108285.html