【一站式教程】Ubuntu利用Docker进行深度学习

Ubuntu利用Docker进行深度学习,看这一篇就够啦!
网上有很多ubuntu利用docker配置深度学习环境的教程,但都不是很全,有的只有安装过程,有的只有某一些常用命令,我这里汇总一下。

本文目录

  • Docker的安装与后续配置
    • 安装Docker
    • 去除sudo限制
    • Docker镜像加速
    • 更换Docker镜像与容器存储位置
  • Docker常用命令
    • 查看docker信息
    • 镜像操作
      • 搜索镜像
      • 拉取镜像
      • 查看镜像
      • 删除镜像
    • 容器操作
      • 创建docker容器
        • 常规创建容器
        • 使容器利用GPU
        • 与容器共享目录
      • 宿主机与容器间复制文件
      • 进入与退出容器
      • 查看容器
      • 开启与关闭容器
      • 重命名容器
      • 删除容器
    • 打包与分享镜像
      • 将容器打包为镜像
      • 将Docker镜像推送到Docker Hub
      • 导出与导入镜像
        • 导出镜像
        • 导入镜像


Docker的安装与后续配置

安装Docker

  1. 更新apt包列表
    sudo apt update
    
  2. 利用apt安装前置软件包
    sudo apt install apt-transport-https ca-certificates curl software-properties-common
    
  3. 添加官方Docker存储库的GPG密钥
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
  4. 将Docker存储库添加到APT源
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
    
  5. 使用新添加的repo源中的Docker包更新包数据库
    sudo apt update
    
  6. 安装Docker
    sudo apt install docker-ce
    

好了,现在Docker已经安装完毕了,我们可以输出docker信息检查一下:

sudo docker info

如果此时输出了docker信息,则docker已经安装完毕了!


去除sudo限制

目前我们运行docker的时候,每句之前还都需要加上sudo,比较麻烦。我们可以利用添加用户到docker用户组的方式,让每次输入命令的时候不再需要在docker之前添加sudo。

  1. 请将当前用户添加到docker组中:
    sudo usermod -aG docker ${USER}
    
  2. 注销或重新登录用户,来激活我们刚刚的改动
  3. 重新登录后,再输出docker信息进行测试:
    docker info
    
    如果此时输出docker信息,说明已经成功加入docker组,以后docker命令前都不需要添加sudo了。

Docker镜像加速

一个Docker镜像小则百M大则数十G,国内从 DockerHub 拉取镜像速度很慢,建议配置镜像加速器。例如:科大镜像,阿里云等等。

  1. 以阿里云为例,首先需要一个阿里云账号,阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆账号后,左侧菜单选中镜像加速器就可以看到你的专属地址了,形式如下:

    https://XXX.mirror.aliyuncs.com/
    

    当然也可以使用科大镜像(并不是专属的,直接复制就行):

    https://docker.mirrors.ustc.edu.cn/
    
  2. 将你的镜像地址写入 /etc/docker/daemon.json 中(如果文件不存在则新建该文件):

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["此处填入你的镜像地址"]
    }
    EOF
    
  3. 重新启动服务:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

此时我们就配好了docker镜像加速,可以更快的从DockerHub中拉取镜像。


更换Docker镜像与容器存储位置

使用如下命令查看Docker镜像与容器的默认存储位置:

docker info | grep "Docker Root Dir"

可以看到输出结果是/var/lib/docker

我们可以利用df -h命令查看各个目录下的空间情况,一般/下目录的空间不足以支撑深度学习镜像动辄10G+的空间占用,所以我们需要更改Docker默认存储位置到空间充足的目录,如/home下的目录。

  1. 关闭docker服务(如有正在运行的容器请使用docker stop 容器名称,关闭容器)

    sudo systemctl stop docker.service
    
  2. 在你想存储的位置创建新的目录,并移动原来的镜像和容器到新的目录

    mkdir /home/user/docker_data #此处替换为新的目录
    cd /home/user/docker_data
    sudo cp -r /var/lib/docker .	
    
  3. 修改docker的配置文件,指定新存储位置

    sudo vim /etc/docker/daemon.json
    

    我们之前已经在这里添加了镜像加速,现在再在这里指定新的存储位置,修改为

    {
      "data-root": "此处填入新的存储位置",
      "registry-mirrors": ["此处填入你的镜像地址"]
    }
    
  4. 重新启动服务:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

