怎么在docker中使用nvidia显卡
https://blog.csdn.net/weixin_43590796/article/details/114848742
参考资料:
https://blog.csdn.net/qq_33547243/article/details/107433616
https://www.cnblogs.com/shoufu/p/12904832.html
https://github.com/NVIDIA/nvidia-docker/issues/533
首先介绍几个事实:
1. 最初的docker是不支持gpu的
2. 为了让docker支持nvidia显卡,英伟达公司开发了nvidia-docker。该软件是对docker的包装,使得容器能够看到并使用宿主机的nvidia显卡。
3. 根据网上的资料,从docker 19版本之后,nvidia-docker成为了过去式。不需要单独去下nvidia-docker这个独立的docker应用程序,也就是说gpu docker所需要的Runtime被集成进docker中,使用的时候用–gpus参数来控制。
(P.S.:因为本实验室服务器的docker默认是支持nvidia的runtime的,所以我在这里没有过多纠结,读者假如从零开始安装docker软件的话可能要细心地保证docker是支持gpu的docker)
几个有代表性的实验:
1. docker run 的时候不加 --gpus参数,典型代码:
docker run -it --name test --rm ubuntu:latest
此时在容器内运行nvidia-smi会提示Command not found
2. docker run 的时候加上 --gpus参数,典型代码:
docker run -it --rm --name test --gpus all ubuntu:latest
此时在容器内运行nvidia-smi会有如下输出:
从这两个实验我们可以得出结论,docker在启动容器的时候添加的–gpus参数确实是给容器添加了新东西的。比如/usr/bin/nvidia-smi这个可执行程序,如果你不添加–gpus参数是不会给你放到容器中的!此外可以推测,不加–gpus参数,宿主的gpu将对于容器不可见。
还有一个需要注意的点是nvidia-smi的输出!CUDA Version: N/A
首先,我的宿主机的CUDA是明确的11.0版本,宿主机的nvidia driver是明确的450.57版本(这一点宿主和容器一致)。那么为什么这里显示 N/A 呢?
抱着nvidia-smi能用driver一定没问题的想法,我三下五除二地在docker中安装了pytorch。可是运行测试代码的时候傻眼了,测试代码:
import torch
torch.cuda.is_available()
输出报错结果如下:
UserWarning: CUDA initialization: Found no NVIDIA driver on your system. Please check that you have an NVIDIA GPU and installed a driver from http://www.nvidia.com/Download/index.aspx (Triggered internally at /pytorch/c10/cuda/CUDAFunctions.cpp:100.)
return torch._C._cuda_getDeviceCount() > 0
为什么Pytorch找不到NVIDIA driver?? 我的driver哪里有问题?? nvidia-smi不是运行的好好的??
尝试过在docker内重装多版本的cuda无果,尝试在docker内重装nvidia驱动反而导致nvidia-smi都无法运行。直到我在参考资料3中找到了解决方案,原来是环境变量的问题。
最后,拉一个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支持)。
docker exec进入容器,再次运行nvidia-smi
和宿主机的输出就完全相同了。
再次尝试pytorch的测试代码,输出为True。
至此,你就获得了一个具有nvidia driver和cuda支持的docker。(需要注意的是,我的pytorch是直接用conda安装的,它的依赖cudatoolkits仅对conda可见,如果你需要cuda做更多事,可能还需要进一步的尝试。但是我猜想既然nvidia-smi的输出是好的,那么大概率没问题)
docker19.03读取NVIDIA显卡
前言
2019年7月的docker 19.03已经正式发布了,这次发布对我来说有两大亮点。
1,就是docker不需要root权限来启动喝运行了
2,就是支持GPU的增强功能,我们在docker里面想读取nvidia显卡再也不需要额外的安装nvidia-docker了
安装nvidia驱动
确认已检测到NVIDIA卡:
$ lspci -vv | grep -i nvidia
00:04.0 3D controller: NVIDIA Corporation GP100GL [Tesla P100 PCIe 16GB] (rev a1)
Subsystem: NVIDIA Corporation GP100GL [Tesla P100 PCIe 16GB]
Kernel modules: nvidiafb
这里不再详细介绍:如果不知道请移步ubuntu离线安装TTS服务
安装NVIDIA Container Runtime
$ cat nvidia-container-runtime-script.sh
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey |
sudo apt-key add -
distribution=$(. /etc/os-release;echo
I
D
ID
IDVERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/KaTeX parse error: Undefined control sequence: \ at position 46: …runtime.list | \̲ ̲ sudo tee /etc…(ARCH) /
deb https://nvidia.github.io/nvidia-container-runtime/ubuntu18.04/$(ARCH) /
Hit:1 http://archive.canonical.com/ubuntu bionic InRelease
Get:2 https://nvidia.github.io/libnvidia-container/ubuntu18.04/amd64 InRelease [1139 B]
Get:3 https://nvidia.github.io/nvidia-container-runtime/ubuntu18.04/amd64 InRelease [1136 B]
Hit:4 http://security.ubuntu.com/ubuntu bionic-security InRelease
Get:5 https://nvidia.github.io/libnvidia-container/ubuntu18.04/amd64 Packages [4076 B]
Get:6 https://nvidia.github.io/nvidia-container-runtime/ubuntu18.04/amd64 Packages [3084 B]
Hit:7 http://us-east4-c.gce.clouds.archive.ubuntu.com/ubuntu bionic InRelease
Hit:8 http://us-east4-c.gce.clouds.archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:9 http://us-east4-c.gce.clouds.archive.ubuntu.com/ubuntu bionic-backports InRelease
Fetched 9435 B in 1s (17.8 kB/s)
Reading package lists… Done
$ apt-get install nvidia-container-runtime
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following packages were automatically installed and are no longer required:
grub-pc-bin libnuma1
Use ‘sudo apt autoremove’ to remove them.
The following additional packages will be installed:
Get:1 https://nvidia.github.io/libnvidia-container/ubuntu18.04/amd64 libnvidia-container1 1.0.2-1 [59.1 kB]
Get:2 https://nvidia.github.io/libnvidia-container/ubuntu18.04/amd64 libnvidia-container-tools 1.0.2-1 [15.4 kB]
Get:3 https://nvidia.github.io/nvidia-container-runtime/ubuntu18.04/amd64 nvidia-container-runtime-hook 1.4.0-1 [575 kB]
…
Unpacking nvidia-container-runtime (2.0.0+docker18.09.6-3) …
Setting up libnvidia-container1:amd64 (1.0.2-1) …
Setting up libnvidia-container-tools (1.0.2-1) …
Processing triggers for libc-bin (2.27-3ubuntu1) …
Setting up nvidia-container-runtime-hook (1.4.0-1) …
Setting up nvidia-container-runtime (2.0.0+docker18.09.6-3) …
which nvidia-container-runtime-hook
/usr/bin/nvidia-container-runtime-hook
安装docker-19.03
step 1: 安装必要的一些系统工具
yum install -y yum-utils device-mapper-persistent-data lvm2
Step 2: 添加软件源信息
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Step 3: 更新并安装 Docker-CE
yum makecache fast
yum -y install docker-ce-19.03.2
Step 4: 开启Docker服务
systemctl start docker && systemctl enable docker
验证docker版本是否安装正常
$ docker version
Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:28:55 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.2
API version: 1.40 (minimum version 1.12)
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:27:34 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
验证下-gpus选项
$ docker run --help | grep -i gpus
–gpus gpu-request GPU devices to add to the container (‘all’ to pass all GPUs)
运行利用GPU的Ubuntu容器
$ docker run -it --rm --gpus all ubuntu nvidia-smi
Unable to find image ‘ubuntu:latest’ locally
latest: Pulling from library/ubuntu
f476d66f5408: Pull complete
8882c27f669e: Pull complete
d9af21273955: Pull complete
f5029279ec12: Pull complete
Digest: sha256:d26d529daa4d8567167181d9d569f2a85da3c5ecaf539cace2c6223355d69981
Status: Downloaded newer image for ubuntu:latest
Tue May 7 15:52:15 2019
±----------------------------------------------------------------------------+
| NVIDIA-SMI 390.116 Driver Version: 390.116 |
|-------------------------------±---------------------±---------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|=++==============|
| 0 Tesla P4 Off | 00000000:00:04.0 Off | 0 |
| N/A 39C P0 22W / 75W | 0MiB / 7611MiB | 0% Default |
±------------------------------±---------------------±---------------------+
±----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| No running processes found |
±----------------------------------------------------------------------------+
:~$
故障排除
您是否遇到以下错误消息:
$ docker run -it --rm --gpus all debian
docker: Error response from daemon: linux runtime spec devices: could not select device driver “” with capabilities: [[gpu]].
上述错误意味着Nvidia无法正确注册Docker。它实际上意味着驱动程序未正确安装在主机上。这也可能意味着安装了nvidia容器工具而无需重新启动docker守护程序:您需要重新启动docker守护程序。
我建议你回去验证是否安装了nvidia-container-runtime或者重新启动Docker守护进程。
列出GPU设备
$ docker run -it --rm --gpus all ubuntu nvidia-smi -L
GPU 0: Tesla P4 (UUID: GPU-fa974b1d-3c17-ed92-28d0-805c6d089601)
$ docker run -it --rm --gpus all ubuntu nvidia-smi --query-gpu=index,name,uui
d,serial --format=csv
index, name, uuid, serial
0, Tesla P4, GPU-fa974b1d-3c17-ed92-28d0-805c6d089601, 0325017070224
原文转载至: https://collabnix.com/introducing-new-docker-cli-api-support-for-nvidia-gpus-under-docker-engine-19-03-0-beta-release/
docker/nvidia-docker使用整理
赵小闹闹
0.183
2019.06.05 18:03:53
字数 822
阅读 16,791
1.打开nvidia-docker
sudo nvidia-docker run -it -p 7777:8888 tensorflow/tensorflow:latest-gpu
2.docker内打开jupyter notebook
jupyter notebook --ip 0.0.0.0 --no-browser --allow-root
第一次浏览器打开jupyter notebook
172.28.9.220:7777/tree?token=9Llv9cCqyNv1Vf7g
172.28.9.220是服务器的ip
7777是开docker是映射号
token是docker开jupyter时显示的token
之后直接使用开启即可
172.28.9.220:7777
3.查看已安装docker
sudo docker images
查看正在运行的容器
sudo docker ps
容器做完修改必须保存
sudo dcoker commit 容器id 容器名
sudo docker commit f55f8ba11f95 tensorflow/tensorflow:latest-gpu
停止某容器
sudo docker stop 容器id
4.docker配置jupyter notebook
创建存放jupyter notebook的文件夹
mkdir [存放notebook的文件夹]
mkdir jupyter
此时相当于在主机的/home/下创建了jupyter文件夹
3.2 如果容器内没有jupyter notebook,需要安装一下
pip install jupyter notebook
3.3 配置jupyter notebook
jupyter notebook --generate-config
vim ~/.jupyter/jupyter-notebook-config.py
1
2
修改如下内容
允许root启动
c.NotebookApp.allow_root = True
允许远程访问
c.NotebookApp.ip = ‘0.0.0.0’
设置notebook文件夹
c.NotebookApp.notebook_dir = ‘/jupyter’
设置静态token,这样就不用每次换token了,另一种方法是设置密码password
c.NotebookApp.token = ‘[自定义token]’
3.4 开启notebook
jupyter notebook &
按Ctrl+P+Q退出容器但不关闭
5 docker运行脚本出现错误
ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm).
解决方案
sudo nvidia-docker run --ipc=host -it -p 7790:8888 liu
启动docker时候加上参数–ipc=host
6 向容器里传文件
sudo docker cp /home/user/zhaobing/docker/tensorflow-mnist/mnist_tfserving_model bafaaaa573b4:/
7 在多个shell中启动同一个docker
启动docker后,在新的窗口:
docker exec -it <container_id> bash
8 docker 挂载卷
nvidia-docker run -it -v /home/user/workspace/liu/remote_workspace:/workspace/liu/remote_workspace retinaface
使用nvidia-docker run 而不是docker run
使用docker run 跑代码发生错误
挂载卷:前后为本地路径与docker内路径,要注意需要哪一级挂到哪一级,防止挂到子目录无法使用上级目录的情况。
9 docker 镜像的导出与导入
1.镜像保存
先使用docker images查询docker id
image.png
使用docker save命令保存为.tar文件
docker save 8ca8d > retinaface.tar
2.镜像导入
docker load < retinaface.tar
导入后使用下述命令给images 命名
docker tag 8ca8dfe44635 retinaface
10.镜像与容器的删除
查询镜像
docker ps
删除镜像
docker rmi
查询容器
docker images
删除容器
docker rm
理论上要先删除容器,才能删除镜像。
- 容器开启无gpu
使用docker run命令开启docker 使用nvidai-smi 发现无GPU信息,可以做如下调整。
sudo docker run -it --gpus all -p 7777:8888 pytorch-zhao
加上–gpus all
12镜像删除
删除docker image 中的镜像
sudo docker image rm ‘REPOSITORY:TAG’
#镜像名:tagm 默认为latest
13docker重命名
docker tag IMAGEID(镜像id) REPOSITORY:TAG
#新的image名和tag
14删除镜像名或者tag为none的镜像
对于REPOSITORY和TAG均为none的镜像
image.png
docker image prune
对于tag为none的镜像
image.png
先使用docker tag命令改名,将tag重命名为latest,再用docker image rm删除
15.docker启动挂载路径
sudo docker run -it -v /data/docker/lib:/workspace pytorch:latest
sudo docker run -it --gpus all -p 7777:8888 -v /data/docker/lib:/workspace pytorch:latest
15.5docker启动时规定内存
使用mmdetection等大型项目时可能出现报错内存过小无法训练的情况,可以指定–shm-size 8G
sudo docker run -it --gpus all -p 7775:8888 --shm-size 8G -v /home/zhaobing:/workspace mmdetection:latest
16. pytorch py2版本镜像地址
https://hub.docker.com/r/vanessa/pytorch-dev/tags/?page=1&ordering=last_updated
17 docker最推荐打开方式
docker run用于最开始开启一个镜像,开启后不要关闭
通过docker attach 可以同步进入docker run开启的镜像界面,缺点是多人开启时均为同步界面,造成混乱,同时关闭该镜像,docker run开启的镜像也会被关闭
推荐通过docker exec命令进入镜像,没有docker attach的缺点
docker exec -it wizardly_chaplygin bash
-it后为docker ps 查看的开启的docker name
18 Nvidia释放显存方法
当出现爆显存,CUDA_ERROR_OUT_OF_MEMORY
sudo kill -9 PID
可杀死相应进程,同时在计算过程给脚本规定使用的GPU可降低tensorflow出现浪费GPU现存问题
CUDA_VISIBLE_DEVICES=x
19. ps u pid
查看某个pid启动时运行命令
安装使用NVIDIA-Docker-- 可使用GPU的Docker容器
nvidia-docker是一个可以使用GPU的docker,nvidia-docker是在docker上做了一层封装,通过nvidia-docker-plugin,然后调用到docker上,其最终实现的还是在docker的启动命令上携带一些必要的参数。因此在安装nvidia-docker之前,还是需要安装docker的。
docker一般都是使用基于CPU的应用,而如果是GPU的话,就需要安装特有的硬件环境,比如需要安装nvidia driver。所以docker容器并不直接支持Nvidia GPU。为了解决这个问题,最早的处理办法是在容器内部,全部重新安装nvidia driver,然后通过设置相应的设备参数来启动container,然而这种办法是很脆弱的。因为宿主机的driver的版本必须完全匹配容器内的driver版本,这样导致docker image无法共享,很可能本地机器的不一致导致每台机器都需要去重复操作,这很大的违背了docker的设计之初。
为了使docker image能很便利的使用Nvidia GPU,从而产生了nvidia-docker,由它来制作nvidia driver的image,这就要求在目标机器上启动container时,确保字符设备以及驱动文件已经被挂载。
nvidia-docker-plugin是一个docker plugin,被用来帮助我们轻松部署container到GPU混合的环境下。类似一个守护进程,发现宿主机驱动文件以及GPU 设备,并且将这些挂载到来自docker守护进程的请求中。以此来支持docker GPU的使用。
需提前安装好的软件
docker
由于nvidia docker是基于docker基础之上运行的,因此需要安装原生的docker。
1.12.6版本的docker安装可查看这篇文章:Docker安装使用命令。http://www.linuxidc.com/Linux/2017-12/149575.htm
Docker CE版本可查看这篇文章:Docker CE安装教程。http://www.linuxidc.com/Linux/2017-12/149576.htm
nvidia显卡驱动
毫无疑问,要想使用GPU,必须要安装显卡驱动,这样nvidia docker才能正常运行。
显卡驱动的安装方式可查看这篇文章: CentOS集成GTX-1080Ti显卡搭建深度学习环境全过程。http://www.linuxidc.com/Linux/2017-12/149577.htm
这篇文章中讲解了CentOS安装显卡搭建深度学习环境的全过程,显卡驱动就是其中一项工作,因此这里就不单独写了,这篇文章中有安装的过程。
安装nvidia docker
1、下载nvidia-docker.repo文件,并将该文件输出到/etc/yum.repos.d/nvidia-docker.repo
curl -s -L https://nvidia.github.io/nvidia-docker/centos7/x86_64/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
操作结果:
这里写图片描述
2、查找可安装的nvidia docker版本
yum search --showduplicates nvidia-docker
运行上面的语句,会出现下面这张图中的信息,一路点击y
这里写图片描述
最终输出结果是下面这张图:
这里写图片描述
大家可以从中选择自己需要安装的nvidia docker版本,这里我安装的是docker是1.12.6版本的。因此我选择安装倒数第一个版本的nvidia docker。
3、安装nvidia-docker
yum install nvidia-docker-1.0.1-1.x86_64
点击回车,系统就会安装nvidia-docker,需要选yes\no的地方输入y,再点击回车,最终安装成功。
运行nvidia docker
1、运行docker:
// 运行docker
systemctl start docker
// 加入开机启动
systemctl enable docker
// 查看状态
systemctl status coker
2、运行nvidia-docker:
systemctl start nvidia-docker
systemctl enable nvidia-docker
systemctl status nvidia-docker
nvidia-docker的操作命令与docker基本相同,所以操作起来没有什么障碍。
kubernetes调用GPU
yaml文件配置:
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
volumes:
- name: nvidia-driver
hostPath:
path: /var/lib/nvidia-docker/volumes/nvidia_driver/384.69 - name: cgroup
hostPath:
path: /sys/fs/cgroup
containers: - name: tensorflow
image: tensorflow:0.11.0-gpu
ports:- containerPort: 8000
resources:
limits:
alpha.kubernetes.io/nvidia-gpu: 1
volumeMounts: - name: nvidia-driver
mountPath: /usr/local/nvidia/
readOnly: true - name: cgroup
mountPath: /sys/fs/cgroup
alpha.kubernetes.io/nvidia-gpu: 1:表示只使用1块gpu
- containerPort: 8000
path: /var/lib/nvidia-docker/volumes/nvidia_driver/384.69:宿主机driver位置,安装了nvidia-docker之后有的,当然需要保证宿主机nvidia driver是已经安装ok的,应该是安装了nvidia-docker之后,会发现宿主机的driver,然后映射到此。
path: /sys/fs/cgroup:挂载该目录也是为了识别显卡,使容器内部能够使用宿主机显卡。
volumeMounts:将宿主机目录挂载到容器内部,这个标签下的配置项就是要把宿主机目录挂载到容器内部的那个目录,通过name标识。
通过这些目录挂载配置,启动pod之后,容器就能够正常识别GPU并进行工作了。
更多Docker相关教程见以下内容:
Docker安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm
Ubuntu 16.04 服务器上配置使用 Docker http://www.linuxidc.com/Linux/2017-06/145176.htm
Ubuntu 15.04下安装Docker http://www.linuxidc.com/Linux/2015-07/120444.htm
Docker 安装实例 http://www.linuxidc.com/Linux/2017-04/142666.htm
Docker 创建基础镜像 http://www.linuxidc.com/Linux/2017-05/144112.htm
在 Ubuntu 15.04 上如何安装Docker及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm
Ubuntu 16.04上Docker使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm
使用Docker分分钟启动常用应用 http://www.linuxidc.com/Linux/2017-04/142649.htm
Ubuntu 16.04下Docker修改配置文件不生效解决办法 http://www.linuxidc.com/Linux/2017-05/143862.htm
Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-12/149578.htm