标定docker镜像的搭建和使用方法总结

一、Docker镜像的基本原理和构建方式

构建一个 Docker 镜像,最常用的有两种:

  • 通过docker commit命令,基于一个已存在的容器构建出镜像。
  • 编写 Dockerfile 文件,并使用docker build命令来构建镜像。

上面这两种方法中,镜像构建的底层原理是相同的,都是通过下面 3 个步骤来构建镜像:

  1. 基于原镜像,启动一个 Docker 容器。
  2. 在容器中进行一些操作,例如执行命令、安装文件等。由这些操作产生的文件变更都会被记录在容器的存储层中。
  3. 将容器存储层的变更 commit 到新的镜像层中,并添加到原镜像上。

1.1 Docker 镜像的构建方式使用场景和选型

docker commit这种镜像构建方式通常用在下面两个场景中:

  • 构建临时的测试镜像;
  • 容器被入侵后,使用docker commit,基于被入侵的容器构建镜像,从而保留现场,方便以后追溯。

除了这两种场景,不建议使用docker commit来构建生产现网环境的镜像。

原因如下:

  • 使用docker commit构建的镜像包含了编译构建、安装软件,以及程序运行产生的大量无用文件,这会导致镜像体积很大,非常臃肿。
  • 使用docker commit构建的镜像会丢失掉所有对该镜像的操作历史,无法还原镜像的构建过程,不利于镜像的维护。
  • Dockerfile 的操作流程可以通过docker image history [镜像名称]查询,方便开发者查看变更记录。

在实际开发中,使用Dockerfile来构建是最常用,也最标准的镜像构建方法.

使用 Dockerfile 构建镜像,本质上也是通过镜像创建容器,并在容器中执行相应的指令,然后停止容器,提交存储层的文件变更。和用docker commit构建镜像的方式相比,它有三个好处:

  • Dockerfile 包含了镜像制作的完整操作流程,其他开发者可以通过 Dockerfile 了解并复现制作过程。
  • Dockerfile 中的每一条指令都会创建新的镜像层,这些镜像可以被 Docker Daemnon 缓存。再次制作镜像时,Docker 会尽量复用缓存的镜像层(using cache),而不是重新逐层构建,这样可以节省时间和磁盘空间。
  • 把这一切都放到一个 Dockerfile 里,既没有源码泄漏,又不需要用脚本去跨平台编译,还获得了最小的镜像。

1.2 Dockerfile入门知识

1.2.1什么是Dockerfile

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。

  • dockerfile是自定义镜像的一套规则
  • dockerfile由多条指令构成,Dockerfile中的每一条指令都会对应于Docker镜像中的每一层。

docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终 Docker 引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。

1.2.2 Dockerfile的基本结构

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

1.2.3 Dockerfile 常用的指令

Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。

1.FROM命令

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
  • FROM:指定基础镜像,必须为第一个命令
  • FROM指令用于指定基础镜像,ARG是唯一可以位于FROM指令之前的指令,一般用于声明基础镜像的版本。
  • –platform选项可用在FROM多平台镜像的情况下指定平台。例如,linux/amd64、lunux/arm64、windows/amd64。
  • AS name表示为构建阶段命令,在后续FROM和COPY --from=name说明中可以使用这个名词,引用此阶段构建的映像。
  • tag或digest值是可选的。如果您省略其中任何一个,构建器默认使用latest标签。如果找不到指定tag,构建起将返回错误。
ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD  /code/run-app
FROM extras:${CODE_VERSION}
CMD  /code/run-extras

2.LABEL

LABEL 指令将元数据添加到镜像。LABEL 是键值对。要在 LABEL 值中包含空格,请像在命令行中一样使用引号和反斜杠。

3.WORKDIR

用来指定当前工作目录(或者称为当前目录)

当使用相对目录的情况下,采用上一个WORKDIR指定的目录作为基准

相当于cd 命令,但不同的是指定了WORKDIR后,容器启动时执行的命令会在该目录下执行

