An introduction to Docker for deep learning researcher
Docker 极简教程
作者不对文章内容以及文章内容使用不当引发的任何后果负任何责任。请谨慎敲下每一个命令。本文档的目的是帮助深度学习新手一个小时内快速上手docker。
预备知识
本文档假定读者具有基本的docker知识, 一些Ubuntu操作经验, 基本的git操作基础. 如果你遇到问题,请首先通过搜索引擎尝试寻找解决方案. 后面再求助能够帮助你的人.
安装
不同平台的安装方式请查看Docker官方文档 (https://docs.docker.com/engine/install/).
这里以Ubuntu系统为例子
安装Docker 文件
首先添加源:
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
然后安装docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli
接下来检测是否正常安装.
输入
sudo docker run hello-world
然后显示
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:97a379f4f88575512824f3b352bc03cd75e239179eea0fecc38e597b2209f49a
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Centos 安装docker
sudo /bin/yum update
sudo /bin/yum install -y yum-utils device-mapper-persistent-data lvm2
设置源
yum -y install yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum list docker-ce --showduplicates | sort -r
然后选择安装
yum install docker-ce
接下来安装nvidia-docker
首先配置
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 clean expire-cache
安装
sudo yum install -y nvidia-docker2
通过测试
docker -v
centos上的一些小命令
df -Th /var/lib/docker
df -h
第一个命令查看目标目录使用情况
第二个命令查看整体情况
安装nvidia docker
为了调用显卡, 我们还需要安装nvidia docker, 请参考官方文档进行安装.
下面我们以Ubuntu 平台为例.
设置docker
curl https://get.docker.com | sh \
&& sudo systemctl --now enable docker
设置nvidia 容器工具
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-docker2
重启
sudo systemctl restart docker
然后检查一下是不是可用
sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi
如果显示,
Mon Feb 28 01:46:31 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.103.01 Driver Version: 470.103.01 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 On | N/A |
| 46% 44C P0 49W / 180W | 803MiB / 8119MiB | 1% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
那么就搞定了.
离线安装docker
在这里可以下载离线的docker文件.
找到存放有docker-20.10.9.tgz
的文件夹. 注意你可能需要sudo权限.
首先解压
tar -xzvf docker-20.10.9.tgz
之后进入docker目录, 并且将所有文件拷贝到/usr/bin/
目录下
cd docker/
cp * /usr/bin/
将如下内容写入/etc/systemd/system/docker.service
vim /etc/systemd/system/docker.service
然后在弹出来的页面写入
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
给刚才写入的文件增加权限
chmod +x /etc/systemd/system/docker.service
systemctl daemon-reload
设置开启启动docker
systemctl enable docker.service
然后启动docker
systemctl start docker
然后通过以下方式检查docker是否安装
docker -v
如果弹出
Docker version 20.10.9, build c2ea9bc
那么说明安装成功.
离线安装nvidia docker
想在Docker中用GPU资源,就需要安装NVIDIA Container Toolkit,如果工作站能连外网,按照官网的步骤很容易安装,但如果不能连外网,比如只能在校园网IP范围内使用,该如何安装呢?
预设条件:已经安装好了显卡驱动和Docker 以下所有下载任务选择最新版;
Step 1. 下载libnvidia-container
安装包(在Ubuntu下是deb文件)
通过VPN传到工作站上,运行
sudo dpkg -i libnvidia-container1_1.4.0-1_amd64.deb
然后下载安装libnvidia-container-tools
https://github.com/NVIDIA/libnvidia-container/tree/gh-pages/stable
Step 2. 下载nvidia-container-toolkit
和 nvidia-container-runtime
以Ubuntu 18.04 为例,分别运行
sudo dpkg -i nvidia-container-toolkit_1.5.1-1_amd64.deb
sudo dpkg -i nvidia-container-runtime_3.5.0-1_amd64.deb
Step 3. 下载nvidia-docker2
并上传到工作站、安装
NVIDIA/nvidia-docker at gh-pages (github.com)github.com/NVIDIA/nvidia-docker/tree/gh-pages
sudo dpkg -i nvidia-docker2_2.6.0-1_all.deb
Step 4. 重启Docker
sudo service docker restart
为非root用户配置docker 使用权限
- 使用root用户登录
- 新建用户组docker之前,查看用户组中有没有docker组
sudo cat /etc/group | grep docker
- 创建docker分组,并将相应的用户添加到这个分组里面
sudo groupadd -g 999 docker
sudo usermod -aG docker quyuxun
- 检查一下创建是否有效
cat /etc/group
-
退出当前登录用户,或者重启docker,以让docker用户组生效
-
确认可以使用docker
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
如果提示get ……dial unix /var/run/docker.sock权限不够,则修改/var/run/docker.sock权限
sudo chmod a+rw /var/run/docker.sock
配置baseline的docker
baseline 是openai开发的代码库,用来搞强化学习,没有需求的同学可以跳过。
baseline的安装
注意baseline需要有prerequisite
sudo apt-get update && sudo apt-get install cmake libopenmpi-dev python3-dev zlib1g-dev
然后下载baselines
git clone https://github.com/openai/baselines.git
cd baselines
然后安装tensorflow-gpu
pip install tensorflow-gpu
切换到tf2分支(如果愿意,也可以使用tf1), 并且安装
git checkout tf2
pip install -e .
然后使用如下代码进行测试
python -m baselines.run --alg=ppo2 --env=PongNoFrameskip-v4 --num_timesteps=0 --load_path=~/models/pong_20M_ppo2 --play
这个时候, 你会看到一个gui界面, 那么就成功了.
然后开始制作docker镜像
sudo docker build -t docker_sample:latest .
sudo docker build -t tl_rl:0.1 .
这里的 .
是目录, docker_sample是镜像名字, latest是版本号, 可以用0.1
等标记.
然后导出docker镜像
sudo docker save -o docker_image_name.tar docker_sample:latest
sudo docker save -o tf_rl.tar tl_rl:0.1
注意, 导出的镜像可能由于所有者权限问题, 而无法被移动或者复制, 这时候我们需要修改文件权限
sudo chmod 777 docker_image_name.tar
Docker 镜像的使用
使用压缩好的docker
sudo docker load -i rl_tf.tar
sudo docker load --input rl_tf.tar
11936051f93b: Loading layer [==================================================>] 129.1MB/129.1MB
...
f63153c62cad: Loading layer [==================================================>] 2.179GB/2.179GB
Loaded image: rl_tf:0.1
然后我们sudo docker images
可以看到
REPOSITORY TAG IMAGE ID CREATED SIZE
rl_tf 0.1 e5e284047d3f About an hour ago 3.48GB
注意, 我们将这个image ID复制下来, 然后
sudo docker run -it --rm e5e284047d3f /bin/bash
sudo docker run --gpus all -it --rm fe7dab327f77 /bin/bash
python -m baselines.run --alg=ppo2 --env=MountainCar-v0
CUDA_VISIBLE_DEVICES=4 python train.py
接下来我们就进入了docker 容器了
root@8dc4fac45394:~/code/baselines#
查看uid
id
uid=1009(quyuxun) gid=1009(quyuxun) groups=1009(quyuxun)
可以看到此时的uid为1009
然后
docker run -it --user=1009 --gpus=all ed62683294a2 /bin/bash
显示
------------------------------------------
| eplenmean | 200 |
| eprewmean | -200 |
| fps | 1093 |
| loss/approxkl | 8.478222e-05 |
| loss/clipfrac | 0.0 |
| loss/policy_entropy | 1.0985302 |
| loss/policy_loss | -0.000300169 |
| loss/value_loss | 121.43289 |
| misc/explained_variance | -0.000372 |
| misc/nupdates | 1 |
| misc/serial_timesteps | 2048 |
| misc/time_elapsed | 1.87 |
| misc/total_timesteps | 2048 |
------------------------------------------
拉取Docker image
sudo docker pull davidfitzek/stable-baselines3-gpu:0.4
然后就开始拉取了
(baseline) mirror@mirror:~/Documents/code/Baseline_Docker/baselines/baselines$ sudo docker pull davidfitzek/stable-baselines3-gpu:0.4
0.4: Pulling from davidfitzek/stable-baselines3-gpu
...
Digest: sha256:5b3f1606b747b1ea9dabc23b8c4970e5141845e89b9df9a4ea9f013128e1bcdf
Status: Downloaded newer image for davidfitzek/stable-baselines3-gpu:0.4
docker.io/davidfitzek/stable-baselines3-gpu:0.4
然后开始运行docker
sudo docker run -it --rm davidfitzek/stable-baselines3-gpu:0.4
使用如下脚本测试
from stable_baselines3 import PPO
model = PPO('MlpPolicy', 'CartPole-v1').learn(10000)
安装ROM
为了让你的电脑能够运行atari游戏,你需要安装atari的rom
进入: https://github.com/openai/atari-py#roms
然后解压到一个位置, 接下来安装
python -m atari_py.import_roms <path to folder>
注意, 安装之后就不要移动rom的位置了, 否则会造成运行出问题.
如果这个脚本无法成功运行, 也可以将文件手动拷贝到你的atari_roms目录下
~/anaconda3/envs/baseline/lib/python3.6/site-packages/atari_py/atari_roms
使用ALE环境安装atari
如果你无法使用atari-py安装rom, 那么请你使用ALE环境
https://github.com/mgbellemare/Arcade-Learning-Environment
pip install ale-py
ale-import-roms roms/
将anaconda环境迁移到docker中
首先搜索anaconda镜像
docker search anaconda
然后拉取镜像
docker pull anaconda
然后运行镜像
sudo docker run -i -t continuumio/anaconda3 /bin/bash
sudo docker run --gpus all -it --rm continuumio/anaconda3 /bin/bash
# sudo docker run -i -t continuumio/anaconda3 /bin/bash 909fa31992e8
# sudo docker run --gpus all nvidia/cuda:10.1 curl
docker环境下,查找anaconda路径
whereis anaconda
本地环境下 复制本地环境到docker
docker cp your_path/anaconda3/envs/env_name docker_name:anaconda_path/envs
# sudo docker cp /home/mirror/anaconda3/envs/rprl 909fa31992e8:.
这里要注意,首先我们要选择dockerID进行复制,这个ID通过docker ps -a
查看,然后选择对应的ID。
之后我们使用
将docker容器保存为镜像
docker commit -a [author] -m [instruction] docker_name image_name
sudo docker commit -a heqiang -m 909fa31992e8 curl
$ sudo docker commit -m "Add curl code" -a "heqiang" 4ece334a2d32 curl:latest
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
其中,-m 来指定提交的说明信息,跟我们使用的版本控制工具一样;-a 可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID 信息。
查看新镜像
docker image ls
将镜像保存为压缩包
docker save image_name -o compressed_package_name.tar
docker镜像导入 在新的机器上导入之前创建的docekr环境。
docker load -i compressed_package_name
启动docker镜像
docker run -i -t docker_image_name /bin/bash
Docker 数据存储
什么是数据卷
我们都知道在Docker中,容器的数据读写默认发生在容器的存储层,当容器被删除时其上的数据将会丢失。如果想实现数据的持久化,就需要将容器和宿主机建立联系(将数据从宿主机挂载到容器内),通俗的说,数据卷就是在容器和宿主机之间实现数据共享。
Docker支持的三种数据挂载方式
Docker提供了三种不同的方式将数据从宿主机挂载到容器中:volume、bind mounts、tmpfs mounts
volume:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
bind mounts:可以存储在宿主机系统的任意位置
使用绑定数据卷存储数据
docker run -it --mount type=bind,source=/opt,target=/root/code/curl/curl_data/ curl /bin/bash
这样就完成了目录的映射,然后将数据存储在对应的目录上就好了,即使是退出docker,也能保存docker产生的数据。
tmpfs mounts:挂载存储在宿主机系统的内存中,不会写入宿主机的文件系统
©著作权归作者所有:来自51CTO博客作者qq6136ff484095f的原创作品,请联系作者获取转载授权,否则将追究法律责任 Docker数据存储方式:数据卷(Data Volume) https://blog.51cto.com/u_15358844/3792845
使用技巧
30系显卡的使用
30系的显卡,需要对的cuda 的torch版本
使用这种方法来安装torch版本就好了,这个请在Dockerfile里完成。
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113
基本技巧
如下是常用docker 命令.
制作docker
sudo docker build -t popro:latest .
制作docker文件
docker save image_name -o compressed_package_name
删除容器
docker rm CONTAINER_ID
列出所有容器(包括正在运行的和已经退出的容器)
docker ps -a
停止正在运行的容器
docker stop CONTAINER_ID
删除镜像(删除镜像之前需要删除所有该镜像下的容器)
docker rmi IMAGE_ID
重命名
docker tag 0d5b39aeafc2 rprl:1.0
导出docker镜像
sudo docker save -o docker_image_name.tar docker_sample:latest
sudo docker save -o tf_rl.tar tl_rl:0.1
注意, 导出的镜像可能由于所有者权限问题, 而无法被移动或者复制, 这时候我们需要修改文件权限
sudo chmod 777 docker_image_name.tar
将docker容器保存为镜像
docker commit -a [author] -m [instruction] docker_name image_name
sudo docker commit -a heqiang -m 909fa31992e8 curl
$ sudo docker commit -m "Add curl code" -a "heqiang" 4ece334a2d32 curl:latest
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
其中,-m 来指定提交的说明信息,跟我们使用的版本控制工具一样;-a 可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID 信息。
查看新镜像
docker run启动一个docker之后,就会生成一个容器,然后这个容器就会一直存在系统里,因此不用再使用docker run启动新的容器了。
所以目前再找到之前保存的docker logs,然后找到ID,启动就好了
寻找docker ID
docker ps -a
寻找该docker 下发生了啥
docker logs docker_Id
然后启动该docker
docker start docker_id
之后再attach上docker就好了
docker attach docker_name
清理整个docker 系统
docker system prune
写dockerfile的时候
FROM不需要注明版本号,例如
FROM continuumio/anaconda3
记得要写-y
docker layer的逻辑
docker 会对每一次run,都生成一次layer,所以我们可以将一堆shell脚本,打包在一起,例如 docker.sh
然后,我们输入如下语句,就可以了
COPY docker.sh .
RUN chmod +x docker.sh
RUN ./docker.sh
普通用户使用docker
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo systemctl restart docker
BUG 排除
这里提供一些bug的排除机制
ImportError: cannot import name ‘FlattenDictWrapper’
这是由于gym环境的支持问题, 使用baseline的tf2分支, 请使用gym==0.14
解决:
pip install gym==0.14
Error response from daemon: could not select device driver ““ with capabilities: [[gpu]]
安装nvidia-docker就可以解决。见
终端设置代理
export http_proxy=http://127.0.0.1:12333
MuJoCo: distutils.errors.CompileError: command ‘gcc’ failed with exit status 1
sudo apt install libosmesa6-dev libgl1-mesa-glx libglfw3
sudo apt-get install patchelf
sudo apt install libosmesa6-dev
Enjoy Reading This Article?
Here are some more articles you might like to read next: