热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【泡泡Docker乐园】Dockerfile简易教程&LARVIO镜像

转载自:https:mp.weixin.qq.comsWf1aCGhl4U64SWiAe6My_Q【泡泡Docker乐园】Dockerfile简易教程&LARVIO镜像原创泡泡机器

转载自:https://mp.weixin.qq.com/s/Wf1aCGhl4U64SWiAe6My_Q


【泡泡Docker乐园】Dockerfile简易教程 & LARVIO镜像

原创 泡泡机器人 泡泡机器人SLAM 2020-04-07

泡泡Docker乐园,带你进入Docker的狂欢派对

简介:【泡泡Docker乐园】第二期来啦!本期我们将简要介绍利用Dockerfile进行image构建的方法。利用Dockerfile可以将image构建的完整过程清晰的展现出来,同时也可方便用户复用layer,减少构建新image的时间开销。最后将提供一个用Dockerfile构建的image项目,单目视觉惯性里程计LARVIO。

编辑:邱笑晨

审核:王强,刘富强,吴奇,王琛

欢迎个人转发朋友圈;其他机构或自媒体如需转载,后台留言申请授权

图片

前言

图片

本期将简要的介绍利用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 apt-key adv ...RUN echo ...

细心的同学们会发现,RUN后面跟的内容和我们在container的终端中执行的指令是一样的。

上面的三条RUN指令,每一条形成一个layer。笔者的建议是,尽量将RUN指令模块化,比如我们要装某个软件,那么可以把所有与该软件相关的依赖项以及该软件的安装都放在一条RUN语句中,这样可提高Dockerfile的可读性,同时也便于复用。不过一个image的layer数是有限制的,因此也要注意不要让层数过多。

ENV指令

ENV指令用来设置环境变量,我们直接用ros/kinetic-ros-core中的例子来说明:


ENV ROS_DISTRO kineticRUN 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指令的基本用法,更多指令和详细用法请参考官方文档:

https://docs.docker.com/engine/reference/builder/

图片

 

利用Dockerfile构建image

图片

 

当写好一个Dockerfile之后,构建image就是一句话的事了,当然还需要注意把你想要COPY到image中去的文件准备好(如果有的话)。执行以下指令即可:


docker build -t IMG_NAME DOCKERFILE_PATH

这里我们直接用本期提供的LARVIO镜像作为示例:

图片

注意到该image共有15个layer,也就是说一共有15条语句,由于我之前已经构建过,因此这里显示的都是Using cache。

图片

LARVIO项目镜像

图片

本期我们为小伙伴们带来一个单目视觉惯性里程计项目的image——LARVIO。

简介:LARVIO是一款基于MSCKF的单目视觉惯性里程计,提供动/静态场景的自动初始化、可选的在线传感器标定(IMU-CAM外参、时标误差、IMU内参)、hybrid MSCKF/纯MSCKF可选、一维/三维逆深度SLAM features参数化可选、静止检测和零速矫正等功能。核心算法不依赖ROS,项目同时提供了单线程和ROS nodelet例程,分别采用Pangolin和Rviz两种可视化方式。在计算开销更低且无回环的情况下,在EuRoC等数据集上的定位精度与VINS-MONO-LOOP相当。

链接:

DockerHub链接

https://hub.docker.com/r/paopaorobot/larvio

GitHub链接:

https://github.com/PaoPaoRobot/docker_larvio

LARVIO原始链接:

https://github.com/PetWorm/LARVIO

上手指南:

这里提供一个简易的上手指南。由于是SLAM类项目,因此需要一些可视化工具来展示运行时的pangolin或者rviz效果。

本次提供的镜像中,已经配置好了VNC可视化的相关组件。以下是一套傻瓜教程:

(1)获得镜像

首先从DockerHub拉取镜像(宿主终端中执行):


docker pull paopaorobot/larvio

或利用Dockerfile进行本地构建(宿主终端中执行):


git clone \ https://github.com/PaoPaoRobot/docker_larvio.gitcd ./docker_larviodocker build -t paopaorobot/larvio .

(2)VNC可视化准备

下载与你电脑操作系统匹配的VNC Viewer,地址是:

https://www.realvnc.com/en/connect/download/viewer/

(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:


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进行连接。如下图:

图片

连接后可观察到如下界面:

图片

 

(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例程,效果如下:

图片

(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.bashroslaunch 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中看到如下效果:

图片

 

泡泡Docker乐园往期回顾:

【泡泡Docker乐园】手把手带你走进Docker世界

如果你对本文感兴趣,想要下载完整文章进行阅读,可以关注【泡泡机器人SLAM】公众号

点击阅读原文,即可获取本文相关资料。



推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
author-avatar
qgd2013_184
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有