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 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容器启动的时候,如果要挂载宿主机的一个目录,可以用-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大小,不指定的话默认大小可能会不够用。
重命名容器名
$ docker rename 【容器ID】 xxx
启动并进入现有容器
$ docker container start 【容器名or容器ID】&& docker container exec -it【容器名or容器ID】/bin/bash
退出容器:ctrl+D
关闭容器:
$ docker container stop【容器名or容器ID】
宿主机和容器间文件互拷
# 宿主机->容器:
$ docker cp /xx/xxx/x 【容器名or容器ID】:/xxx/xxx/
# 容器->宿主机:
$ docker cp【容器名or容器ID】:/xxx/xxx/ /xx/xxx/x
查看容器列表:
$ docker container ls
$ docker container ls --all
查看镜像列表:
$ docker image ls
删除容器
$ docker container rm 【容器名or容器ID】
将容器保存为镜像
$ docker commit [OPTIONS] CONTAINER(容器名或容器ID) [REPOSITORY[:TAG]](镜像名或镜像ID)
镜像导出为文件(用于迁移、备份)
$ docker save 镜像名称 > xxx.tar
文件导出镜像
$ docker load < /tmp/test.tar
# 安装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
很多时候我们使用的训练资源是学校或公司的服务器,这些服务器往往没有给使用者提供图形界面,我们通过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服务的默认端口是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
编辑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格式的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
sudo fdisk --list
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个参数,以空格分割,其中:
/dev/sda1
表示你要挂载的分区,根据你查看分区的结果填写。
/media/D
表示挂载点,根据你自身需求填写。
ntfs-3g
表示待挂载分区使用的文件系统。分为以下几种情况
ntfs-3g
或ntfs
(在Ubuntu 20.04中ntfs是链接到ntfs-3g的)。vfat
.auto
.usr ... fmask=111
为一个参数,各项之间用 ,
分割,用于设置挂载分区的特性:
auto
和 noauto
: 这是控制设备是否自动挂载的选项。auto是默认选择的选项,这样,设备会在启动或者你使用mount -a命令时按照fstab的内容自动挂载。如果你不希望这样,就使用noauto选项,如果这样的话,你就只能明确地通过手工来挂载设备。
user
和 nouser
:这是一个非常有用的选项,user选项允许普通用户也能挂载设备,而nouser则只允许root用户挂载。nouser是默认选项,这也是让很多 Linux新手头疼的东西,因为他们发现没有办法正常挂载光驱,Windows分区等。如果你作为普通身份用户遇到类似问题,或者别的其他问题,就请把 user属性增加到fstab中。
exec
和 noexec
: exec允许你执行对应分区中的可执行二进制程序,同理,noexec的作用刚好相反。如果你拥有一个分区,分区上有一些可执行程序,而恰好你又不愿意,或者不能在你的系统中执行他们,就可以使用noexec属性。这种情况多发生于挂载Windows分区时。exec是默认选项,理由很简单,如果 noexec变成了你/根分区的默认选项的话……
rw
和ro
:让该分区以可擦写或者是只读的型态挂载上来,如果你想要分享的数据是不给用户随意变更的, 这里也能够配置为只读。则不论在此文件系统的文件是否配置 w 权限,都无法写入!
sync
和 async
:对于该文件系统的输入输出应该以什么方式完成。sync的意思就是同步完成,通俗点讲,就是当你拷贝一个东西到设备或者分区中时,所有的写入变化将在你输入cp命令后立即生效,这个东西应该立马就开始往设备或者分区里面拷贝了。而如果是async,也就是输入输出异步完成的话,当你拷贝一个东西到设备或者分区中时,可能在你敲击cp命令后很久,实际的写入操作才会执行,换句话说,就是进行了缓冲处理。有时候这种机制蛮不错的,因为sync会影响你系统的运行速度,但是这也会带来一些问题。想一想,当你希望将一个文件拷贝到u盘上时,你执行了cp 命令,却忘记执行umount命令(它会强行将缓冲区内容写入),那么你拷贝的文件实际上并没有在u盘上面。如果你是使用的mv命令,而你又很快将u盘拔出……恭喜你,文件会从这个星球上消失的。因此,虽然async是默认属性,但是对于u盘,移动硬盘这种可移动存储设备,最好还是让他们使用sync选项。
suid
和nosuid
:该文件系统是否允许 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.
0
指示能否被 dump 备份命令作用。dump 是一个用来做为备份的命令, 我们可以透过 fstab 指定哪个文件系统必须要进行 dump 备份! 0 代表不要做 dump 备份, 1 代表要每天进行 dump 的动作。 2 也代表其他不定日期的 dump 备份动作, 通常这个数值不是 0 就是 1.
0
指示是否以 fsck 检验扇区。启动的过程中,系统默认会以 fsck 检验我们的 filesystem 是否完整 (clean)。 不过,某些 filesystem 是不需要检验的,例如内存置换空间 (swap) ,或者是特殊文件系统例如 /proc 与 /sys 等等。所以,在这个字段中,我们可以配置是否要以 fsck 检验该 filesystem 喔。 0 是不要检验, 1 表示最早检验(一般只有根目录会配置为 1), 2 也是要检验,不过 1 会比较早被检验啦! 一般来说,根目录配置为 1 ,其他的要检验的 filesystem 都配置为 2 就好了。