ubuntu下使用docker进行深度学习环境配置(从入门到精通)

docker入门

更多详细的docker简明配置,请看docker专栏!
[docker简明教程] 1_docker的安装
[docker简明教程] 2_docker从docker hub拉取镜像
[docker简明教程] 3_容器与镜像的基本操作
[docker简明教程] 4_docker 容器启动项设置
[docker简明教程] 5_使用vscode管理docker
[docker简明教程] 6_docker 文件拷贝与挂载
[docker简明教程] 7_docker 代码开发调试工作流程

1.docker安装

准备工作:
首先卸载老版本的docker

sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
    
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

正式安装:

sudo apt-get install docker-ce docker-ce-cli containerd.io -y

帖子:安装指南

2.给当前用户赋权限

安装完,只用使用sudo指令使用docker,非常不方便。这里给当前用户添加使用docker的权限。

sudo docker ps
sudo docker images
sudo gpasswd -a $USER docker 
newgrp docker
docker ps
docker images
sudo systemctl restart docker

如果修改了docker的安装目录,迁移到其他硬盘安装,需要修改docker文件夹的权限.否则开机可能会无法正常读取docker镜像和容器.

帖子:参考链接

3.docker切换国内源

国外源比较慢,切换到国内源:
创建或修改 /etc/docker/daemon.json 文件,修改为如下形式

{
    "registry-mirrors": [
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com"
    ]
}

加载重启docker

service docker restart

查看是否成功

docker info

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第1张图片
参考链接:更换国内源

4.docker创建一个hello_world容器

docker run hello-world

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第2张图片

5.docker创建anaconda容器并进入

拉取anaconda3镜像并创建一个名为lidar的容器(1GB左右)

docker run --name lidar -idt continuumio/anaconda3

等待完成后,查看当前docker安装的镜像:

docker ps -a

在这里插入图片描述

启动容器

docker start 3c52b4761178

在这里插入图片描述
进入容器镜像内部

docker exec -it ef34f4dffb31 /bin/bash

退出容器:

ctrl + D

在这里插入图片描述

6.从本地anaconda虚拟环境克隆到anaconda容器内

一般本地镜像地址为:/home/"$USER"/anaconda3/envs
进入第5步中创建的anaconda镜像,然后输入:

conda info --envs

查看(默认)镜像位置为:/opt/conda
在这里插入图片描述

使用下面的指令克隆镜像:

# 在终端中 env_name输入你自己的镜像名字,docker_name输入将要放入的docker镜像名字,然后直接粘贴运行即可~
env_name=badgr
docker_name=lidar
docker cp /home/"$USER"/anaconda3/envs/"$env_name" "$docker_name":/opt/conda/envs

接着再进入容器 查看环境是否复制成功(然后再退出容器):
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第3张图片
此时发现已经多了一个badgr镜像。拉取成功!
到此为止,该test容器中已经包含我们所需的代码和环境,可以对其进行打包。
参考链接:参考链接

7.把docker容器制作成docker镜像

退出容器后执行:

docker commit -a 'author' -m 'instruction' lidar lidar_img

参数:

  • lidar :容器名字
  • lidar_img:保存的镜像的名字。

等待几分钟,发现镜像制作完成
在这里插入图片描述

查看镜像:

docker images

在这里插入图片描述
第一个镜像就是我们刚刚制作的新镜像。

7.1 docker commit指令详解:

docker   commit -m="描述信息" -a="作者" 容器id 目标镜像名: [TAG]

例如:

docker   commit -m="ros主从通信-ubuntu2004-tensorflow2.9-gpu-cuda11.2" -a="lbw"  caf1023f4a8d lidar_trajectory:v2

因为每一次加载镜像都会把上一次对容器的更改清空,所以当我们对容器做了修改之后,应当即使commit生成新的镜像文件,下一次就可以直接加载新的镜像文件了.
例如,我现在有一个新的容器,通过docker ps -a 可以查看ID是9d037c11b7e6

CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS                      PORTS                                       NAMES
9d037c11b7e6   tensorflow_1:v1.0    "bash -c 'source /et…"   9 minutes ago    Up 9 minutes                0.0.0.0:8888->8888/tcp, :::8888->8888/tcp   sleepy_nash

