本文的目的是使用Docker创建并分享一个深度学习环境。

使用Docker安装环境的优点如下:

  1. 无需自己配置环境,通过 Docker 镜像可以使用各种已配置好的深度学习环境。
  2. 轻量便捷。一个 Docker 客户端+一个镜像,总共大约3~4G即可组成一个深度学习系统环境。
  3. 便于分享。可以将自己的环境通过镜像库或直接以文件拷贝的方式传播。
  4. 官方支持。很多深度学习框架&项目提供官方 Docker 镜像。

目录

  1. 安装docker
  2. 安装nvidia-docker(需要GPU支持)
  3. “Vscode + docker+pytorch”来远程访问notebook
  4. 容器的快照与载入
  5. 通过容器实操远程notebook
  6. 常用命令

1、安装docker(在ubuntu上)

ubantu官方安装指南

linux命令行中测试安装是否成功:sudo docker run hello-world
这条指令会下载hello-world镜像并实例化这个它,输出如下结果:
image.png

关于wsl2的情况

安装wsl2的官方指南 wsl2下安装docker的官方指南 不可使用wsl1,这是因为wsl2与wsl1不同在于,wsl2具备完整的linux内核,这是docker所必须的。

  1. wsl1切换wsl2版本时,若提示“请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化。”,请管理员运行下面命令并重启。bcdedit /set hypervisorlaunchtype auto
  2. wsl2下安装docker后,如下图,有docker-destop和docker-desktop-data两个发行版,各自存储程序和数据,它们默认都在c盘。

image.png

  1. docker-desktop-data数据量可能很大,下面是迁移到其他地方的方法:
    1. # 1、打包到其他磁盘
    2. wsl --export docker-desktop-data E:\wsl\docker-desktop-data\docker-desktop-data.tar
    3. # 2、注销这个docker-desktop-data
    4. wsl --unregister docker-desktop-data
    5. # 3、载入刚才的打包到指定的目录
    6. wsl --import docker-desktop-data D:\wsl\docker-desktop-data\ D:\wsl\docker-desktop-data\docker-desktop-data.tar --version 2

2、安装nvidia-docker(需要GPU支持)

官方github 官方指南

3、“Vscode + docker+pytorch”来远程访问notebook

关于docker的镜像

这里看看命令就行,下面vscode+docker才是重点

注:我使用win和wsl组合,即便你使用Linux, 对于下面的docker命令等都是相同的。

  1. 在命令行中获取最新镜像:docker pull pytorch/pytorch,就像下面这样:

    https://registry.hub.docker.com/r/pytorch/pytorch 在这里可以看看哪些发行版

image.png
也可通过网易仓库来获取镜像: docker pull hub-mirror.c.163.com/pytorch/pytorch
注意拉取的镜像版本是否兼容宿主机的显卡驱动。

  1. 下面来查看本地是否有这个pytorch镜像 docker images。 答:有的:

image.png

  1. 创建并进入容器 ```bash

    nvidia-docker支持

    docker run —rm -it -p 8022:22 —ipc host —name pytorch —gpus all -v ~/data:/data pytorch:latest

cpu

docker run —rm -it -p 8022:22 —ipc host —name pytorch -v ~/data:/data pytorch:latest

  1. - docker run [选项] pytorch/pytorch:latest 创建指定镜像的容器
  2. - --rm 容器退出即删除
  3. - -it 交互终端
  4. - -p 8022:22 宿主端口映射容器端口
  5. - --ipc=host 进程间通信方式
  6. - -v ~/data:/data 挂载数据卷
  7. - --name pytorch 容器自命名
  8. - --gpus all 宿主的gpu全部可见
  9. 4. 该镜像是带了condapip的,如下图:
  10. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624611203314-8a3b1948-884c-4116-9ec3-8a6a6dca6890.png#clientId=uc6346fe2-87ef-4&from=paste&height=280&id=u089cc56d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=329&originWidth=638&originalType=binary&ratio=2&size=32597&status=done&style=none&taskId=ua5213421-3761-4d7f-8130-95bc2776c41&width=543)
  11. 5. 但是该镜像没有Jupyter, 可以在容器的内部命令行中使用`conda install jupyter`命令来安装它。
  12. 6. 容器是有生命周期的,容器“死了”,刚才“花费心思”安装的jupyter也就没了。但可以给当前容器生成镜像快照,用这个镜像创建容器就好了。[参考本文后面的容器快照部分。](#EW1cH)
  13. 如下图,我创建了一个pytorch:v1的镜像,它包含了刚才安装的jupyter。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624614553482-12e7af89-064f-4d7c-a3e8-6ac55eb35ef1.png#clientId=ub4c98458-dd60-4&from=paste&height=98&id=u4da8522f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=102&originWidth=612&originalType=binary&ratio=2&size=12625&status=done&style=none&taskId=uf6c1605a-2f74-4095-9d4e-08407519617&width=587)
  14. 7. pytorch:v1镜像再次创建容器
  15. ```bash
  16. # nvidia-docker支持
  17. docker run -it -p 8022:22 --ipc host --name pytorch --gpus all -v ~/data:/data pytorch:latest
  18. # cpu
  19. docker run -it -p 8022:22 --ipc host --name pytorch -v ~/data:/data pytorch:latest

