Docker搭建ORB-SLAM3相关开发环境
目前已经构建了orb-slam3的开发环境,下载orb-slam3-dev的tar压缩包,按照下文介绍进行安装。
链接:https://pan.baidu.com/s/1LMLH5pUJZ6oszEezX2ArsA?pwd=fzn2
提取码:fzn2
百度网盘下载后解压,对于熟悉docker用户,快速上手按照4.2加载和保存镜像。
1. Docker简介
1.1. Docker 优势
Docker是一个开源的应用容器化平台,它让开发者可以打包他们的应用及其依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。Docker 提供了一套标准的运行、构建、分发应用的解决方案,可以让应用的部署工作更加高效、快捷和一致性。
**与传统虚拟机相比的优势:**Docker 和传统虚拟机技术虽然都提供了应用程序的隔离环境,但它们在架构、资源利用率、启动速度、便携性等方面存在显著差异:
-
更轻量级:
-
- Docker:容器共享主机的内核,不需要为每个应用配备完整的操作系统,因此体积更小,启动更快。
- 虚拟机:每个VM包含一个完整的Guest OS,消耗更多资源,启动慢。
-
更高的资源利用率:
-
- Docker:由于轻量级特性,可以在同一硬件上运行更多的容器,极大地提高了资源利用效率。
- 虚拟机:每个VM都需要分配独立的资源,即使未充分利用也会占用预定的资源。
-
更快的启动速度:
-
- Docker:容器几乎可以瞬间启动,适合频繁创建和销毁的场景。
- 虚拟机:启动涉及到整个操作系统的加载,耗时较长。
-
更好的可移植性和一致性:
-
- Docker:通过Dockerfile定义应用环境,确保了“一次构建,到处运行”,降低了环境差异带来的问题。
- 虚拟机:虽然也支持迁移,但因其包含整个操作系统,迁移复杂度相对较高。
-
更简单的管理与部署:
-
- Docker:通过Docker CLI或Docker Compose等工具,可以轻松管理容器和应用栈,自动化程度高。
- 虚拟机:管理通常需要更复杂的虚拟化管理平台,操作相对繁琐。
-
更高效的开发与测试环境:
-
- Docker:便于开发者快速搭建与销毁开发、测试环境,加速迭代周期。
- 虚拟机:创建和配置新的开发环境通常耗时较长。
Docker 以其轻量化、高效、灵活的特性,在现代软件开发、持续集成、微服务架构等领域得到了广泛的应用。与传统虚拟机相比,它在资源效率、部署速度、环境一致性等方面展现出了明显优势,成为了现代云原生技术栈中的重要组成部分。使用docker搭建ORB-SLAM3相关的开发环境,可以保证开发、测试、应用环境一样,减少在环境不同导致的bug。
1.2. Docker概念
仓库(Repository):用于存储Docker镜像的地方,类似于源代码控制系统中的代码库。Docker仓库可以是公共的,如Docker Hub,也可以是私人的。
镜像(Image):它是Docker容器的运行时模板,由多个层(layers)组成。每个镜像都包含了一系列修改后的层,当应用更新或升级时,会生成一个新的层。
容器(Container):这是Docker的运行实体,它包含了应用程序所需的所有环境和配置。容器可以在运行状态下被创建、启动、停止、移动和删除。
Docker Client:用户通过这个客户端与Docker守护进程进行交互。
Docker Daemon:守护进程负责管理和调度Docker容器,设置成开机自启的服务
Docker Images:本机下载的镜像,由多个docker命令操作生成镜像层(只读)
Docker Repository:存放镜像的仓库,可以是公共的,如Docker Hub。
2. Docker 安装
本文只介绍ubuntu安装docker和开启docker服务,其他平台类似,安装可能更简便。
官⽹安装⽅法:https://docs.docker.com/engine/install/ubuntu/ 。
2.1. 更新软件包源
sudo apt-get update
sudo apt-get upgrade
2.2. 安装Docker的依赖项
Docker依赖于一些系统库和工具,特别是对于较旧的Linux发行版。安装这些依赖项:
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
2.3. 添加Docker的官方GPG密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
2.4. 设置Docker稳定版存储库:
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
2.5. 安装Docker引擎:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
2.6. 验证安装
sudo docker run hello-world
如果一切正常,你将看到hello from docker。
2.7. 启动Docker服务:
sudo systemctl start docker # 设置开启
sudo systemctl enable docker # 设置开机启动
2.8. 网络问题
如果由于网络问题,这里推荐使用国内编写的脚本,会去国内的服务器下载,按照步骤下载,速度更快。
wget http://fishros.com/install -O fishros && . fishros
2.9. 配置国内镜像源
创建或修改 /etc/docker/daemon.json 文件,修改为如下形式:
{
"registry-mirrors": [
"https://registry.hub.docker.com",
"http://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn"
]
}
拉取镜像源会从国内服务器,速度飞快,
systemctl restart docker
查看是否成功
docker info
hucheng@hucheng-T5-SKYLAKE:~$ docker info
Client: Docker Engine - Community
Version: 24.0.2
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.10.5
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.18.1
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 2
Running: 1
Paused: 0
Stopped: 1
Images: 4
Server Version: 24.0.2
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 3dce8eb055cbb6872793272b4f20ed16117344f8
runc version: v1.1.7-0-g860f061
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: builtin
Kernel Version: 5.4.0-150-generic
Operating System: Ubuntu 18.04.6 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.46GiB
Name: hucheng-T5-SKYLAKE
ID: 01ecf49b-70cb-43e2-9357-3fc22e7001aa
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://dockerproxy.com/
https://hub-mirror.c.163.com/
https://mirror.baidubce.com/
https://ccr.ccs.tencentyun.com/
Live Restore Enabled: false
WARNING: No swap limit support
服务端也开启了,就可以与docker 守护进程通信。docker 也是CS架构,在命令行终端输入的命令需要被守护进程监听,守护进程挂了,docker运行就会报错。
2.10. 允许非root用户使用Docker
默认情况下,只有root用户可以运行Docker命令。如果你想允许其他用户使用Docker,可以将他们加入到docker组:
sudo usermod -aG docker your_username
3. Dockerfile
3.1. 简介
Dockerfile是一个用于自动构建Docker镜像的文本文件,它以一系列指令的形式定义了如何从基础镜像开始,逐步添加文件、安装软件包、设置环境变量、运行脚本等,直至最终形成一个新的自定义镜像的过程。Dockerfile的设计遵循从上至下的执行顺序,每条指令在构建过程中都会在前一层的基础上增加新的一层,从而形成了镜像的层次结构。
3.2. Dockerfile的基本结构和常用指令
- FROM:Dockerfile的第一条指令必须是FROM,用来指定基础镜像。例如,FROM ubuntu:18.04 表示基于Ubuntu 18.04版本的镜像开始构建。
- RUN:用于执行命令,可以是 shell 命令或执行可执行文件。每次RUN指令都会创建一个新的镜像层。例如,RUN apt-get update && apt-get install -y python3 安装Python3。
- COPY:将本地文件或目录复制到镜像内部。例如,COPY . /app 将当前目录下的所有文件复制到镜像的/app目录。
- ADD:类似COPY,但还支持自动解压URL指向的归档文件,并且可以将远程文件下载到镜像中。
- WORKDIR:设置后续命令的默认工作目录,例如,WORKDIR /app 将工作目录设定为/app。
- CMD:指定容器启动时默认执行的命令,可以被docker run命令行参数覆盖。例如,CMD [“python3”, “app.py”],注意只有最后一个CMD命令会生效,会被docker run 的命令参数覆盖(则不执行)
- ENTRYPOINT:类似于CMD,用于配置容器启动时执行的命令,但它不会被docker run命令行参数覆盖,常与CMD一起使用来设置默认参数。
- ENV:设置环境变量,例如,ENV MY_VAR=value。
- EXPOSE:声明容器运行时监听的端口,但并不映射端口,例如,EXPOSE 8080。
- VOLUME:创建数据卷挂载点,例如,VOLUME /data。
- USER:指定运行容器时的用户,例如,USER nobody。
下面是一个dockerfile文件,拉取ros镜像,拷贝orb-slam3到镜像中,安装必要的开发工具。
# 使用ros官方镜像作为基础镜像
FROM osrf/ros:melodic-desktop-full
# 安装必要的基础工具
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
cmake \
gcc \
gedit\
vim \
wget \
curl \
unzip \
libeigen3-dev \
libopencv-dev \
libboost-all-dev \
libpcl-dev \
build-essential
# 设置语言环境
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# 添加用户并设置权限
RUN useradd -ms /bin/bash devuser && \
echo "devuser:123" | chpasswd && \
usermod -aG sudo devuser
# 切换到新用户以进行后续操作
USER devuser
WORKDIR /home/devuser
# 拷贝ORB-SLAM3
COPY slam_ws/ORB_SLAM3 /home/devuser/
# 编译 ORB-SLAM3
RUN cd ORB-SLAM3 && \
chmod +x install.sh && \
./build.sh
# 安装 ORB-SLAM3 ros
RUN echo "export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/devuser/ORB-SLAM3_WT/Examples/ROS" >> ~/.bashrc && \
source ~/.bashrc && \
chmod +x build_ros.sh && \
./build_ros.sh
# 安装ros usb_cam 驱动包
RUN apt install ros-melodic-usb-cam
# 拷贝kalibr (注意路径)
COPY slam_ws/calib_ws/src calib_ws/
# 拷贝sdk
COPY slam_ws/sdk/IMSEE-SDK/ /home/devuser/sdk/IMSEE-SDK/
COPY slam_ws/sdk/librealsense-2.50.0 /home/devuser/sdk/
COPY slam_ws/sdk/realsense_ros/src /home/devuser/sdk/
# 设置ENTRYPOINT,方便进入容器后直接启动bash
ENTRYPOINT ["/bin/bash"]
构建镜像时,推荐找官方镜像或者已经构建完整的镜像。对于官方镜像体积非常小,只有最基础的linux内核,适合非常轻量级的示例。完整的镜像提供了更多工具,适合做算法开发与测试。
3.3. Dockerfile优势
- 可重复性:确保每次构建的镜像都是相同的,有利于持续集成和持续部署(CI/CD)流程。
- 可维护性:Dockerfile作为代码的一部分,可以版本控制,便于追踪更改和协作。
- 效率:通过分层构建,仅当某层内容变化时才会重新构建那一层,节省时间和资源。
- 标准化:统一应用的部署和运行环境,降低环境差异带来的问题。
Dockerfile的编写遵循简洁和明确的原则,使得构建过程清晰可见,便于管理和维护,是Docker生态中构建镜像的重要工具。
4. 镜像
4.1. 构建镜像
根据上面的流程,编写dockerfile构建自己的镜像,运行命令:
docker build -t <image-name>[:<tag>] .
上面的命令会寻找当前目录下的Dockerfile文件,tag省略时,默认是latest版本。如果是其他名字,运行命令:
docker build -f /path/to/your/custom-Dockerfile -t my-image .
- -f 或 --file 指定了Dockerfile的路径。
- -t 用于指定构建后镜像的仓库名和标签。
- . 表示上下文目录,Docker会从这个目录中获取Dockerfile以及COPY或ADD命令中引用的文件。即使你指定了-f来改变Dockerfile的位置,构建上下文仍然很重要,因为它定义了Docker能够访问哪些文件。
4.2. 加载和保存镜像
构建镜像过程比较复杂,需要等待较长的时间,因此推荐下载别人构建的镜像,只需要拷贝tar包,也可以将个人构建的镜像打包给人使用。
运行docker images 显示这是本人电脑下载的docker镜像:
hucheng@hucheng-T5-SKYLAKE:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
orb-slam3-compile 1 f5ead81c107e 3 days ago 7.13GB
orb-slam3-dev latest 3640663d2b5d 3 days ago 4.35GB
ubuntu 18.04 5a214d77f5d7 2 years ago 63.1MB
hello-world latest 48b5124b2768 7 years ago 1.84kB
4.3. 使用docker save导出完整镜像(包括元数据和历史):
docker save -o my_image.tar my_image:tag
-o指定输出文件名,my_image是镜像名,:tag是镜像的标签,如果不指定,默认是latest。
4.4. 使用docker export导出运行时镜像状态:
docker export my_container > my_container.tar
注意,docker export需要容器ID或名称,而不是镜像名。
4.5. 加载Docker镜像
导出的tar文件可以通过docker load命令加载到Docker中,使其成为可用的镜像。
docker load -i my_image.tar
因此下载百度网盘的orb-slam3-dev包,运行下面命令加载镜像:
docker load -i orb-slam3-dev
或者,如果使用的是docker import命令来直接从tar文件创建一个新的镜像(这种方式不保留原有镜像的历史记录):
cat my_container.tar | docker import - my_new_image:tag
docker save和docker export用于导出镜像或容器为tar文件,适合于备份或传输;而docker load和docker import则用于将这些tar文件重新导入Docker,使之成为可运行的镜像。docker使用分层的概念,最上面是可写层,其他层都是可读层,有唯一的id,可读层可以服用,占用磁盘更小。
5. 容器
5.1. 简介
Docker容器是Docker技术的核心组成部分,它们是轻量级、可移植的运行时环境,用于执行应用程序及其所有依赖项。容器与宿主机共享操作系统内核,但拥有自己独立的文件系统、网络配置、进程空间等,从而实现了与主机和其他容器的隔离。下面是对Docker容器的基本使用方法。
5.2. 创建并启动容器
- 使用 docker run:这是一步到位创建并启动容器的命令。例如,基于 ubuntu 镜像创建一个新容器,并运行交互式 Bash shell:
docker run -it --name dev -v /home/path: ~/dev ubuntu /bin/bash
-i 表示使容器的标准输入保持打开,-t 分配一个伪TTY,–name 命令,-v 挂载 ,ubuntu 是镜像名
5.3. 启动已存在的容器
- 使用 docker start:启动一个已创建但未运行的容器。需要提供容器的ID或名称:
docker start <容器ID或名称>
5.4. 停止容器
- 使用 docker stop:停止运行中的容器。可指定容器ID或名称,并可设置超时时间:
docker stop [容器ID或名称] [-t|--time[=10]]
5.5. 重启容器
- 使用 docker restart:重启一个容器。同样需要容器的ID或名称:
docker restart [容器ID或名称]
5.6. 删除容器
- 使用 docker rm:删除已停止的容器。对于运行中的容器,需加 -f 强制删除:
docker rm [容器ID或名称]
若要删除所有容器(包括运行中的),可以结合 docker ps -aq 列出所有容器ID,然后传递给 rm 命令:
docker rm $(docker ps -aq)
5.7. 查看容器
- 使用 docker ps:列出正在运行的容器。使用 -a 参数可以查看所有容器(包括停止的):
docker ps [-a]
5.8. 进入容器
- 使用 docker exec:在运行中的容器中执行命令,常用于进入容器的shell:
docker exec -it [容器ID或名称] /bin/bash
- 使用 docker attach:直接附加到容器的标准输入输出流,但不如 exec 方便管理:
docker attach [容器ID或名称]
5.9. 导入和导出容器
- 导出容器:使用 docker export 命令将容器保存为tar文件:
docker export [容器ID或名称] > container.tar
- 导入容器:使用 docker import 命令将tar文件导入为新的镜像,然后可以基于该镜像启动容器:
cat container.tar | docker import - new_image_name:tag
5.10. 运行容器完整命令
docker 容器启动后的名称唯一,下面是一个完整的运行和进入docker容器的命令:
docker run \
--detach, -d \
--name my_container_name \
--restart always \
--volume /host/dir:/container/dir:ro \
--publish 8080:80 \
--env VAR1=value1 \
--env-file ./env.list \
--memory="512m" \
--cpus="0.5" \
--network my_network \
--mac-address="02:42:ac:11:65:43" \
--dns 8.8.8.8 \
--dns-search example.com \
--user 1000:1000 \
--workdir /app \
--read-only \
--security-opt label=disable \
--cap-add=SYS_ADMIN \
--device=/dev/sdc \
--privileged \
--runtime=runc \
my_image:tag \
command arg1 arg2
这个命令的各部分含义如下:
- –detach, -d:以后台模式运行容器。
- –name my_container_name:为容器指定一个名称。
- –restart always:容器退出后总是重启。
- –volume /host/dir:/container/dir:ro:将主机的/host/dir目录以只读形式挂载到容器的/container/dir。
- –publish 8080:80:将容器的80端口映射到主机的8080端口。
- –env VAR1=value1:设置环境变量VAR1的值为value1。
- –env-file ./env.list:从文件加载环境变量。
- –memory=“512m”:限制容器内存使用为512MB。
- –cpus=“0.5”:限制容器使用CPU核心数为0.5个核心。
- –network my_network:连接到名为my_network的网络。
- –mac-address=“02:42:ac:11:65:43”:指定容器的MAC地址。
- –dns 8.8.8.8:设置DNS服务器。
- –dns-search example.com:设置DNS搜索域名。
- –user 1000:1000:以uid 1000 和 gid 1000的用户身份运行容器。
- –workdir /app:设置容器的工作目录。
- –read-only:以只读模式挂载容器的根文件系统。
- –security-opt label=disable:禁用SELinux标签。
- –cap-add=SYS_ADMIN:向容器添加特定能力,如SYS_ADMIN。
- –device=/dev/sdc:向容器添加主机设备。
- –privileged:给予容器更多权限,接近于宿主机。
- –runtime=runc:指定容器运行时。
- my_image:tag:使用的镜像名称及标签。
- command arg1 arg2:容器启动后执行的命令及其参数。
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
可选参数(OPTIONS)包括:
-
-d, --detach:以后台模式运行命令,在容器中不保留标准输入输出。默认情况下,exec 命令会同步执行并等待命令完成。
-
-e, --env=[]:设置环境变量,格式为 key=value。可以多次使用该选项来设置多个环境变量。
-
-i, --interactive
-
- 保持标准输入 (STDIN) 打开,即使没有连接到终端也是如此。这对于需要用户输入的交互式命令很有用。
-
-t, --tty:分配一个伪终端 (TTY),通常与 -i 一起使用,为命令提供一个类似终端的环境。
-
-u, --user=“”:指定在容器中执行命令的用户名或 UID,以及可选的组名或 GID(格式为 :)。
-
–privileged:给予在容器中运行的命令扩展权限,类似于具有 root 权限,但更进一步,能访问所有设备节点等。
-
-w, --workdir=“”:指定容器内执行命令的工作目录。
-
–detach-keys=“”:覆盖容器分离时使用的键序列。
-
–help:显示帮助信息。
-
CONTAINER 是其中执行命令的容器的名称或ID。
-
COMMAND [ARG…] 是在容器内执行的具体命令及其参数。
6. vscode插件开发
docker命令非常多,掌握最简单最常用的命令即可。推荐使用vscode和插件进入docker容器,下载docker和ssh插件:
vscode远程连接,选择开发容器
选择对应的容器,进入容器内部
7. 总结
这里也有一份pdf文档关于docker使用,搭建了可视化的web端,使用docker-compose启动多容器(待续). 本教程目前只介绍docker构建镜像和运行容器。
up>)。
- –privileged:给予在容器中运行的命令扩展权限,类似于具有 root 权限,但更进一步,能访问所有设备节点等。
- -w, --workdir=“”:指定容器内执行命令的工作目录。
- –detach-keys=“”:覆盖容器分离时使用的键序列。
- –help:显示帮助信息。
- CONTAINER 是其中执行命令的容器的名称或ID。
- COMMAND [ARG…] 是在容器内执行的具体命令及其参数。
6. vscode插件开发
docker命令非常多,掌握最简单最常用的命令即可。推荐使用vscode和插件进入docker容器,下载docker和ssh插件:
[外链图片转存中…(img-pjoVEw6o-1719629496791)] vscode远程连接,选择开发容器
[外链图片转存中…(img-Orr4kovZ-1719629496792)] 选择对应的容器,进入容器内部
[外链图片转存中…(img-EWPlw53v-1719629496793)]
7. 总结
这里也有一份pdf文档关于docker使用,搭建了可视化的web端,使用docker-compose启动多容器(待续). 本教程目前只介绍docker构建镜像和运行容器。