【泡泡Docker乐园】Dockerfile简易教程 & LARVIO镜像(亲测完美)
简介:【泡泡Docker乐园】第二期来啦!本期我们将简要介绍使用Dockerfile进行image构建的方法。利用Dockerfile可以将image构建的完整过程清晰的展现出来,同时也可方便用户复用layer,减少构建新image的时间开销。最后将提供一个用Dockerfile构建的image项目,单目视觉惯性里程计LARVIO。
编辑:邱笑晨
审核:王强,刘富强,吴奇,王琛
欢迎个人转发朋友圈;其他机构或自媒体如需转载,后台留言申请授权
感谢晨博,感谢泡泡机器人
文章目录
- 【泡泡Docker乐园】Dockerfile简易教程 & LARVIO镜像(亲测完美)
-
1、前言
本期将简要的介绍利用Dockerfile构建image的方法。
在上一期中,image的构建采用的步骤是:首先pull一个现成的image,然后实例化一个该image的container,再在该container中进行各种操作,最后将该container进行提交(commit),从而构建一个新的image。这比较符合我们通常在虚拟机中的工作流程,即进入虚拟系统,然后在该系统内进行各种操作。
这种方式的一个缺点是,其他人在拿到这个image时无法容易地知晓该image到底是如何构建的。同时一些可复用的操作在我们下一次构建新image时又要重新来一遍,比较浪费时间。
Docker中提供了另外一种构建image的方式,即采用Dockerfile。在Dockerfile中,我们可以实现构建image所需的一切操作,包括pull基础image、安装各种库、编辑脚本等等等等。所有的操作都以明文的形式写在Dockerfile中,方便用户掌握构建image的步骤,同时每一条Dockerfile语句都形成一层(layer),当用户在同一基础image上有相同操作时,这些layer可以方便的进行复用,无需重新构建。
Dockerfile基础指令
这部分将介绍一些Dockerfile中常用的基础指令,我们将以ROS的一个官方镜像ros/kinetic-ros-core的Dockerfile为例来进行介绍,地址为:
https://github.com/osrf/docker_images/blob/b075c7dbe56055d862f331f19e1e74ba653e181a/ros/kinetic/ubuntu/xenial/ros-core/Dockerfile
该Dockerfile中所采用的指令并不是全部,但这些指令通常已经能够替代“在container中操作再commit”的image构建过程,能够满足绝大多数需求。
事实上,如果你发现有操作无法在Dockerfile中完成,那一定是你还没找到或者还没理解某些指令。
FROM指令
FROM指令用来指定所要构建的image的基础image。你可以在任意本地或者DockerHub的基础上进行新image的构建,因此FROM指令可以指向本地或者DockerHub上任意可用的image。
在ros/kinetic-ros-core中,该指令的用法为:
FROM ubuntu:xenial
这表示该image是以ubuntu的xenial标签为基础image进行构建的。在后面的构建过程中,该指令会自动从DockerHub中pull下该基础image。后续的其他指令则都基于该image执行。
在DockerFile中,每一条指令语句都构成一个layer,FROM语句一般构成所构建image的第一个layer。
RUN指令
RUN指令用来指明在上一layer基础上要继续进行的操作。它代替了我们进入container中执行各种终端命令来进行配置的过程。任何需要执行终端指令来构建新image的操作,都可以利用RUN来实现。
在ros/kinetic-ros-core中,使用了若干条RUN指令(受限于篇幅,我们只截取部分):
RUN apt-get update && apt-get install -q -y \
dirmngr \
gnupg2 \
&& rm -rf /var/lib/apt/lists
细心的同学们会发现,RUN后面跟的内容和我们在container的终端中执行的指令是一样的。
上面的三条RUN指令,每一条形成一个layer。笔者的建议是,尽量将RUN指令模块化,比如我们要装某个软件,那么可以把所有与该软件相关的依赖项以及该软件的安装都放在一条RUN语句中,这样可提高Dockerfile的可读性,同时也便于复用。不过一个image的layer数是有限制的,因此也要注意不要让层数过多。
ENV指令
ENV指令用来设置环境变量,我们直接用ros/kinetic-ros-core中的例子来说明:
ENV ROS_DISTRO kinetic
RUN rosdep init && \
rosdep update --rosdistro $ROS_DISTRO
可以看到,通过ENV指令设置的环境变量ROS_DISTRO,在后面的RUN指令中被利用。这种用法的好处是,如果我们有某个参数的修改会影响到DockerFile中所有终端命令的执行,那么我们可以设置一个环境变量,通过只修改一处环境变量,即可实现全部终端指令的调整。
同时ENV当然还具备其字面意义的功能,即为image设置一些所需要的环境变量。
COPY指令
COPY指令是懒人福音。尽管RUN指令可以实现所有的终端命令,但有些操作我们可能还是会觉得利用终端来做比较麻烦,比如写一个比较长的脚本。
COPY命令的基本作用是将外部文件复制到image中,我们可以利用这一点,先在宿主机中写好一个脚本,然后直接COPY进去,避免写一个又臭又长的RUN语句。
当然了,一旦采用这种用法,那么如果要了解构建的所有细节,就无法单从Dockerfile中得知了,还需要去看一下外部的这个脚本到底写的是什么。
来看看ros/kinetic-ros-core中的用法:
COPY ./ros_entrypoint.sh /
这里是将本地的一个已经写好的ros_entrypoint.sh文件拷贝到新image的根目录下。
COPY指令中的首个路径可以是宿主机绝对路径或者Dockerfile所在路径的相对路径。一般建议将所需要COPY的文件都放在和Dockerfile的同一级目录。
ENTRYPOINT指令
ENTRYPOINT指令用来指定构建的image实例化时调用的程序。在ros/kinetic-ros-core中其用法为:
ENTRYPOINT ["/ros_entrypoint.sh"]
这其实是将我们在之前COPY进来的脚本作为container初始调用的程序。
CMD指令
CMD指令用来设置构建的image实例化时调用的默认命令,该命令会被docker run中传递的命令(如果有的话)覆盖。在ros/kinetic-ros-core中其用法为:
CMD [“bash”]
这即是说在创建container时会调用bash开启一个终端。
小结
这部分以ros/kinetic-ros-core的Dockerfile为例介绍了一些最基本和常用的Dockerfile指令的基本用法,更多指令和详细用法请参考官方文档:
官方文档
利用Dockerfile构建image
当写好一个Dockerfile之后,构建image就是一句话的事了,当然还需要注意把你想要COPY到image中去的文件准备好(如果有的话)。执行以下指令即可:
docker build -t IMG_NAME DOCKERFILE_PATH
这里我们直接用本期提供的LARVIO镜像作为示例:
注意到该image共有15个layer,也就是说一共有15条语句,由于我之前已经构建过,因此这里显示的都是Using cache。
2、LARVIO项目镜像
本期我们为小伙伴们带来一个单目视觉惯性里程计项目的image——LARVIO。
简介:LARVIO是一款基于MSCKF的单目视觉惯性里程计,提供动/静态场景的自动初始化、可选的在线传感器标定(IMU-CAM外参、时标误差、IMU内参)、hybrid MSCKF/纯MSCKF可选、一维/三维逆深度SLAM features参数化可选、静止检测和零速矫正等功能。核心算法不依赖ROS,项目同时提供了单线程和ROS nodelet例程,分别采用Pangolin和Rviz两种可视化方式。在计算开销更低且无回环的情况下,在EuRoC等数据集上的定位精度与VINS-MONO-LOOP相当。
DockerHub链接
GitHub链接:
LARVIO原始链接:
上手指南:
这里提供一个简易的上手指南。由于是SLAM类项目,因此需要一些可视化工具来展示运行时的pangolin或者rviz效果。
本次提供的镜像中,已经配置好了VNC可视化的相关组件。以下是一套傻瓜教程:
(1)获得镜像
注意:下载速度慢的话建议把docker源配置为阿里云源
首先从DockerHub拉取镜像(宿主终端中执行):
docker pull paopaorobot/larvio
或利用Dockerfile进行本地构建(宿主终端中执行):
git clone \
https://github.com/PaoPaoRobot/docker_larvio.git
cd ./docker_larvio
docker build -t paopaorobot/larvio .
注意后面.
号。
(2)VNC可视化准备
下载与你电脑操作系统匹配的VNC Viewer,地址是:
VNC 下载连接
如果是ubuntu系统,选择DEB X64
,然后使用
sudo dpkg -i *.deb
安装
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407174413647.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
(3)下载数据集
LARVIO的例程提供了EuRoC数据集的演示程序。其中pangolin例程需求asl格式,ros nodelet例程需求bag格式,如果网速比较慢,建议下载最小的V102序列。下载地址是:
https://projects.asl.ethz.ch/datasets/doku.php?id=kmavvisualinertialdatasets
下载不下来的话使用泡泡机器人的百度网盘
(4)创建container
我们假设你将V1_02的asl和bag都存放在宿主的YOUR_PATH_TO_EUROC/V1_02_medium路径下,执行下述命令实例化container:
注意把bag包也放在V1_02_medium下。
docker run -itd -v \
YOUR_PATH_TO_EUROC/V1_02_medium:/root/Dataset/V1_02 \
-p 5900:5900 paopaorobot/larvio
该命令实例化了一个container并且将数据集挂载在container中的/root/Dataset路径下。
然后打开VNC Viewer,输入127.0.0.1:5900进行连接。如下图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020040717490545.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
连接后可观察到如下界面:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407174941665.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
(5)Pangolin例程
在VNC Viewer中,打开一个终端,执行下述命令:
cd /root/LARVIO/build
./larvio \
/root/Dataset/V1_02/mav0/imu0/data.csv \
/root/Dataset/V1_02/mav0/cam0/data.csv \
/root/Dataset/V1_02/mav0/cam0/data \
../config/euroc.yaml
即可直接运行LARVIO的pangolin例程,效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407175551251.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
(6)ROS例程
在宿主机终端中,执行下述命令开启LARVIO节点:
docker exec -itd \
`docker ps | grep paopaorobot/larvio | awk '{print $1}'` \
/bin/bash -c \
'cd /root/LARVIO/ros_wrapper && \
. devel/setup.bash && \
roslaunch larvio larvio_euroc.launch'
然后在VNC Viewer中,打开一个终端,执行下述命令打开rviz可视化:
cd /root/LARVIO/ros_wrapper
. devel/setup.bash
roslaunch larvio larvio_rviz.launch
回到宿主机终端,执行下命令播放数据集:
docker exec -it \
`docker ps | grep paopaorobot/larvio | awk '{print $1}'` \
/bin/bash -c \
'. /opt/ros/melodic/setup.bash && \
rosbag play \
/root/Dataset/V1_02/V1_02_medium.bag'
此时可以在VNC中看到如下效果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407180940470.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
点击阅读原文,即可获取本文相关资源。
欢迎来到泡泡论坛,这里有大牛为你解答关于SLAM的任何疑惑。
有想问的问题,或者想刷帖回答问题,泡泡论坛欢迎你!
泡泡网站:www.paopaorobot.org
泡泡论坛:http://paopaorobot.org/bbs/
泡泡机器人SLAM的原创内容均由泡泡机器人的成员花费大量心血制作而成,希望大家珍惜我们的劳动成果,转载请务必注明出自【泡泡机器人SLAM】微信公众号,否则侵权必究!同时,我们也欢迎各位转载到自己的朋友圈,让更多的人能进入到SLAM这个领域中,让我们共同为推进中国的SLAM事业而努力!
微信扫一扫 关注该公众号
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200407181015123.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTcwNjI2,size_16,color_FFFFFF,t_70)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)