Docker环境部署深度学习平台

基本知识与概念

Docker入门教程Docker入门教程

Docker —— 从入门到实践

Docker环境配置

Docker安装 Ref: Install Docker Engine on Ubuntu

首先安装docker-ce。由于GPU虚拟化的需要,安装的Docker版本应>19.03

$ sudo apt-get update
$ 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 apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

卸载Docker Engine,CLI和Containerd软件包(之前没有安装docker可以略过)

$ sudo apt-get purge docker-ce docker-ce-cli containerd.io

删除数据(之前没有安装docker可以略过)

主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷。
您必须手动删除所有已编辑的配置文件。

$ sudo rm -rf /var/lib/docker

注意检查版本>19.03,否则卸载老版本重新安装(之前没有安装docker可以略过)

$ sudo apt-get remove docker docker-engine docker.io containerd runc

配置权限 Ref: 为当前用户添加docker运行权限,免sudo

# 添加docker group:
$ sudo groupadd docker
# 将当前用户添加到docker组:
$ sudo gpasswd -a ${USER} docker
# 重启docker服务
$ sudo service docker restart
# 更新用户群组
$ newgrp docker

配置Nvidia toolkit

首先执行nvidia-smi检查Nvidia驱动版本

Docker环境部署深度学习平台_第1张图片

下面安装用于Docker GPU虚拟化的套件:

Ref: nvidia-docker

Ref: docker使用GPU

For Ubuntu 16.04/18.04/20.04, Debian Jessie/Stretch/Buster:

# Add the package repositories
$ 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-container-toolkit
$ sudo systemctl restart docker

测试是否成功:

$ docker run --gpus all nvidia/cuda:10.0-base nvidia-smi

指定容器所使用GPU的方法

# 使用所有GPU
$ docker run --gpus all 【镜像名】
# 使用两个GPU
$ docker run --gpus 2 【镜像名】
# 指定GPU运行
$ docker run --gpus '"device=1,2"' 【镜像名】

注意,GPU编号从0开始

测试容器是否能启动成功,Pull下来的image需要run后变为container:

$ docker run --gpus all --name=data -it nvidia/cuda:10.1-cudnn7-devel

要知道您正在运行的Ubuntu版本,请执行

$ cat /etc/lsb-release

在宿主机中用 df -h 查看容器空间大小,然后找到需要新增的device name(不用停容器)

Docker目录挂载和容器内到容器外的端口映射

Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定。

例如,我要从dockerhub Pull下来1.5.1-cuda10.1-cudnn7-devel的image需要run后变为container,即启动一个datavol容器,宿主机的/home/g903/fdisk4目录挂载到容器的/root/data目录,可通过以下方式指定:

$ docker pull pytorch/pytorch:1.5.1-cuda10.1-cudnn7-devel
$ docker run --gpus all --shm-size 14g -it -d -p 23:22 -p 8888:8888 -v /home/g903/disk4:/root/data --name datavol pytorch/pytorch:1.5.1-cuda10.1-cudnn7-devel  /bin/bash
$ docker container start datavol && docker container exec -it datavol /bin/bash

这样,在容器启动后,容器内会自动创建/root/data的目录。
同时,容器中的SSH服务22端口映射到容器外的23端口,jupyter的8888端口映射到容器外的8888端口,方便本地Pycharm和VSCode利用远程服务器中容器内的SSH服务(容器内需要安装SSH服务,下文有安装教程),远程连接到服务器中的容器环境进行操作。
--shm-size 14g 是docker共享内存14G大小,不指定的话默认大小可能会不够用。

常用命令

  1. 重命名容器名

    $ docker rename 【容器ID】 xxx
    
  2. 启动并进入现有容器

    $ docker container start 【容器名or容器ID】&& docker container exec -it【容器名or容器ID】/bin/bash
    
  3. 退出容器:ctrl+D

  4. 关闭容器:

    $ docker container stop【容器名or容器ID】
    
  5. 宿主机和容器间文件互拷

    # 宿主机->容器: 
    $ docker cp /xx/xxx/x 【容器名or容器ID】:/xxx/xxx/
    # 容器->宿主机:
    $ docker cp【容器名or容器ID】:/xxx/xxx/  /xx/xxx/x
    
  6. 查看容器列表:

    $ docker container ls
    $ docker container ls --all 
    
  7. 查看镜像列表:

    $ docker image ls
    
  8. 删除容器

    $ docker container rm 【容器名or容器ID】
    
  9. 将容器保存为镜像

    $ docker commit [OPTIONS]  CONTAINER(容器名或容器ID)  [REPOSITORY[:TAG]](镜像名或镜像ID)
    
  10. 镜像导出为文件(用于迁移、备份)

    $ docker save 镜像名称 > xxx.tar
    
  11. 文件导出镜像

    $ docker load < /tmp/test.tar
    

安装SSH服务指令

# 安装SSH服务:
$ sudo apt update && sudo apt install openssh-server
# 修改SSH配置文件
$ vim /etc/ssh/sshd_config  # #号去掉是取消注释
# PermitRootLogin prohibit-password # 默认打开 禁止root用户使用密码登陆,需要将其注释
PubkeyAuthentication yes #启用公钥私钥配对认证方式
PermitRootLogin yes #允许root用户使用ssh登录