此时我们再查看Docker镜像与容器的默认存储位置:

docker info | grep "Docker Root Dir"

可以看到输出结果是我们自己指定的新位置。


至此我们已经安装好了docker,下面就可以正式操作docker了。

docker中和我们打交道的主要是 镜像容器 两个概念,这里借用大佬的解释:
镜像:概念类似虚拟机的镜像。是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。
容器:由docker镜像创建的运行实例。容器中会运行特定的运用,包含特定应用的代码及所需的依赖文件。可以把容器看作一个简易版的linux环境和运行在其中的应用程序。

以本人粗浅的理解,镜像就像是代码,是静态的,可以到处复制。容器就像是代码运行起来之后得到的程序,是动态的,就像我们可以和程序交互,我们也可以和容器交互。

如果要利用docker进行深度学习,一般来说,分以下几步:

  1. 先拉取一个他人配置好的镜像作为基础环境
  2. 将这个镜像创建为实例,将深度学习代码放入实例中,在实例中针对你的项目进一步的配置
  3. 在实例中跑深度学习代码并得到结果
  4. 将实例打包为镜像,以备之后再次使用或迁移至其他物理机使用

此后的章节会根据以上步骤进行具体命令上的介绍。


Docker常用命令

docker命令使用包括传递一系列docker选项和命令,后跟参数。语法采用以下形式:

docker [option] [command] [arguments]

查看docker信息

docker info

镜像操作

搜索镜像

我们可以使用docker带子命令的search命令搜索Docker Hub上可用的镜像,以搜索pytorch1.9相关镜像为例:

docker search pytorch1.9

当然也可以直接在Docker Hub的网页端搜索。


拉取镜像

我们可以使用pull命令拉取Docker Hub上可用的镜像,如:

docker pull lsg1213/pytorch1.9

镜像通常较大,可能需要拉取较长时间。


查看镜像

利用images命令查看目前docker中存在的镜像

docker images

删除镜像

利用rmi命令删除docker中的镜像

docker rmi image_name:tag_name

我们现在已经可以获取深度学习基础环境的镜像了,但是镜像是静态的,我们需要将其创建为容器,并在容器中对其进行进一步的配置,或者在其中运行网络获得结果。


容器操作

创建docker容器

常规创建容器

镜像只是一个可读的配置文件,真正用来运行程序的是容器。对于我们本地的docker镜像,我们可以使用run命令,将其创建为容器:

docker run -it --name 'Goodjob' lsg1213/pytorch1.9:v1 /bin/bash