然后我们对这个容器做了以下程序上的修改,或者安装了一些额外的库.现在我们需要重新commit以下:

docker commit \
 -m="add gpu test" \
 -a="lbw" \
 9d037c11b7e6 \
 tensorflow_1:v2.0
-m是提交信息
-a是提交用户名
然后9d037c11b7e6是当前容器运行的id
最后tensorflow_1是库名,v2.0是版本标签TAG

提交完毕,就可以发现多了一个镜像,下一次我们只需要运行新的镜像就可以了.
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第4张图片

8. 把docker镜像制作成压缩包

 docker save -o lidar_tar.tar lidar_img

参数:

  • lidar_tar.tar: 压缩包名称
  • lidar_img: 镜像名称
    在这里插入图片描述

到此为止,本地的conda环境便打包完成。

9. 读取docker镜像压缩包,并制作容器

在另一台需要运行镜像的电脑上执行:

  • 将打包好的镜像压缩包拷贝到宿主机上。
  • cd 到压缩包目录,执行:
docker load -i lidar_tar.tar

等待数分钟后,然后通过

docker images

查看镜像,然后制作容器:

docker run --name creat_test -idt lidar_img

PS:若创建容器时需要对容器内文件与容器外文件做映射,则需要执行以下指令:

docker run --name creat_test -v /home/b/hxb:/root/hxb -idt image_test

-v /home/b/hxb:/root/hxb:该指令可以在创建容器时将 容器外的/home/b/hxb目录映射到容器内的/root/hxb目录。这样可以在容器内直接访问容器外的/home/b/hxb文件夹。

10. docker文件映射

参考这个文章链接
使用-r指令:

docker run -r /host/path:/docker/path

其中/host/path为宿主机需要挂载到docker容器内的目录
/docker/path为docker容器内的目录
挂载之后,修改容器内的目录也会修改容器外的目录。修改容器外的目录内容也会影响到容器内部的目录。

11.几个常用docker命令汇总

  • 启动容器:
 docker run -dit lidar_img /bin/bash
  • 进入容器镜像内部
docker exec -it ef34f4dffb31 /bin/bash

另一种简单的进入容器的方法:先给容器改名:

 docker rename 9b407075e544 lidar

然后通过docker start -i name指令直接进入容器内:

docker start -i lidar
  • 退出容器:
ctrl + D
  • 停止容器:
docker stop 'CONTAINER ID'
  • 删除容器(由于容器即使停止也会占用存储空间,所以有必要删除没用的容器来释放空间):
    删除前需要停止容器.
docker rm 'CONTAINER ID'
  • 删除镜像(需先删除关联的容器):
docker rmi 'IMAGE ID'

!!!一键停用所有容器并删除所有容器!!!

docker stop $(docker ps -q) & docker rm $(docker ps -aq)
  • 干净卸载docker:
rm -rf /etc/systemd/system/docker.service.d
rm -rf /var/lib/docker
rm -rf /var/run/docker
rm -rf /var/run/docker.pid

参考链接:原文链接

12.修改docker 的默认存储目录

12.1 使用软链接

我们知道在操作系统当中,默认情况下 Docker 容器的存放位置在 /var/lib/docker 目录下面,可以通过下面命令查看具体位置。

  • 默认存放位置
$ sudo docker info | grep "Docker Root Dir"

解决默认存储容量不足的情况,最直接且最有效的方法就是挂载新的分区到该目录。但是在原有系统空间不变的情况下,所以采用软链接的方式,修改镜像和容器的存放路径达到同样的目的。

  • 停掉Docker服务
$ systemctl restart docker
  • 停掉Docker服务
$ service docker stop

然后移动整个 /var/lib/docker 目录到空间不较大的目的路径。这时候启动 Docker 时发现存储目录依旧是 /var/lib/docker 目录,但是实际上是存储在数据盘 /data/docker 上了。

  • 移动原有的内容
$ mv /var/lib/docker /data/docker
  • 进行链接
$ ln -sf /data/docker /var/lib/docker

12.2 指定容器启动参数