# 开启SSH服务:
$ sudo service ssh start
# 查看SSH服务是否开启:
$ ps -e | grep ssh

本地访问服务器(docker容器)上的tensorboard可视化结果

很多时候我们使用的训练资源是学校或公司的服务器,这些服务器往往没有给使用者提供图形界面,我们通过ssh访问,此时要想使用tensorboard来可视化我们的训练过程就比较麻烦了。

tensorboard默认使用是通过一个端口来访问可视化结果,所以可以通过端口映射来解决这个问题。

1、服务器到本地的端口映射(推荐,本地客户端打开cmd命令窗口输入以下指令)

ssh -L 6006:127.0.0.1:6666 username@serverIP

使用ssh连接到服务器,并做端口转发,其中本地IP是省略了的,6006是本地端口;127.0.0.1:6666指的是服务器的本地端口6666
上述操作将服务器的6666端口映射到本地机器的6006端口

如果是直接在服务器上使用tensorboard的话,可以将6666改为6006(tensorboard默认端口为6006),这样就可以通过本地6006端口访问可视化结果了。

然而,很多企业为了保证服务器环境干净,一般会使用docker,这样一来仅仅是上述端口转发便不够用了。

2、容器到服务器的端口映射

sudo nvidia-docker run -p 6666:6006 --name test  -it 镜像id

在服务器上启动容器,使用-p指令进行端口映射,将容器的6006端口映射到服务器的6666端口。

以上便实现了 容器:6006——>服务器:6666——>本地:6006 的端口映射
此时,在容器内使用tensorboard(其默认端口一般为6006),便可以在本地通过本地6006端口访问tensorboard的可视化结果。
注意,在使用上述方法是,端口号可自己设定,但是要确保使用的端口没有被其他程序占用,最好使用一些不常用的端口。

Docker中配置jupyter,本机可以远程访问

# 启动容器时绑定主机和docker的接口,jupyter服务的默认端口是8888
NV_GPU=0 nvidia-docker run -tid -v /home/code_directory jupyter:/home/code_directory -p 8877:8888 --name jupyter_serverce centos:7.5 /bin/bash
# 登录容器
docker exec -it jupyter_serverce /bin/bash --login
# 安装 jupyter
pip install jupyter notebook
# 配置jupyter notebook
jupyter notebook --generate-config
# 修改配置文件,新版本没有这个,可以不用写
vim ~/.jupyter/jupyter_notebook_config.py
# 第83行,允许远程访问
c.NotebookApp.allow_remote_access = True
# 第85行,允许root启动
c.NotebookApp.allow_root = True
# 第205行,监听任意的访问IP地址
c.NotebookApp.ip = '*'
# 第263行,加载默认的notebook文件夹,即容器启动时挂载的主机代码目录
c.NotebookApp.notebook_dir = '/home/code_directory'
# 第354行,设置默认token
c.NotebookApp.token = '1357'
#浏览器默认不启动
c.NotebookApp.open_browser = False
c.NotebookApp.port =8888 #可自行指定一个端口, 访问时使用该端口
===============================================================================================
# 启动notebook
# 容器内启动
jupyter notebook &
# 主机内启动
docker exec jupyter_serverce jupyter notebook &
# Windows浏览器打开容器中的代码目录
# http://[主机IP]:[绑定容器的端口]/tree?token=[配置文件中所设置的c.NotebookApp.token值]
http://10.37.2.190:8877/tree?token=1357

换apt源

编辑ubuntu中/etc/apt/sources.list

$ sudo vim /etc/apt/source.list

Linux查看当前目录 选择地址条快捷键:ctrl+L
选择ubutun对应的系统版本(例如ubutun 18.04 LTS),拷贝对应内容覆盖sources.list文件:

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

再运行以下指令更新apt源

$ sudo apt-get update
$ sudo apt-get upgrade

Ubuntu 20.04系统自动挂载NTFS的硬盘

入门阶段,发现原来的视频教程在Ubuntu 20.04系统里都有些变化。可喜的是变得简单了,比如新系统下,可以自动挂载ntfs格式的U盘。系统已经安装了ntfs-3g软件,于是挂载ntfs的硬盘也很方便了,在此分享给大家。

第一步:查看硬盘信息:

ls -l /dev/sd*  #查看硬盘,我的硬盘有四个分区
sudo blkid       #硬盘的UUID,不过这个用不到

第二步:修改/etc/fstab

sudo vim /etc/fstab

在该文件最后,我添加了:

#disk1 was on /dev/sda2 during installation
/dev/sda2 /home/xjgao/disk1  ntfs-3g  rw  0  0
#disk2 was on /dev/sda3 during installation
/dev/sda3 /home/xjgao/disk2  ntfs-3g  rw  0  0
#disk3 was on /dev/sda4 during installation
/dev/sda4 /home/xjgao/disk3  ntfs-3g  rw  0  0

保存该文件。

第三步:执行 sudo mount -a

