平台:Ubuntu18.04 —— 主要参考:菜鸟教程
Docker 包括三个基本概念:
- 镜像(Image):镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像
注意镜像和容器的区别,是用run启动镜像,得到一个对应的容器,容器停止后可以用start启动。镜像名 ≠ 容器名,镜像ID ≠ 容器ID;
镜像系统一般都需要apt update一下
一、安装docker工具
1. 按 菜鸟教程 中“Ubuntu Docker 安装——手动安装 ”的指导进行。
执行测试
sudo docker run hello-world # 报错是由于官方源在国外,无法连接 Unable to find image 'hello-world:latest' locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
2. 添加国内源,重新尝试即可。 ——参考
sudo vim /etc/docker/daemon.json # 编辑配置文件,163的挺好用 # 添加下面的内容 { "registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"] } sudo systemctl restart docker.service # 重启docker服务
3. 添加当前用户到docker用户组 ——参考
docker默认属于root用户,其它用户要使用docker命令需要sudo权限。可以将需要的账号添加到docker用户组下,就不必每次都用sudo了。
cat /etc/group # 查看有哪些分组 sudo usermod -aG docker username # 将username用户添加到docker分组里 newgrp docker # 更新分组信息
docker run hello-world # 测试
二、 常用命令
1.
docker ps # 查看正在运行的容器
docker rm container_name/id # 删除容器
docker rmi image_name/ID # 删除镜像
docker run image_name/ID # 运行镜像生成容器,有时候运行失败也会生成一个容器
docker run -it ubuntu /bin/bash # -i:交互式,-t:终端,即启动镜像ubuntu并进入其命令行终端shell:/bin/bash;这时exit后容器将停止(exited)
docker logs container_name/ID # 查看容器内的标准输出
docker stop container_name/ID # 停止运行容器
docker start container_name/ID # 启动一个已经停止运行容器
docker restart container_name/ID # 重启容器
docker exec -it container_name/ID /bin/bash # 进入已启动的容器的终端,这时exit后容器还在后台运行(Up)
# 镜像打包与加载
docker save image_name/ID -o filename.tar # 镜像打包的内容包括各种历史记录,会比较大
docker load -i filename.tar # 镜像load后还是原来的名称
# 容器打包与加载
docker commit container_name/ID image_name:version # 把容器打包为镜像
docker export container_name/ID > exportname.tar # 导出为tar包
docker import exportname.tar new_image_name:version # 导入容器为新镜像,可以定义新镜像名
docker tag image_id new_image_name # 镜像重命名/增加新指引label,这之后将有两个镜像名称指向一个镜像id,可以删掉其中一个名称 ——参考
docker rename container_name new_container_name # 容器重命名,容器名用 docker ps -a 可以看到,NAMES(这个名称一般是随机生成的)
2. 主机与docker容器之间的文件传输(容器间不行) ——参考
# 容器中不存在的目录将自动创建
# 在宿主机目录,向容器传输文件 docker cp path/to/file container_name:/target/path/ # "/target/path/"必须存在并以反斜杠 / 结尾,否则只会在target/目录下形成一个叫 path 的文件
# 在宿主机目录,从容器向宿主机传输文件
docker cp dockername:/path/to/file target/path
** 挂载主机目录到容器 ——详解
docker run -it -v /path/of/source/directoy:/target/path/in/container image_name/ID /bin/bash # source在宿主机上,两边的路径都用绝对路径
** 一个例子
主机上有目录 /home/work,容器导出的镜像内有新建的目录 /home/job,里面是向容器内新加的文件,
docker run -it -v /home/work/:/home/ image_name/ID /bin/bash # × 容器内 /home/job目录不见了(看不到,ls不了),因为主机的相关目录挂载到容器内的/home/下面了,和job同级,都在/home/目录下,job目录被掩盖了(实际上还在) docker run -it -v /home/work/:/home/job/ image_name/ID /bin/bash # √ 容器内 /home/job目录还在,可以正常使用
3. 常用工具安装
apt install vim # 默认不包含vim
4. 在docker安装驱动时出现问题 —— 问题暂未解决
“An NVIDIA kernel module 'nvidia-uvm' appears to already be loaded in your kernel. This may be because it is in use (for example, by an X server, a CUDA program, or the NVIDIA Persistence Daemon), but this may also happen if your kernel was configured without support for module unloading...."
lsmod | grep nvidia # 查看nvidia的相关module,输出依次为:Module, Size, Used, by
二、安装nvidia-docker
如果要在容器内跑使用GPU的程序,需要安装nvidia-docker,这样可以在docker内直接调用宿主机的GPU。
如果直接在容器内安装nvidia的驱动,配置cuda环境,在使用时将需要指定宿主机的GPU位置,类似于/devices/gpu0 这样的。
nvidia-docker 安装方法按照 nvidia官方文档即可;博客可 参考
验证可用后,可以去 docker官方 找 nvidia/cuda 相关的镜像,这些镜像像其它镜像一样用即可,里面已经安装了对应版本的cuda等内容。
** 版本含义,如:10.1-cudnn7-runtime-ubuntu18.04表示:ubuntu系统库,cuda10.1,cudnn7,runtime版。
** 三个版本的nvidia-docker(三个版本的size依次增大) ——参考
base版:只有基础的库(libcudart);
runtime版:有所有的共享库,调用即可;
devel版:即开发版,包含共享库和编译、调试工具,头文件等,有bin/目录和nvcc,libcudnn在 /usr/lib/x86_64-linux-gnu/libcudnn.so。
1. 问题:OsError: libcudnn.so.7: cannot open shared object file: No such file or directory
背景:使用devel-cudnn8版的nvidia-docker,pip安装torch,torchvision
解决:下载了一个cudnn7.5的库包,解压到docker内(名为cuda/),设置LD_LIBRARY_PATH环境变量,将 path/to/cuda/lib64(内涵目标链接库)加入该环境变量,然后source ~/.bashrc即可