4.RUN

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

RUN 主要用于在Image里执行指令,比如安装软件,下载文件等。
COPY指令从复制文件、目录到镜像文件系统的。

5.COPY

编写Dockerfile的时候copy宿主机文件到镜像中。

6.CMD

Dockerfile只允许使用一次CMD命令。使用多个CMD会抵消之前所有的命令,只有最后一个命令生效。一般来说,这是整个Dockerfile脚本的最后一个命令。

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

CMD有三种形式:

  • CMD [“exec”,“param1”,“param2”]:使用exec执行,推荐方式。
  • CMD command param1 param2:在/bin/sh中执行,可以提供交互操作。
  • CMD [“param1”,“param2”]:提供给ENTRYPOINT的默认参数(极少这样使用)。

7.EXPOSE

EXPOSE指令通知容器在运行时监听某个端口,可以指定TCP或UDP,如果不指定协议,默认为TCP端口。但是为了安全,docker run命令如果没有带上相应的端口映射参数,Docker并不会将端口映射出去。

EXPOSE 80/tcp
EXPOSE 80/udp

指定映射端口方式:

docker run -P:将所有端口发布到主机接口,每个公开端口绑定到主机上的随机端口,端口范围在/proc/sys/net/ipv4/ip_local_port_range定义的临时端口范围内。

docker run -p :显式映射单个端口或端口范围。

8.ENTRYPOINT

ENTRYPOINT 指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有其他传入值作为该命令的参数。

一个Dockerfile中只能有一个ENTRYPOINT命令。如果有多条,只有最后一条有效。