如果 Docker 的版本是 1.12 或以上的,可以修改或新建 daemon.json 文件。修改后会立即生效,不需重启 Docker 服务。

  • 修改配置文件
$ vim /etc/docker/daemon.json
{
    "registry-mirrors":
        ["http://7e61f7f9.m.daocloud.io"],
    "graph": "/new-path/docker"
}

12.3. System 下创建配置文件

在 /etc/systemd/system/docker.service.d 目录下创建一个 Drop-In 文件 docker.conf,默认 docker.service.d 文件夹不存在,必须先创建它。创建 Drop-In 文件的原因,是我们希望 Docker服务使用 docker.conf 文件中提到的特定参数,将默认服务所使用的位于 /lib/systemd/system/docker.service 文件中的参数进行覆盖。

  • 定义新的存储位置
$ sudo vi /etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=/usr/bin/dockerd --graph="/data/docker" --storage-driver=devicemapper

保存并退出 vim 编辑器 /data/docker 就是新的存储位置,而 devicemapper 是当前 Docker 所使用的存储驱动。如果你的存储驱动有所不同,请输入之前第一步查看并记下的值。现在,你可以重新加载服务守护程序,并启动 Docker 服务了,这将改变新的镜像和容器的存储位置。为了确认一切顺利,运行 docker info 命令检查 Docker 的根目录。

# 重新reload配置文件

$ sudo systemctl daemon-reload

# 重启docker服务

$ sudo systemctl start docker

添加链接描述

进阶篇:

1.向docker内拷贝文件

这个命令可以把后面参数反过来就可以从docker向宿主考文件.

docker cp file_name docker_name:/dir

参数:

  • file_name:需要复制的文件或者文件夹
  • docker_name:容器的名字
  • dir:复制到容器内的文件地址

2. 从终端一键启动docker

新建一个d_lidar_start.sh文件,写入下面的语句,其中lidar是我容器的名字,需要提前修改以下名字.

echo "欢迎进入lidar的docker容器!,容器内的conda虚拟环境是badgr!!"
docker start lidar 
docker exec -it lidar /bin/bash

然后保存下来,命名为d_lidar_start.sh,打开.bashrc,加入下面的语句:

alias d_lidar="/home/lbw/Shell/d_lidar_start.sh"

保存,然后重新开一个终端,就可以直接输入d_lidar进入刚才创建的容器了:
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第5张图片

3. 在容器使用apt安装软件

调用的时候常常需要安装vim等软件,所以有必要使用apt进行安装.
首先要看一下容器内的系统版本:

cat /etc/issue

发现系统是:Debian11

首先需要换一下Debian11 的apt的源:
备份一下原来的源:
mv /etc/apt/sources.list /etc/apt/sources.list.bak
这里在容器外部先编辑保存一个sources.list:

#http://mirrors.163.com/debian/为软件源也可以为其他的 bullseye为版本代号 main non-free contrib区别如下
deb http://mirrors.163.com/debian/ bullseye main non-free contrib

deb http://mirrors.163.com/debian/ bullseye-updates main non-free contrib

deb http://mirrors.163.com/debian/ bullseye-backports main non-free contrib

deb-src http://mirrors.163.com/debian/ bullseye main non-free contrib

deb-src http://mirrors.163.com/debian/ bullseye-updates main non-free contrib

deb-src http://mirrors.163.com/debian/ bullseye-backports main non-free contrib

#deb http://mirrors.163.com/debian-security/ bullseye/updates main non-free contrib

#deb http://mirrors.ustc.edu.cn/debian-security/ bullseye/updates main non-free contrib

#deb-src http://mirrors.163.com/debian-security/ bullseye/updates main non-free contrib

#deb-src http://mirrors.ustc.edu.cn/debian-security/ bullseye/updates main non-free contrib

deb http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib

deb-src http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib

然后使用docker cp命令复制到容器内的/etc/apt/下面.
然后在容器内使用

apt update 

更新系统源

下面就可以安装vim软件了:

apt get install vim

4.docker拉取官方tensorflow库

看这个博客!
因为我们需要gpu,所以推荐安装:

安装支持GPU版本的tensorflow和jupyter

docker pull tensorflow/tensorflow:latest-gpu-jupyter