参数说明:
-i:交互式操作
-t:终端
-name:指定容器名称
'Goodjob':容器的名字
lsg1213/pytorch1.9:v1:镜像名称:镜像标签(当镜像名称后面没有标签时,可以只写名称不写标签,此时docker会默认标签为latest
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash

使容器利用GPU

在利用docker进行深度学习时,是要利用GPU资源的,然而常规的创建过程并不能使docker利用宿主机的GPU资源。目前版本的docker提供了gpus参数供我们使用。

使得docker虚拟机可以访问宿主机全部的GPU资源时,我们使用--gpus all

docker run -it --name 'Goodjob' --gpus all lsg1213/pytorch1.9:v1 /bin/bash

使得docker虚拟机可以访问宿主机指定的GPU资源时,如第1,2块卡,我们使用--gpus '"device=1,2"'

docker run -it  --name 'Goodjob' --gpus '"device=1,2"' lsg1213/pytorch1.9:v1 /bin/bash

注意:这里是单引号包双引号包device=x,漏掉其中任何一对引号都会报错。

与容器共享目录

我们可以让宿主机和容器共享代码目录,这样有两个好处:

  • 在宿主机上修改代码,容器内的代码就可以同步改动。
  • 容器内产生的运行结果,我们也可以在宿主机上同步看到。

利用v参数共享目录:

docker run -it  --name 'Goodjob' --gpus '"device=1,2"' -v out_path:container_inner_path lsg1213/pytorch1.9:v1 /bin/bash

参数说明:
-v:共享目录
out_path:宿主机路径
container_inner_path:容器路径

注意:这里宿主机路径和容器路径都要采用绝对路径


宿主机与容器间复制文件

当我们需要复制宿主机文件到容器时,可以利用cp命令:

docker cp /home/out_path/a.py d9b132f2f636:/home/container_inner_path

参数说明:
cp:复制命令
/home/out_path/a.py:宿主机文件路径
d9b132f2f636:容器id
/home/container_inner_path:容器路径

当然,cp命令也可以复制容器的文件到宿主机,将两个参数反过来就可以了:

docker cp d9b132f2f636:/home/container_inner_path/a.py /home/out_path 

进入与退出容器

当使用run命令,将容器创建起来后,我们会自动进入容器内部:

root@d9b132f2f636:/#

我们可以利用exit命令退出容器,进入宿主机:

exit

在其他时候,我们使用attach命令进入正在运行的容器

docker attach 容器名或容器ID

查看容器

我们可以使用ps命令查看运行的容器,使用ps -a命令查看所有已经创建的容器:

docker ps -a

输出所有容器状态:

CONTAINER ID   IMAGE                COMMAND       CREATED              STATUS              PORTS     NAMES
d9b132f2f636   lsg1213/pytorch1.9   "/bin/bash"   About a minute ago   Up About a minute             Goodjob

开启与关闭容器

当一个容器已经被创建,我们可以使用startstop命令开启和停止容器。

开启容器运行:

docker start d9b132f2f636

停止容器运行:

docker stop d9b132f2f636

重命名容器

docker rename 原容器名称 新容器名称

删除容器

docker rm 容器名称

现在我们已经可以在容器中运行深度学习代码并得到我们想要的结果了。但是这还没有结束,因为此后我们还可能有使用此容器的需求,或者我们可以将其分享给其他小伙伴,帮助他们更快的体验深度学习环境,这时就需要打包和分享镜像。


打包与分享镜像

当我们在容器中配置好了深度学习环境,我们可能需要将其打包为镜像,在其他机器上运行,或者让其他人运行,此时就需要打包与分享镜像。

将容器打包为镜像

当我们想得到容器的镜像,以便在其删除后仍可以复现,或者想将其推送到Docker Hub时,我们使用commit命令将容器打包(提交)为镜像。

docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name

参数说明:
commit:提交命令
-m:提交的注释
-a:作者的名字
container_id:容器的id
repository/new_image_name:作者自定义的库名(一般和用户名一致)/镜像名


将Docker镜像推送到Docker Hub

我们可以将自己的镜像推送到Docker Hub,供所有人下载使用。

  1. 注册Docker Hub,在Docker Hub网站https://hub.docker.com/signup可以进行注册。

  2. 登录Docker Hub

    docker login -u docker-registry-username
    
  3. 利用push命令,要将名为image_name的镜像推送到你的存储库(假设你叫superman):

    docker push superman/image_name
    

导出与导入镜像

有时候我们的服务器并不能联网,不能从Docker Hub上pull镜像,我们就需要先从某个宿主机上将镜像导出,再在服务器上将镜像导入。

导出镜像

我们可以使用export命令根据容器 ID 将镜像导出成一个tar文件:

docker export d9b132f2f636 > Goodjob.tar

可以看到文件已经保存到当前的 docker 终端目录下。

导入镜像

我们可以使用import命令将tar文件导入为镜像:

docker import Goodjob_image < Goodjob.tar

Ps:如果有同时打包多个镜像到一个tar的需求,需要使用saveload命令进行镜像的导入和导出,大家可以自行查阅。


至此,我们已经学会了所有有关docker构建深度学习环境的知识,如有问题欢迎各位在评论区指出!

你可能感兴趣的:(docker,ubuntu,深度学习)