如下图,这个镜像的确包含了jupyter包了。
image.png

  1. 下面来看看如何远程访问容器中的notebook。 本文下面讲了如何远程Notebook,但是还是用vscode来做这件事吧, 因为上诉操作相比vscode来说太复杂了,见下。

vscode + docker = “简单”

先讲一下原理:前提是宿主系统环境中有docker并且启动了docker服务,那么vscode可以利用Docker插件后来管理docker的镜像和容器等等,而且简单配置之后可以进行远程宿主的docker管理,甚至vscode的Remote-Containers插件能够远程连接上述的容器。对于上面提到的镜像,vscode可以帮你创建容器,但是建议手动创建容器,毕竟一些启动参数还是需要自定义的,比如下面会提到-v参数。

  1. vscode装上Docker插件、Remote-Containers插件,以及其他必要的插件。
    1. 如果是远程服务器,那么需要先配置docker:host选项: ```bash

      第一步:在远程宿主机中先设置docker的远程配置。记住这里的端口号

      vi /lib/systemd/system/docker.service

      修改ExecStart这行

      ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock

第二步:在本地机的vscode中的Docker:host选项。

“docker.host”: “http://远程宿主机ip:远程宿主机的docker中配置的远程端口

  1. 2. 如果上述远程配置无误的话,在本地机的docker功能栏中,远程宿主机的pytorch:v1镜像就会出现在面前,而且右键点击run interactive即可能创建交互终端的容器:
  2. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624619669985-e31e264a-80b9-4a35-b40e-afe8f6d8ad6f.png#clientId=u01b01132-f7ef-4&from=paste&height=526&id=u95d1147d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=517&originWidth=422&originalType=binary&ratio=2&size=28992&status=done&style=none&taskId=ue3f01a32-5718-4897-a74b-5e319260250&width=429)<br /> c. 现在已经创建了容器,在上方找到pytorch:v1容器,右键attach visual studio code即可,:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624619819456-c0bc1d47-d95b-4dc9-8f23-b13d0bd25164.png#clientId=u01b01132-f7ef-4&from=paste&height=349&id=u4647aeea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=436&originWidth=664&originalType=binary&ratio=2&size=32902&status=done&style=none&taskId=u141878bf-cd4c-4a83-88d8-bbbc8f4331f&width=531)
  3. 现在, 已经进入容器内部了。点击插件中心,见下图,我们还需要为容器的内部环境也装上必须要的vscode插件,比如anaconda extension packjupyter等等。
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624619967620-ee868fd0-3922-4b1d-bf0f-a9a9b32d72df.png#clientId=u01b01132-f7ef-4&from=paste&height=544&id=u55186a5f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=778&originWidth=1029&originalType=binary&ratio=2&size=156475&status=done&style=none&taskId=ue5d8020e-fe14-4ef3-9151-fef9d1646a5&width=719.5)
  5. 最后,上述虽然也创建了容器,但是并不建议这么做,因为vscode自动创建容器的命令是 `docker run --rm -it -p 8888:8888/tcp pytorch:v1` 这条命令实在太简陋了,通常还需要使用`-v`等参数来为容器载入一些宿主机的目录或文件。所以还是要手动创建容器,创建好了才在vscode中打开这个容器。
  6. 第一步:手动创建容器,这里使用了-v参数:<br />`docker run -it --rm -p 8888:8888/tcp -v /mnt/e/project:/root/ pytorch:v2`<br />然后vscode就能检测到你创建的容器了,点击进入它。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624673172600-ddb3dc5b-2a5f-417a-9a81-71083b39b14c.png#clientId=u85cebbb2-f122-4&from=paste&height=262&id=u4f646224&margin=%5Bobject%20Object%5D&name=image.png&originHeight=193&originWidth=512&originalType=binary&ratio=2&size=12835&status=done&style=none&taskId=ued0acd2c-8cb0-4a17-9879-6e50f0033d8&width=694)<br />下面就是最终的效果。可以看见,**pytorch环境、notebook、宿主目录的载入**都是可以的。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624674904786-4428b12d-7232-4a85-9b78-78437e7959c0.png#clientId=u89ee1738-1dde-4&from=paste&height=398&id=ufb54c147&margin=%5Bobject%20Object%5D&name=image.png&originHeight=533&originWidth=906&originalType=binary&ratio=2&size=54611&status=done&style=none&taskId=u09f443ea-3923-4ecb-a6ee-6372a61f6c9&width=677)<br />最后,有必要对目前的容器再做一次快照,毕竟又安装了不少东西嘛。
  7. <a name="wjQGe"></a>
  8. ### 小结
  9. 1. 拉取官方镜像
  10. 1. 强推vscode+docker
  11. 1. 安装docker插件和remote-Containers插件。
  12. 1. 配置远程宿主机地址 `Docker:host`
  13. 1. 手动创建容器并使用vscode连接它
  14. 3. 进入容器内部后,把容器配置好,安装必要的插件和包
  15. 3. 将容器做快照备份下来,免得下次又搞配置或安装等,甚至打包备份下来。
  16. <a name="EW1cH"></a>
  17. # 容器的快照、打包分享、再次创建容器
  18. 1. 在宿主机的命令行看看 容器的id是什么 `docker ps -a`
  19. 1. 生成容器快照(即镜像) `docker commit -p 容器id 镜像名` 参数-pcommit时暂停容器。
  20. 1. 接着查看镜像是否备份成功了 `docker images`
  21. 1. 然后把镜像打包为tar文件以便分享 `docker save -o 备份文件名.tar 镜像名`
  22. 上面的4步如下:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/956564/1624614348739-da7d63a5-c3f0-4d27-8b34-7cff5f09d3df.png#clientId=u21de8362-7f15-4&from=paste&height=140&id=u0070cc5c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=254&originWidth=1344&originalType=binary&ratio=2&size=44540&status=done&style=none&taskId=ud4cdf8e7-057c-44ee-8d8e-32cdfb6e5d1&width=741)
  23. 5. 载入你打包的镜像文件`docker load -i 镜像名.tar ` 并创建容器 `docker run -d -p 80:80 镜像`
  24. <a name="LkYPa"></a>
  25. # 通过容器实操远程notebook(不建议该方法,仅参考)
  26. <a name="XzG31"></a>
  27. ### 1 创建容器
  28. 服务器中执行下面命令:
  29. ```bash
  30. sudo docker run -it -p 7777:8888 --ipc=host -v /home/xujia/data:/data --name pytorch 5ffed6c83695
  • -it 交互终端
  • -p 7777:8888 宿主端口映射容器端口
  • —ipc=host 进程间通信方式
  • -v /home/data:/data 挂载数据卷
  • —name pytorch 容器自命名
  • 5ffed6c83695 镜像的id

