docker ps :查看正在运行的容器
docker ps -a:查看所有的容器,包括死掉的容器和正在运行的容器

1.本机和docker容器共享文件夹

1、在本机中某个文件下建立一个文件夹

mkdir -p /home/zs/share

2、利用docker run 创建一个带有共享文件夹的容器

作用:挂载宿主机的一个目录
如:# docker run -it -v /宿主机目录:/容器目录 镜像名 /bin/bash
docker run -it -v /home/zs/share:/home/zs/share  --name zs ca2056b7d9a8  /bin/bash
#docker run -it -v 主机文件夹路径:容器内文件夹路径 --name 希望创建的容器名字 镜像名:版本名 bash

其中aaa修改成自己的用户名,development 为创建容器的名字,ca2056b7d9a8为 创建容器的镜像ID

2.docker安装cuda

执行如下命令:


sudo bash cuda_10.0.130_410.48_linux.run

报错缺少libxml2

root@computer:/home/share# bash cuda_10.1.105_418.39_linux.run 
./cuda-installer: error while loading shared libraries: libxml2.so.2: cannot open shared object file: No such file or directory
root@computer:/home/share# apt install libxml2

报错gcc版本不对,如下

$ sudo sh cuda_10.2.89_440.33.01_linux.run
Failed to verify gcc version. 
See log at /var/log/cuda-installer.log for details.

然后vim查看文件/var/log/cuda-installer.log
说是GCC版本不兼容,要是想忽略这个问题,请使用–override参数

于是乎就可以:

sudo sh cuda_10.2.89_440.33.01_linux.run --override

安装完成后,设置环境变量

打开主目录下的 .bashrc文件添加如下路径,例如我的.bashrc文件在/home/lu/下。
 
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-10.0/lib64
    export PATH=$PATH:/usr/local/cuda-10.0/bin
    export CUDA_HOME=$CUDA_HOME:/usr/local/cuda-10.0
 
终端运行:source ~/.bashrc
 
检查:nvcc --version

3. docker使用nvidia驱动

首先介绍几个事实:

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的输出是好的,那么大概率没问题)
总结:
docker共享主机nvidia驱动

docker run -itd --gpus all --name bs1 -e NVIDIA_DRIVER_CAPABILITIES=compute,utility -e NVIDIA_VISIBLE_DEVICES=all ubuntu
#bs1为我创建的容器名 ubuntu为拉的镜像名

报错:docker: Error response from daemon: could not select device driver ““ with capabilities: [[gpu]].

需要安装nvidia-container-toolkit或nvidia-container-runtime(包含nvidia-container-toolkit)

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - 
#正常会显示OK
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list 我的系统是Ubuntu18.04
sudo apt-get update 
#这一步要保证没得问题,我的显示有几个源重复配置,然后我就将其(sudo vim nvidia-docker.list)注释掉
sudo apt-get install nvidia-container-toolkit
sudo systemctl restart docker

重启docker后成功!

添加/删除用户以及密码

sudo useradd –d /home/username –m –s /bin/bash username
#设置或者更改密码
sudo passwd username
#删除用户:
sudo userdel –r username
#username为你添加的用户名同时也是镜像名

将用户添加到docker组

sudo adduser bs1 docker
#正在添加用户"bs1"到"docker"组...
#正在将用户“bs1”加入到“docker”组中
#完成。

#启动容器,开机或者重启之后
docker start bs1
#关闭容器
docker stop bs1

4.Xavier AGX

sudo docker run -it --gpus all --net host --restart always -p 8050:8050 seg:v2 /bin/bash
docker run -itd --net=host ripl/lcm:latest /bin/bash #docker容器中的网络共享宿主机的网络。(lcm通信中会用到)

5.根据Linux进程号(PID)找到docker容器

当使用top、ps等命令找到了linux进程时,如果是某个docker容器,但是无法准确找到容器ID。可以通过以下方式找到docker容器:

5.1步骤一

获取进程号(PID):首先,你需要获取你想要查询的进程的 PID。你可以使用 ps 命令或 top 命令来查找正在运行的进程的 PID。例如,要查看 PID 为 12345 的进程,运行:

ps aux | grep 12345

5.2步骤二

查找容器 ID:然后,你可以通过访问 /proc/[PID]/cgroup 文件来查找 Docker 容器的 ID。在这个文件中,你会找到有关容器的信息。在终端运行以下命令,将 [PID] 替换为你的进程号:

cat /proc/[PID]/cgroup

这会列出包含 Docker 容器 ID 的一行,类似于:

1:name=systemd:/docker/[CONTAINER_ID]

5.3步骤三

CONTAINER_ID的前12位即[短容器ID],使用docker ps可以筛选出对应的容器,例如以下命令:

docker ps |grep c35229c02f

补充:
如果想实时监控docker容器运行状态,可以使用以下命令即可:

docker stats
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