设置开机自动挂载NTFS分区

  1. 查看分区:sudo fdisk --list
  2. 打开/etc/fstab:sudo gedit /etc/fstab,以我自己的情况为例,添加以下内容并保存:
    /dev/sda1 /media/D ntfs-3g user,auto,rw,dev,exec,suid,async,utf8,dmask=000,fmask=111 0 0

该命令共有6个参数,以空格分割,其中:

  1. /dev/sda1表示你要挂载的分区,根据你查看分区的结果填写。

  2. /media/D表示挂载点,根据你自身需求填写。

  3. ntfs-3g 表示待挂载分区使用的文件系统。分为以下几种情况

    • NTFS:填写ntfs-3gntfs(在Ubuntu 20.04中ntfs是链接到ntfs-3g的)。
    • FAT32或FAT16或FAT:填写vfat.
    • 自动检测文件系统:填写auto.
  4. usr ... fmask=111 为一个参数,各项之间用 ,分割,用于设置挂载分区的特性:

    • autonoauto: 这是控制设备是否自动挂载的选项。auto是默认选择的选项,这样,设备会在启动或者你使用mount -a命令时按照fstab的内容自动挂载。如果你不希望这样,就使用noauto选项,如果这样的话,你就只能明确地通过手工来挂载设备。

    • usernouser:这是一个非常有用的选项,user选项允许普通用户也能挂载设备,而nouser则只允许root用户挂载。nouser是默认选项,这也是让很多 Linux新手头疼的东西,因为他们发现没有办法正常挂载光驱,Windows分区等。如果你作为普通身份用户遇到类似问题,或者别的其他问题,就请把 user属性增加到fstab中。

    • execnoexec: exec允许你执行对应分区中的可执行二进制程序,同理,noexec的作用刚好相反。如果你拥有一个分区,分区上有一些可执行程序,而恰好你又不愿意,或者不能在你的系统中执行他们,就可以使用noexec属性。这种情况多发生于挂载Windows分区时。exec是默认选项,理由很简单,如果 noexec变成了你/根分区的默认选项的话……

    • rwro:让该分区以可擦写或者是只读的型态挂载上来,如果你想要分享的数据是不给用户随意变更的, 这里也能够配置为只读。则不论在此文件系统的文件是否配置 w 权限,都无法写入!

    • syncasync:对于该文件系统的输入输出应该以什么方式完成。sync的意思就是同步完成,通俗点讲,就是当你拷贝一个东西到设备或者分区中时,所有的写入变化将在你输入cp命令后立即生效,这个东西应该立马就开始往设备或者分区里面拷贝了。而如果是async,也就是输入输出异步完成的话,当你拷贝一个东西到设备或者分区中时,可能在你敲击cp命令后很久,实际的写入操作才会执行,换句话说,就是进行了缓冲处理。有时候这种机制蛮不错的,因为sync会影响你系统的运行速度,但是这也会带来一些问题。想一想,当你希望将一个文件拷贝到u盘上时,你执行了cp 命令,却忘记执行umount命令(它会强行将缓冲区内容写入),那么你拷贝的文件实际上并没有在u盘上面。如果你是使用的mv命令,而你又很快将u盘拔出……恭喜你,文件会从这个星球上消失的。因此,虽然async是默认属性,但是对于u盘,移动硬盘这种可移动存储设备,最好还是让他们使用sync选项。

    • suidnosuid:该文件系统是否允许 SUID 的存在?如果不是运行文件放置目录,也可以配置为 nosuid 来取消这个功能!

    • defaults:同时具有 rw, suid, dev, exec, auto, nouser, async 等参数。 基本上,默认情况使用 defaults 配置即可

      以上其实是 mount 命令的参数,在 Ubuntu 20.04 中配合ntfs-3g命令的参数,还有下述选项:

    • umask:这个是用来指定挂载windows分区后文件的默认权限(事实上,是默认没有的权限,即umask参数指出的值挂载后的文件将不具有),因为Windows分区里面的文件是没有权限这个概念的,所以要手动指定默认权限,于是,指定umask为000,就是不排除任何,即具有所有权限。

    • fmask:针对文件进行设置,意义和用法同umask.

    • dmask:针对文件夹进行设置,意义和用法同umask.

  5. 0指示能否被 dump 备份命令作用。dump 是一个用来做为备份的命令, 我们可以透过 fstab 指定哪个文件系统必须要进行 dump 备份! 0 代表不要做 dump 备份, 1 代表要每天进行 dump 的动作。 2 也代表其他不定日期的 dump 备份动作, 通常这个数值不是 0 就是 1.

  6. 0指示是否以 fsck 检验扇区。启动的过程中,系统默认会以 fsck 检验我们的 filesystem 是否完整 (clean)。 不过,某些 filesystem 是不需要检验的,例如内存置换空间 (swap) ,或者是特殊文件系统例如 /proc 与 /sys 等等。所以,在这个字段中,我们可以配置是否要以 fsck 检验该 filesystem 喔。 0 是不要检验, 1 表示最早检验(一般只有根目录会配置为 1), 2 也是要检验,不过 1 会比较早被检验啦! 一般来说,根目录配置为 1 ,其他的要检验的 filesystem 都配置为 2 就好了。

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