在 EndeavourOS 上开发 ROS 2 Humble 时,我希望继续使用宿主机的新内核和桌面环境,但把 ROS 依赖固定在官方支持的 Ubuntu 22.04 里。这里使用 rootless Podman + Distrobox 创建独立容器,通过华为云 Ubuntu/ROS 2 镜像安装 Humble Desktop,并让 RViz 默认使用宿主机 NVIDIA 独显。

最终环境:

  • 容器名:ros2-humble
  • 容器 home:~/distrobox-homes/ros2-humble
  • 系统:Ubuntu 22.04.4 LTS / amd64
  • ROS:ros-humble-desktop 0.10.0-1jammy.20260612.213429
  • 开发工具:ros-dev-tools、colcon、rosdep、GCC 11、CMake 3.22、Git
  • 默认 shell:zsh,同时配置交互式 bash
  • 独显:NVIDIA GeForce RTX 5070 Ti Laptop GPU
  • 宿主 NVIDIA 驱动:610.43.02
  • OpenGL:NVIDIA / 4.6,无 llvmpipe

一、宿主机准备

安装 Podman 和 Distrobox:

BASH
sudo pacman -S --needed podman distrobox

验证版本和架构:

BASH
podman --version
distrobox --version
uname -m

本次环境为:

TEXT
podman version 6.0.0
distrobox: 1.8.2.5
x86_64

二、先验证宿主机 NVIDIA PRIME offload

这台机器是 Intel Arrow Lake 核显 + NVIDIA 独显的混合显卡环境。创建容器前,先确认宿主机独显正常:

BASH
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader

__NV_PRIME_RENDER_OFFLOAD=1 \
__GLX_VENDOR_LIBRARY_NAME=nvidia \
glxinfo -B

本机结果:

TEXT
NVIDIA GeForce RTX 5070 Ti Laptop GPU, 610.43.02
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce RTX 5070 Ti Laptop GPU/PCIe/SSE2

三、拉取 Ubuntu 22.04 并创建容器

通过华为云 SWR 拉取 Ubuntu 22.04:

BASH
podman pull \
  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/ubuntu:22.04

podman tag \
  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/ubuntu:22.04 \
  localhost/ubuntu:22.04

创建独立 home 和带 NVIDIA 集成的 Distrobox:

BASH
mkdir -p ~/distrobox-homes/ros2-humble

distrobox create \
  --image localhost/ubuntu:22.04 \
  --name ros2-humble \
  --home ~/distrobox-homes/ros2-humble \
  --nvidia \
  --additional-flags "--env __NV_PRIME_RENDER_OFFLOAD=1 --env __GLX_VENDOR_LIBRARY_NAME=nvidia --env __VK_LAYER_NV_optimus=NVIDIA_only" \
  --yes

--nvidia 会把与宿主驱动版本匹配的 NVIDIA 用户态库集成进容器。三个环境变量让 OpenGL 和 Vulkan 默认选择 NVIDIA,这样 RViz、rqt 等程序不需要每次手工添加 PRIME 参数。

首次进入会安装 Distrobox 基础整合包:

BASH
distrobox enter ros2-humble

四、配置 Ubuntu Jammy 镜像源

以下命令都在容器内执行。

BASH
sudo tee /etc/apt/sources.list >/dev/null <<'EOF'
deb https://mirrors.huaweicloud.com/repository/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.huaweicloud.com/repository/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.huaweicloud.com/repository/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.huaweicloud.com/repository/ubuntu/ jammy-security main restricted universe multiverse
EOF

sudo tee /etc/apt/apt.conf.d/99huaweicloud-direct >/dev/null <<'EOF'
Acquire::http::Proxy::mirrors.huaweicloud.com "DIRECT";
Acquire::https::Proxy::mirrors.huaweicloud.com "DIRECT";
EOF

安装仓库配置工具并设置 UTF-8 Locale:

BASH
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ca-certificates curl gnupg lsb-release locales software-properties-common

sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8

五、安装 ROS 2 Humble Desktop

添加 ROS 仓库签名密钥:

BASH
sudo install -d -m 0755 /usr/share/keyrings

curl -fsSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  | sudo gpg --dearmor --yes \
      -o /usr/share/keyrings/ros-archive-keyring.gpg

添加华为云 ROS 2 Jammy 源:

