引言
随着机器人操作系统(ROS)在机器人领域的广泛应用,容器化技术成为提高开发效率和简化部署的关键。在多种容器化方案中,基于X11、Wayland和标准Dockerfile的ROS容器化方式各有特点,它们在容器内安装ROS1和ROS2的实现方式和适用场景上存在显著差异。
方案一通过X11协议实现ROS容器的图形界面支持。X11在容器中工作时,通过挂载宿主机的X11套接字并设置环境变量,使容器内的ROS应用能够访问宿主机的图形界面。ROS1的X11容器化实现相对成熟,但ROS2在X11环境下的性能可能受到网络传输开销的影响。
方案二采用Wayland协议代替传统X11,Wayland以其更简洁的架构和更高的图形传输效率著称,减少了中间环节,降低了CPU和内存开销。但Wayland在容器中的使用还处于发展阶段,ROS的Wayland适配需要额外的步骤和工具支持,且跨平台兼容性较差。
方案三则推荐使用标准Dockerfile构建ROS容器。通过Dockerfile,开发者能够在容器内精确配置ROS1和ROS2的运行环境,实现高效的资源管理和安全性控制。Dockerfile的灵活性允许开发者根据需求定制镜像,且Docker的跨平台支持使得容器能够在不同操作系统上无缝运行。
因此,这三种方案分别在图形界面支持、性能、跨平台兼容性、安全性和开发部署便利性上各有优劣。开发者应根据具体的项目需求和技术背景,选择最适合的容器化方案来安装和运行ROS1及ROS2。
最后,如果大家喜欢我的创作风格,请大家多多关注up主,你们的支持就是我创作最大的动力!如果各位观众老爷觉得我哪些地方需要改进,请一定在评论区告诉我,马上改!在此感谢大家了。
各位观众老爷,本文通俗易懂,快速熟悉Docker,收藏本文,关注up不迷路,后续将持续分享Docker纯干货(请观众老爷放心,绝对又干又通俗易懂)。请多多关注、收藏、评论,评论区等你~~~
文章目录
总的来是,创建基于X11容器比较适合在虚拟机中,不推荐双系统使用X11的容器。我写第一章和第二章只是为了让大家能对创建容器的方式有一个更加清晰的认识,还是推荐各位观众老爷使用dockerfile创建容器。
方案一:基于X11的ROS容器化
(一)X11在容器中的工作原理
X11工作原理
- X11(X Window System,也叫 X)在容器中的工作原理主要涉及容器对 X11 协议的处理以及与宿主机或其他 X 服务器的通信等方面,以下是详细解释:
基本概念 - X11 协议 :是一种用于在计算机之间进行图形用户界面交互的网络协议。它允许运行在一台计算机上的图形应用程序在另一台计算机上显示图形界面,并接收用户的输入,如键盘和鼠标操作。
X11在容器中的工作原理主要依赖于以下几种方式:
-
网络通信
-
端口映射 :容器通过端口映射与宿主机的X服务器通信。在宿主机上,X服务器监听特定端口(如6000号),运行容器时,通过在容器和宿主机之间建立端口映射,把容器内的X11应用程序请求转发到宿主机上的X服务器。
-
共享网络命名空间 :让容器与宿主机共享网络命名空间,容器就能直接访问宿主机网络接口和端口,包括X服务器监听端口,实现通信。
-
-
文件系统挂载
-
挂载宿主机X权限文件目录 :X11协议用权限文件控制X服务器访问,通常在宿主机
/tmp/.X11-unix
目录。容器运行时挂载该目录,使容器内X11应用程序能访问权限文件,获得访问权限,同时容器内还需设置正确环境变量,如DISPLAY
变量,告诉X11应用程序图形界面输出位置。 -
设置环境变量 :除了挂载目录,需在容器内设置正确环境变量,像
DISPLAY
变量,其值为宿主机地址和相应显示编号,让X11应用程序知道将图形界面输出到哪。
-
-
X服务器转发与代理
-
X11转发 :部分容器运行环境或远程连接工具支持X11转发功能,容器内X11应用程序图形界面数据经加密通道(如SSH隧道)转发到本地或远程X服务器上显示,适用于远程访问容器中图形应用程序,确保数据安全传输。
-
代理服务器 :在容器和X服务器间设代理服务器,代理服务器可处理和转发X11协议数据,如数据压缩、加密或访问控制等,容器内X11应用程序请求先发给代理服务器,再由代理服务器转发到实际X服务器,把服务器响应返回容器内应用程序。
-
(二)ROS1的X11容器化实现
进入Ubuntu系统后,可以使用X11构建和运行容器。以下是具体的步骤:
- 检查是否安装X11服务器
Ubuntu系统通常已经安装了X11服务器,可以通过以下命令检查是否安装:
echo $DISPLAY
如果输出类似于 :0
或 :1
,则表示X11服务器已运行。
- 安装Docker
这一部分在这里就不再过多赘述, 之前的文章已经讲过。请参照 Docker系列(一):从依赖冲突到标准化交付!容器原理解析×SLAM跨平台实战×10分钟极速部署指南 。
- 拉取ROS1镜像
运行以下命令拉取 ROS1 镜像,此处以 ROS1 Noetic 为例:
docker pull osrf/ros:noetic-desktop-full
如下图所示,出现这样的结果,表示拉取成功!
注释: 这里很多观众老爷经常反映无法拉取,原因无外乎以下几点。
-
命令行输入错误: 这个最好解决,甚至都算不上错误,仔细点。
-
网络问题: 这个需要借助clash,ip最好是大漂亮。
-
镜像源: 官方的镜像源已经不再支持大陆的服务了,需要更换docker的镜像源,之前的博文已经讲过了,请参考 Docker系列(二):从零构建容器环境|服务自启配置×镜像源加速×免sudo提权×避坑手册 。
- 验证ROS1镜像(可选)
查看TAG标签是否存在“noetic-desktop-full”,若存在,则证明已拉取成功!
docker images
- 创建基于X11的容器(直接创建方式)
使用以下命令创建容器:
docker run -it --name ros1 \
--env="DISPLAY" --env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--volume="$HOME/.Xauthority:/root/.Xauthority:rw" \
--env="XAUTHORITY=/root/.Xauthority" \
osrf/ros:noetic-desktop-full \
bash -c "apt-get update && apt-get install -y libxcb* && rqt"
使用下面代码可以进行验证,存在 ros1_container
容器。
docker ps -a
也可以使用如下办法进行创建,虽然不会进行报错,但只能进入到容器中重新进行下载安装ros1。
docker run -it --name ros1_container ubuntu:24.04
- 启动并进入容器
# 启动容器
docker start ros1_container
# 进入容器
docker exec -it ros1 /bin/bash
- 配置ROS1环境
在容器中运行以下命令,配置ROS1环境变量:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
- 运行ROS1程序
# 进入容器后
roscore
(三)ROS2的X11容器化实现
-
前面安装方式相同
-
拉取ROS2镜像
docker pull osrf/ros:humble-desktop-full
- 创建容器
docker run -it \
--name ros2-humble \
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--volume="/home/zys/SLAM/algo/nav:/home/zys/SLAM/algo/nav" \
osrf/ros:humble-desktop-full \
rqt
- 后面操作均一致,记得修改配置环境变量中的ROS版本
方案二:基于Wayland的ROS容器化
(一)Wayland与X11的架构差异
- 架构设计
-
X11 :经典客户端 - 服务器架构,显示服务器管理输入设备和屏幕输出,客户端应用通过网络与显示服务器通信,支持网络透明显示。
-
Wayland :显示服务器直接与硬件通信,客户端应用通过 Wayland 协议与显示服务器交互,中间无 X 服务器。
- 通信机制
-
X11 :应用与 X 服务器通过 X 协议通信,消息传递复杂。
-
Wayland :客户端与显示服务器直接交互,通信基于简洁的 Wayland 协议。
- 性能和效率
-
X11 :复杂架构和历史遗留问题,高分辨率和复杂图形场景下性能不佳。
-
Wayland :简洁架构和硬件优化,性能出色,图形显示流畅。
- 兼容性
-
X11 :应用生态庞大,兼容性好。
-
Wayland :兼容性仍在逐步推广,在主流桌面环境已支持,但覆盖范围不及 X11。
- 组件构成
-
X11 :由 X 服务器、X 客户端、窗口管理器等组成。
-
Wayland :由 Wayland 协议、合成器、客户端组成,合成器管理窗口和输入事件。
(二)ROS的Wayland适配步骤
- 拉取镜像
这里以ROS2为例
sudo docker pull osrf/ros:humble-desktop-full
- 创建容器
docker run -it --name ros2 \
-v SLAM-vol:/root/SLAM \
-e XDG_RUNTIME_DIR=/tmp \
-e WAYLAND_DISPLAY=$WAYLAND_DISPLAY \
-v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/$WAYLAND_DISPLAY \
-e QT_QPA_PLATFORM=wayland \
osrf/ros:humble-desktop-full
- 启动并进入容器
# 启动容器
docker start ros2
# 进入容器
docker exec -it ros2 /bin/bash
- 配置环境
echo "source /ros_entrypoint.sh" >> ~/.bashrc
source ~/.bashrc
- 验证ROS2
ros2
- 启动小乌龟
apt install qtwayland5
ros2 run turtlesim turtlesim_node
方案三:标准Dockerfile构建ROS容器(强烈推荐)
(一)准备DockerFile(以ROS1为例)
之前我们已经在前文讲解过DockerFile了,请参考 Docker系列(三):深度剖析Dockerfile与图形化容器实战 — 3种容器构建方法对比与性能调优 。
- 建立DockerFile
DockerFile可选择建立在任意位置,我选择建在主目录
mkdir ros_docker
cd ~/ros_docker
nano DockerFile
注释: 对这部分内容不熟悉的友友们,可以翻阅我之前的文章。
- 编写文档
# 使用Ubuntu 20.04作为基础镜像
FROM ubuntu:20.04
# 防止在非交互模式下的TZ数据错误
ARG DEBIAN_FRONTEND=noninteractive
# 更新并安装基本工具
RUN apt-get update && apt-get install -y \
lsb-release \
gnupg2 \
curl \
&& rm -rf /var/lib/apt/lists/*
# 添加ROS Noetic的源
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-noetic.list'
# 添加ROS key
RUN curl -sSL 'http://packages.ros.org/ros.key' | apt-key add -
# 安装ROS Noetic Desktop-Full
RUN apt-get update && apt-get install -y \
ros-noetic-desktop-full \
&& rm -rf /var/lib/apt/lists/*
# 初始化rosdep
RUN apt-get update && apt-get install -y \
python3-rosdep \
&& rm -rf /var/lib/apt/lists/* \
&& rosdep init && rosdep update
# 设置环境变量
RUN echo "source /opt/ros/noetic/setup.bash" >> /etc/bash.bashrc
# 安装其他常用工具
RUN apt-get update && apt-get install -y \
python3-rosinstall \
python3-rosinstall-generator \
python3-wstool \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 设置默认工作目录
WORKDIR /root
# 运行bash
CMD ["bash"]
完成后,保存退出。
(二)镜像并运行容器
- 构建DockerFile镜像
注释: 一定要在DockerFile文档的路径下进行这一步操作!并且这一步要等好长时间,耐心等待即可。
docker build -t ros_noetic .
- 运行容器
docker run -it --name ros1_container ros_noetic
- 验证
source /opt/ros/noetic/setup.bash
roscore
三种方案对比分析
(一)性能开销(CPU/GPU/内存)
方案 | 性能开销分析 |
---|---|
X11 | X11 协议会增加一定的网络传输开销,图形界面数据需要在宿主机和容器之间传输,可能导致较高的 CPU 和带宽占用。GPU 直通或共享可改善图形性能,但配置复杂。 |
Wayland | Wayland 协议可减少中间环节,提高图形传输效率,降低 CPU 和内存开销。但在容器技术中使用 Wayland 的经验和工具支持较少,性能表现受应用支持程度影响。 |
Dockerfile | Dockerfile 本身不直接影响性能开销,但通过优化镜像和合理配置资源限制,可以控制容器的 CPU、GPU 和内存使用。在不涉及图形界面时,性能开销主要来自容器的业务负载。 |
(二)跨平台兼容性(Linux/Windows)
方案 | 跨平台兼容性分析 |
---|---|
X11 | 原生支持 Linux ,在 Windows 上需额外软件支持(如 Xming 或 VcXsrv),跨平台使用时兼容性和配置复杂度较高,部分 Linux 特定功能在 Windows 上可能受限。 |
Wayland | 目前主要用于 Linux 系统,Windows 上的 Wayland 支持处于实验阶段,缺乏成熟工具和广泛的软件支持,跨平台兼容性较差。 |
Dockerfile | Docker Desktop 支持 Windows 和 Linux,使得 Dockerfile 定义的容器在这两个系统上都可运行。但需注意架构差异和文件路径等系统特定配置。 |
(三)安全性与权限管理差异
方案 | 安全性与权限管理分析 |
---|---|
X11 | 直接挂载 X11 套接字存在安全风险,可能导致权限提升和访问控制绕过。xhost 命令管理访问权限的方式较为粗糙,不够灵活。 |
Wayland | Wayland 设计提升了安全性,减少了攻击面,但在容器场景中,Wayland socket 的挂载和访问控制仍需谨慎处理,相关安全机制仍在发展中。 |
Dockerfile | 可通过定制化镜像和安装安全工具增强安全性,利用 Docker 的权限控制机制(如用户命名空间)实现更细粒度的权限管理,降低容器与宿主机的耦合度。 |
(四)开发与部署的便利性
方案 | 开发与部署便利性分析 |
---|---|
X11 | 图形界面应用程序开发便利,但容器启动时需要额外参数配置,且在不同系统上的配置复杂度高,可能影响部署效率。 |
Wayland | 开发便利性取决于应用支持程度,容器中使用 Wayland 的文档和工具匮乏,部署时需处理协议兼容性和权限问题。 |
Dockerfile | 开发阶段可定制环境,通过构建参数和多阶段构建优化流程;部署时,Docker 的镜像分发机制简化了跨环境部署,且容器可作为独立单元进行编排和扩展。 |
能够看到这里的观众老爷,无疑是对up的最大肯定和支持,在此恳求各位观众老爷能够多多点赞、收藏和关注。在这个合集中,未来将持续给大家分享关于Docker的多种常见开发实用操作。未来也将继续分享Docker、conda、ROS等等各种实用干货。感谢大家支持!
往期回顾 — 往期专栏 和 系列博文
往期专栏: Ubuntu系列
本期专栏: Docker系列
Docker系列(一):从依赖冲突到标准化交付!容器原理解析×SLAM跨平台实战×10分钟极速部署指南
Docker系列(二):从零构建容器环境|服务自启配置×镜像源加速×免sudo提权×避坑手册