为了方便可视化,这里安装了带有jupyter的版本(5.91GB)
等待完成后可以查看镜像:

tensorflow/tensorflow   latest-gpu-jupyter   8da916739a38   9 months ago    5.91GB

然后下一步就是使用这个镜像制作容器.

5.docker在制作容器的时候,允许程序调用外部gpu

https://www.yisu.com/zixun/18335.html

调用gpu进入我们下载的tensorflow容器

docker run -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-jupyter 

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第6张图片

然后按住ctrl 点击链接http://127.0.0.1:8888直接打开网页,或者复制链接到浏览器打开.都可以进入jypyter界面

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第7张图片

进入之后,可以创建文件gpu_test输入下面的代码,来测试是否可以使用gpu:

import tensorflow as tf
with tf.compat.v1.Session():
    input1=tf.constant([1.0,1.0,1.0,1.0])
    input2=tf.constant([2.0,2.0,2.0,2.0])
    output=tf.add(input1,input2)
    result=output.eval()
    print(result)

还可以运行指令!nvidia-smi查看cuda版本和显存:
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第8张图片
至此,说明tf和gpu配置完毕.

6.使用rancher管理容器(未完成,无法创建主机)

链接

6.1 安装和运行rancher:

执行命令:

sudo docker run -d --restart=always -p 8080:8080 rancher/server:stable

参数含义:

-d指在后台运行

--restart=always意思是在遇到重启系统时自动重启docker,不需要手动再去启动

8090端口可以自定义,这是对外的端口

rancher/server是容器名称

stable是官方的稳定版本

安装完成后去浏览器访问,有的浏览器访问不了,最好用谷歌浏览器:

访问地址:ubuntu系统的IP地址:8090(这个端口就是我们自定义的端口,例:127.0.0.1:8090),访问成功后如下图:

可以通过ifconfig指令,查看lo那一项的ip地址,就是本机ip地址,一般默认都是127.0.0.1.然后

浏览器打开下面的地址,进入rancher界面.

127.0.0.1:8090

7.docker版本回退

使用docker version查看docker版本.
通过制定安装版本的方式回退docker版本到18.09.1

sudo apt-get install docker-ce=18.09.1

8.docker 使用ros通信

只要配置好host 名和 ip 地址,就可以实现通信了. 如果实现的话只需要在docker run的时候配置一下host 和 ip,例如, --add-host docker_host:172.17.0.2 --add-host master_host:172.17.0.1 下面步骤是解释了详细原理,实际操作并不需要这么做.

8.1 安装网络管理工具并查看ip地址

在docker中使用ros通信相当于主从机通信.首先需要docker容器里面安装2个网络管理软件:

sudo apt install net-tools #ifconfig
sudo apt install iputils-ping #ping

然后在的容器里面通过ifconfig查看网络连接
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第9张图片
eth0表示的就是和宿主机器的网络通信ip:172.17.0.2
然后到宿主机器里也通过ifconfig查看网络连接:
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第10张图片
对应的docker0表示的就是宿主机器与docker容器的网络通信ip:172.17.0.1
可以ping一下网络通不通,一般是没问题的.
然后下面的步骤就是这个帖子里面的内容了:链接

8.2 分别修改宿主和容器内的/etc/hosts 文件

分别修改宿主和容器内的/etc/hosts 文件,在localhost下面增加上述ip.我这里把宿主机器作为主机,hostname设置为:master_host.容器作为从机,hostname设置为:docker_host

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第11张图片

8.3 分别修改宿主和容器内.bashrc文件

分别修改宿主和容器内.bashrc文件,增加:以下代码:

export ROS_HOSTNAME=本设备命名

export ROS_MASTER_URI=http://主机设备名:11311

ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第12张图片

8.4 测试通信

在宿主机启动roscore
在容器内可以通过rostopic list 看到消息:
ubuntu下使用docker进行深度学习环境配置(从入门到精通)_第13张图片

9. docker内绘图和显示

如果程序里使用了opencv的imshow进行显示,那么就会报错导致程序退出.所以要设置一下让docker能够显示图形化界面:
参考这个链接:链接

