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 代码开发调试工作流程
准备工作:
首先卸载老版本的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
帖子:安装指南
安装完,只用使用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镜像和容器.
帖子:参考链接
国外源比较慢,切换到国内源:
创建或修改 /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
docker run hello-world
拉取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
一般本地镜像地址为:/home/"$USER"/anaconda3/envs
进入第5步中创建的anaconda镜像,然后输入:
conda info --envs
使用下面的指令克隆镜像:
# 在终端中 env_name输入你自己的镜像名字,docker_name输入将要放入的docker镜像名字,然后直接粘贴运行即可~
env_name=badgr
docker_name=lidar
docker cp /home/"$USER"/anaconda3/envs/"$env_name" "$docker_name":/opt/conda/envs
接着再进入容器 查看环境是否复制成功(然后再退出容器):
此时发现已经多了一个badgr镜像。拉取成功!
到此为止,该test容器中已经包含我们所需的代码和环境,可以对其进行打包。
参考链接:参考链接
退出容器后执行:
docker commit -a 'author' -m 'instruction' lidar lidar_img
参数:
等待几分钟,发现镜像制作完成
查看镜像:
docker images
第一个镜像就是我们刚刚制作的新镜像。
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
提交完毕,就可以发现多了一个镜像,下一次我们只需要运行新的镜像就可以了.
docker save -o lidar_tar.tar lidar_img
参数:
到此为止,本地的conda环境便打包完成。
在另一台需要运行镜像的电脑上执行:
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文件夹。
参考这个文章链接
使用-r指令:
docker run -r /host/path:/docker/path
其中/host/path为宿主机需要挂载到docker容器内的目录
/docker/path为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)
rm -rf /etc/systemd/system/docker.service.d
rm -rf /var/lib/docker
rm -rf /var/run/docker
rm -rf /var/run/docker.pid
参考链接:原文链接
我们知道在操作系统当中,默认情况下 Docker 容器的存放位置在 /var/lib/docker 目录下面,可以通过下面命令查看具体位置。
$ sudo docker info | grep "Docker Root Dir"
解决默认存储容量不足的情况,最直接且最有效的方法就是挂载新的分区到该目录。但是在原有系统空间不变的情况下,所以采用软链接的方式,修改镜像和容器的存放路径达到同样的目的。
$ systemctl restart 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
如果 Docker 的版本是 1.12 或以上的,可以修改或新建 daemon.json 文件。修改后会立即生效,不需重启 Docker 服务。
$ vim /etc/docker/daemon.json
{
"registry-mirrors":
["http://7e61f7f9.m.daocloud.io"],
"graph": "/new-path/docker"
}
在 /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
添加链接描述
这个命令可以把后面参数反过来就可以从docker向宿主考文件.
docker cp file_name docker_name:/dir
参数:
新建一个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进入刚才创建的容器了:
调用的时候常常需要安装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
看这个博客!
因为我们需要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
然后下一步就是使用这个镜像制作容器.
https://www.yisu.com/zixun/18335.html
调用gpu进入我们下载的tensorflow容器
docker run -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-jupyter
然后按住ctrl 点击链接http://127.0.0.1:8888直接打开网页,或者复制链接到浏览器打开.都可以进入jypyter界面
进入之后,可以创建文件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版本和显存:
至此,说明tf和gpu配置完毕.
链接
执行命令:
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
使用docker version
查看docker版本.
通过制定安装版本的方式回退docker版本到18.09.1
sudo apt-get install docker-ce=18.09.1
只要配置好host 名和 ip 地址,就可以实现通信了. 如果实现的话只需要在docker run的时候配置一下host 和 ip,例如, --add-host docker_host:172.17.0.2 --add-host master_host:172.17.0.1
下面步骤是解释了详细原理,实际操作并不需要这么做.
在docker中使用ros通信相当于主从机通信.首先需要docker容器里面安装2个网络管理软件:
sudo apt install net-tools #ifconfig
sudo apt install iputils-ping #ping
然后在的容器里面通过ifconfig
查看网络连接
eth0表示的就是和宿主机器的网络通信ip:172.17.0.2
然后到宿主机器里也通过ifconfig
查看网络连接:
对应的docker0表示的就是宿主机器与docker容器的网络通信ip:172.17.0.1
可以ping一下网络通不通,一般是没问题的.
然后下面的步骤就是这个帖子里面的内容了:链接
分别修改宿主和容器内的/etc/hosts 文件,在localhost下面增加上述ip.我这里把宿主机器作为主机,hostname设置为:master_host.容器作为从机,hostname设置为:docker_host
分别修改宿主和容器内.bashrc文件,增加:以下代码:
export ROS_HOSTNAME=本设备命名
export ROS_MASTER_URI=http://主机设备名:11311
在宿主机启动roscore
在容器内可以通过rostopic list 看到消息:
如果程序里使用了opencv的imshow进行显示,那么就会报错导致程序退出.所以要设置一下让docker能够显示图形化界面:
参考这个链接:链接
开放权限,允许所有用户,当然包括docker,访问X11 的显示接口
sudo apt-get install x11-xserver-utils
xhost +
需要注意的是!!!xhost +
这个命令,需要宿主机每一次启动的时候都要输入的.所以可以把这个命令加入到宿主机器的开机自启中.
出现access control disabled, clients can connect from any host说明操作成功.
-v /tmp/.X11-unix:/tmp/.X11-unix \ #共享本地unix端口
-e DISPLAY=unix$DISPLAY \ #修改环境变量DISPLAY
-e GDK_SCALE \ #我觉得这两个是与显示效果相关的环境变量,没有细究
-e GDK_DPI_SCALE \
在vscode中下载docker的插件,然后就可以非常方便的管理docker容器.
基本的操作是,可以对容器进行开启和停止.还可以直接使用vscode打开容器内的文件夹,对程序进行修改,并且可以实现代码自动补全.
基本操作可以参考链接:链接
宿主机启动后,docker服务会自动启动,只要在docker run的时候加上这个参数: --restart=always
就可以实现容器随着宿主机器启动而自动启动了.
docker里面跑了我们的程序,那么如何让我们的程序在docker容器启动的同时,也跟着一起启动呢?
这里是通过在home目录下写了一个自启动脚本,然后在bashrc中启动该脚本.因为每次启动容器都会自动启动bashrc,所以就会自动运行程序.
这里使用的策略是:
注意这个文件夹里面只能有1个Dockerfile文件,并且该文件命名应为Dockerfile
docker build -t reposite_name:tap_name .
等待完成
一般情况下,报错都是因为有墙,我们下载的镜像经常有国外的源下载不了的问题.我们可以打开Dockerfile,对相应的语句进行修改,例如
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 -
# 使用阿里源安装库
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