2 使用notebook

服务器中执行下面命令:

  1. jupyter notebook --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token= --notebook-dir='/data'

jupyter notebook 启动notebook命令
--no-browser 参数:不需要浏览器自动进入notebook
--ip=0.0.0.0 参数:notebook要监听的ip,这里采用本地ip,即容器的Ip。
--allow-root 参数:运行root用户运行
--NotebookApp.token= 参数:指定notebook登录密码,可为空。
--notebook-dir='/data' 参数:指定notebook的启动根目录。

3 远程登录notebook

在本地电脑上执行下面的命令:ssh username@host-ip -L 1234:127.0.0.1:7777
将本地电脑的1234端口(1234:127.0.0.1)映射到服务器的7777端口(username@host-ip:7777),即映射到jupyter的监听地址。

浏览器登录:localhost:1234即可以打开远程的notebook了

常用命令

  • 查询命令参数

格式:docker 命令 —help ,比如 docker run --help

  • 容器创建、查看、删除

docker run [-it] 镜像名 -it参数:交互界面, -rm参数:运行结束自动删除容器
docker ps 列出运行容器
docker ps -a 列出所有容器
docker rm 容器名 删除容器

  • 容器启动、进入、退出

docker start [-i] 容器名 -i参数:交互模式
exit 退出交互模式
docker stop 容器名 停止容器
docker restart 容器名 重启容器