无参的方式:
ENTRYPOINT [“/usr/sbin/nginx"]

指定参数的方式:
ENTRYPOINT [“/usr/sbin/nginx”, “-g”, “deamon off"]

docker run 的–entrypoint 标志可以覆盖原Dockerfile中的ENTRYPOINT 指令。

注意理解该命令, 该命令 是指定你每次 docker run启动容器的时候,都会自己执行的一个程序!!!。

CMD与ENTRYPOINT的关系

  • CMD可以为ENTRYPOINT提供参数,ENTRYPOINT本身也可以包含参数,但是可以把需要变动的参数写到CMD里面,而不需要变动的参数写到ENTRYPOINT里面;
  • ENTRYPOINT使用第二种shell方式会屏蔽掉CMD里面的命令参数和docker run后面加的命令。
  • 在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前。

ENTRYPOINT/CMD最后一条命令为无限运行的命令:
这句话才是使用ENTRYPOINT的精髓。
在Docker Daemon模式下,entrypoint、cmd命令的最后一个命令,一定是要当前容器需要一直运行的,才能防止容器退出。

当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令。换句话说实际执行时,会变成 “”

二、标定docker镜像的搭建

docker build 命令用于使用 Dockerfile 创建镜像。

标定Dockerfile文件如下:

# author: huanghongjiang
# date: 2023-07-21
FROM osrf/ros:melodic-desktop-full

#更换源
RUN apt update &&\
cp /etc/apt/sources.list /etc/apt/sources.list.bak &&\
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse" > /etc/apt/sources.list &&\
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse" >> /etc/apt/sources.list &&\
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse" >> /etc/apt/sources.list &&\
echo "deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse" >> /etc/apt/sources.list 
&& apt update
#安装kalibr依赖
RUN apt-get update && DEBIAN_FRONTEND=noninteractive \
	apt-get install -y \
	git wget autoconf automake nano \
	python3-dev python-pip python-scipy python-matplotlib \
	ipython python-wxgtk4.0 python-tk python-igraph python-pyx \
	libeigen3-dev libboost-all-dev 
	libsuitesparse-dev \
	doxygen \
	libopencv-dev \
	libpoco-dev libtbb-dev libblas-dev liblapack-dev libv4l-dev \
	python-catkin-tools
#安装imu-tk依赖
RUN apt-get install build-essential cmake libeigen3-dev libqt4-dev libqt4-opengl-dev freeglut3-dev gnuplot 
#安装Ceres依赖
RUN apt-get install libgoogle-glog-dev libatlas-base-dev &&\
	apt-get install software-properties-common &&\

使用位于当前目录下的Dockerfile创建标定docker镜像,标签为xxx:v1。

sudo docker build -t xxx:v1 . 

三、上传docker镜像到阿里云

3.1 登录到阿里云的doker仓库

sudo docker login --username=**** registry.cn-shenzhen.aliyuncs.com 

–username为阿里云的用户名,另外,密码为开通镜像服务时设置的密码

3.2 为本地docker镜像添加tag

sudo docker tag [镜像ID] registry.cn-shenzhen.aliyuncs.com/xyzxyz/image-test:[镜像版本号]

3.3 推送docker镜像到阿里云的镜像仓库

sudo docker push registry.cn-shenzhen.aliyuncs.com/xyzxyz/image-test:[镜像版本号]

3.4 从阿里云中拉取镜像

sudo docker pull registry.cn-shenzhen.aliyuncs.com/minmirror/minjdk:[镜像版本号]

四、多传感器标定docker镜像的使用方法

4.1 登录阿里云

sudo docker login --username=**** registry.cn-shenzhen.aliyuncs.com 

4.2 拉取FPV相机多传感器标定编译环境docker镜像:

sudo docker pull <REPOSITORY_NAME>:<TAG_NAME>

4.3 编译方法

4.3.1 kalibr的编译方法

4.3.1.1下载kalibr源码到本地
mkdir -p ~/kalibr_workspace/src
cd ~/kalibr_workspace/src
git clone https://github.com/ethz-asl/kalibr.git
4.3.1.2 将本地的kalibr源码以及输入输出目录挂载到docker镜像,启动标定编译环境docker镜像
sudo docker run -it -v {your_path}/kalibr_workspace:/kalibr_workspace/ -v {your_path}/kalibr_input:/kalibr_input -v {your_path}/kalibr_output/:/kalibr_output--rm registry.cn-shenzhen.aliyuncs.com/xxx:v1 bash
4.3.1.3 在docker容器里进行kalibr源码编译

在docker容器下终端:

cd kalibr_workspace && \
catkin init && \
catkin config --extend /opt/ros/melodic && \
catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release && \
catkin build -j16
4.3.1.4 在docker容器内运行kalibr相应程序

在docker容器下终端:

cd /kalibr_workspace &&\
source devel/setup.bash &&\
rosrun kalibr kalibr_calibrate_imu_camera \
	--target /kalibr_input/april_6x6_80x80cm.yml \
	--cam /kalibr_input/cam_april-camchain.yml \
	--imu /kalibr_input/imu_adis16448.yml  \
	--bag /kalibr_input/imu_april.bag  \
	--bag-from-to 5 45

注:在docker容器中无法可视化结果,需要把对应可视化的代码屏蔽掉再执行。

4.3.2 imu_tk的编译方法

4.3.2.1 下载imu_tk源码到本地
git clone https://github.com/Kyle-ak/imu_tk.git
4.3.2.2 将本地的imu_tk源码以及输入输出目录挂载到docker镜像,启动标定编译环境docker镜像
sudo docker run -it -v {your_path}/imutk_workspace:/imutk_workspace/ -v {your_path}/imutk_input:/imutk_input -v {your_path}/imutk_output/:/imutk_output--rm registry.cn-shenzhen.aliyuncs.com/xxx:v1 bash
4.3.2.3 在docker容器里进行imu_tk源码编译

在docker容器下终端:

cd imu_tk && \
mkdir build && \
cd build && \
cmake  .. && \
make -j16
4.3.2.4 在docker容器运行imu_tk相应程序:

在docker容器下终端:

cd /imu_tk/bin/ &&\
./test_imu_calib /imu_tk_input/xsens_acc.mat /imu_tk_input/xsens_gyro.mat 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值