BASH
sudo tee /etc/apt/sources.list.d/ros2.list >/dev/null <<'EOF'
deb [arch=amd64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.huaweicloud.com/ros2/ubuntu/ jammy main
EOF

安装 Humble Desktop 和开发工具:

BASH
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ros-humble-desktop \
  ros-dev-tools \
  build-essential cmake git \
  python3-colcon-common-extensions \
  mesa-utils

Desktop 版包含 RViz、rqt、turtlesim、demo nodes 和完整图形栈。本次下载约 700 MB,共安装 1300 余个 deb 包。

六、配置 shell 自动加载 Humble

当前容器跟随宿主机使用 zsh:

BASH
touch ~/.zshrc
grep -qxF 'source /opt/ros/humble/setup.zsh' ~/.zshrc \
  || echo 'source /opt/ros/humble/setup.zsh' >> ~/.zshrc

同时配置交互式 bash:

BASH
grep -qxF 'source /opt/ros/humble/setup.bash' ~/.bashrc \
  || echo 'source /opt/ros/humble/setup.bash' >> ~/.bashrc

重新进入后验证:

BASH
echo "$ROS_DISTRO"
ros2 pkg prefix demo_nodes_cpp
colcon --help >/dev/null && echo colcon_ok

预期:

TEXT
humble
/opt/ros/humble
colcon_ok

需要注意,Ubuntu 默认 .bashrc 在非交互 bash -lc 中会提前返回。从宿主机直接执行 ROS 2 命令时,应显式加载环境:

BASH
distrobox enter ros2-humble -- bash -lc '
source /opt/ros/humble/setup.bash
ros2 topic list
'

如果脚本使用 set -u,必须先 source /opt/ros/humble/setup.bash,再开启 nounset;Humble setup 脚本会读取一些可选环境变量。

七、验证 ROS 2 pub/sub

在容器内启动 C++ demo talker,再读取一条 /chatter

BASH
source /opt/ros/humble/setup.bash

ros2 run demo_nodes_cpp talker >/tmp/ros2-humble-talker.log 2>&1 &
talker_pid=$!

sleep 2
timeout 20 ros2 topic echo --once /chatter std_msgs/msg/String

kill "$talker_pid" 2>/dev/null || true
wait "$talker_pid" 2>/dev/null || true

本次冷启动后的实际输出:

TEXT
data: 'Hello World: 3'
---

这说明 ROS 2 节点、DDS 发现、话题发布和订阅链路都正常。

八、验证 NVIDIA OpenGL 与 RViz

不添加临时环境变量,直接执行:

BASH
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader
glxinfo -B

实际结果:

TEXT
NVIDIA GeForce RTX 5070 Ti Laptop GPU, 610.43.02
direct rendering: Yes
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce RTX 5070 Ti Laptop GPU/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 610.43.02

实际启动 RViz 后,日志显示:

TEXT
[rviz2]: OpenGl version: 4.6 (GLSL 4.6)

输出中没有 llvmpipe,也没有 Mesa driver error。

九、为什么 Ubuntu 22.04 核显路径会回退 llvmpipe

宿主机 Intel 核显为 Arrow Lake-S,PCI ID 是 8086:7d67。容器能看到 /dev/dri/renderD128renderD129,权限也正常,但 Ubuntu 22.04 HWE Mesa 23.2.1 会报告:

TEXT
MESA: warning: Driver does not support the 0x7d67 PCI ID.
libGL error: failed to load driver: iris

随后回退到 llvmpipe。这里缺的不是内核设备映射,而是容器内旧 Mesa 对 Arrow Lake 设备表和图形特性的支持。

Mesa 24.1 发布记录里才出现 ARL platform、L3、modifier、PAT、MOCS 等一系列支持。宿主 EndeavourOS 的 Mesa 26.1.4 能正确识别 Mesa Intel(R) Graphics (ARL),但把宿主 Mesa 强行塞进 Ubuntu 22.04 容器容易引入 LLVM、glibc 和 ABI 问题。因此这里选择复用 NVIDIA 驱动。

十、安装被中断后的恢复

如果安装过程中断,dpkg --audit 可能列出大量“已解包、未配置”的包。无需删除容器,重新启动后执行:

BASH
sudo DEBIAN_FRONTEND=noninteractive dpkg --configure -a
sudo DEBIAN_FRONTEND=noninteractive apt-get -f install -y

sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  ros-humble-desktop \
  ros-dev-tools \
  build-essential cmake git \
  python3-colcon-common-extensions \
  mesa-utils

最后确认没有未配置包:

BASH
dpkg --audit

十一、日常使用

进入容器:

BASH
distrobox enter ros2-humble

创建 colcon 工作空间:

BASH
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build --symlink-install
source install/setup.zsh

宿主机直接编译:

BASH
distrobox enter ros2-humble -- bash -lc '
source /opt/ros/humble/setup.bash
cd ~/ros2_ws
colcon build --symlink-install
'

停止容器:

BASH
distrobox stop ros2-humble

宿主机升级 NVIDIA 驱动后,停止并重新进入容器,让 Distrobox 刷新 NVIDIA 用户态库,再用 nvidia-smiglxinfo -B 重新验收。