9.1 在宿主机安装x11-xserver-utils

开放权限,允许所有用户,当然包括docker,访问X11 的显示接口

sudo apt-get install x11-xserver-utils
xhost +

需要注意的是!!!xhost +这个命令,需要宿主机每一次启动的时候都要输入的.所以可以把这个命令加入到宿主机器的开机自启中.

出现access control disabled, clients can connect from any host说明操作成功.

9.2 在启动docker容器时,添加选项如下:

 -v /tmp/.X11-unix:/tmp/.X11-unix \           #共享本地unix端口

 -e DISPLAY=unix$DISPLAY \                    #修改环境变量DISPLAY

 -e GDK_SCALE \                               #我觉得这两个是与显示效果相关的环境变量,没有细究

 -e GDK_DPI_SCALE \

10. 使用vscode管理和使用docker

在vscode中下载docker的插件,然后就可以非常方便的管理docker容器.
基本的操作是,可以对容器进行开启和停止.还可以直接使用vscode打开容器内的文件夹,对程序进行修改,并且可以实现代码自动补全.

基本操作可以参考链接:链接

11. docker容器设置开机自启和程序自启动

宿主机启动后,docker服务会自动启动,只要在docker run的时候加上这个参数: --restart=always
就可以实现容器随着宿主机器启动而自动启动了.

docker里面跑了我们的程序,那么如何让我们的程序在docker容器启动的同时,也跟着一起启动呢?

这里是通过在home目录下写了一个自启动脚本,然后在bashrc中启动该脚本.因为每次启动容器都会自动启动bashrc,所以就会自动运行程序.

12. 在docker 中进行程序调试和版本管理

这里使用的策略是:

  1. 运行docker容器(同时把本地代码挂载到容器内)
  2. 使用vscode进入容器,并打开代码,修改代码,运行和调试.
  3. 在宿主机一端,使用git管理代码.

13.通过dockerfile 创建 docker镜像

13.1 新建一个文件夹并创建一个Dockerfile文件

注意这个文件夹里面只能有1个Dockerfile文件,并且该文件命名应为Dockerfile

13.2 进入这个文件夹,使用下面指令

docker build -t reposite_name:tap_name .

等待完成

13.3 如果报错了怎么办?

一般情况下,报错都是因为有墙,我们下载的镜像经常有国外的源下载不了的问题.我们可以打开Dockerfile,对相应的语句进行修改,例如

  • apt 改国内源:
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse" >>/etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse" >>/etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse" >>/etc/apt/sources.list
RUN gpg --keyserver keyserver.ubuntu.com --recv A4B469963BF863CC 
RUN gpg --export --armor A4B469963BF863CC | apt-key add -
  • pip 改国内源
# 使用阿里源安装库
RUN ${PIP} config set global.index-url http://mirrors.aliyun.com/pypi/simple/
RUN ${PIP} install xxx --trusted-host mirrors.aliyun.com
# 清华源
RUN ${PIP} config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/

# 阿里源
RUN ${PIP} config set global.index-url http://mirrors.aliyun.com/pypi/simple/

# 豆瓣源
RUN ${PIP} config set global.index-url https://pypi.douban.com/simple

终极启动命令!

一个完整的包含gpu使用,端口映射,hosts配置,图形化界面显示,文件映射的docker run命令:

docker run -it --gpus all -p 8888:8888 --restart=always -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/lbw/study/code/lidar_trajectory:/home/code/lidar_trajectory -e DISPLAY=unix$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE --add-host docker_host:172.17.0.2 --add-host master_host:172.17.0.1 lidar_trajectory_docker:v1

几条经常用的指令

docker   commit -m="ros主从通信-ubuntu2004-tensorflow2.9-gpu-cuda11.2" -a="lbw"  caf1023f4a8d lidar_trajectory:v2

docker run -it --gpus all -p 8888:8888  --restart=always -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/lbw/study/code/lidar_trajectory:/home/code/lidar_trajectory -e DISPLAY=unix$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE --add-host docker_host:172.17.0.2 --add-host master_host:172.17.0.1 lidar_trajectory_docker:v1

你可能感兴趣的:(Docker入门教程系列,docker,ubuntu,容器)