Podman 容器管理:RTAB-Map ROS 2 开发环境

本文介绍如何在 NixOS + Podman 环境下管理 RTAB-Map ROS 2 容器,涵盖容器启动、交互、设备挂载、GUI 支持等常用操作。


📋 目录

  1. 启动已有容器
  2. 进入容器交互
  3. 创建新容器(推荐配置)
  4. 设备挂载与权限
  5. GUI 支持配置
  6. 常用 Podman 命令速查
  7. 故障排查

启动已有容器

基本启动

# 启动已存在的容器
podman start rtabmap-realsense

# 查看容器状态
podman ps -a

带交互模式启动

# -i: interactive(交互模式)
podman start -i rtabmap-realsense

⚠️ 注意:如果容器原本是用 sleep infinity 启动的,没有交互式 shell,此命令不会进入 shell。


进入容器交互

使用 exec 进入运行中的容器

# 进入容器的 bash shell
podman exec -it rtabmap-realsense bash

前提条件:容器必须已经处于运行状态

完整流程

# 1. 启动容器(如果未运行)
podman start rtabmap-realsense

# 2. 进入容器
podman exec -it rtabmap-realsense bash

# 3. 在容器内执行 ROS 2 命令
source /opt/ros/humble/setup.bash
ros2 topic list

执行单条命令(不进入 shell)

# 直接在容器内执行命令
podman exec rtabmap-realsense ros2 topic list

# 执行 RTAB-Map 节点
podman exec -it rtabmap-realsense ros2 launch rtabmap_launch rtabmap.launch.py

创建新容器(推荐配置)

基础开发容器

podman run -it --name rtabmap-dev \
    --network=host \
    --privileged \
    -v $(pwd):/workspace \
    -w /workspace \
    docker.io/introlab3it/rtabmap_ros:humble-latest \
    bash

参数说明

参数 说明
-it 交互式 + TTY
--name rtabmap-dev 容器名称
--network=host 使用主机网络(ROS 2 通信需要)
--privileged 特权模式(访问设备)
-v $(pwd):/workspace 挂载当前目录
-w /workspace 设置工作目录

完整配置(RealSense + GUI)

podman run -it --name rtabmap-realsense-new \
    --network=host \
    --privileged \
    --device=/dev/video0 \
    --device=/dev/video1 \
    --device=/dev/video2 \
    --device=/dev/video3 \
    --group-add=$(getent group video | cut -d: -f3) \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v /dev/bus/usb:/dev/bus/usb \
    -e DISPLAY=$DISPLAY \
    -e QT_X11_NO_MITSHM=1 \
    -v $(pwd):/workspace \
    -w /workspace \
    docker.io/introlab3it/rtabmap_ros:humble-latest \
    bash

后台运行容器

# 后台启动(使用 sleep infinity 保持运行)
podman run -d --name rtabmap-background \
    --network=host \
    --privileged \
    -v $(pwd):/workspace \
    docker.io/introlab3it/rtabmap_ros:humble-latest \
    sleep infinity

# 需要时再进入
podman exec -it rtabmap-background bash

设备挂载与权限

RealSense 相机挂载

# 查看 RealSense 设备
ls -la /dev/video*

# 挂载所有视频设备
podman run -it \
    --device=/dev/video0 \
    --device=/dev/video1 \
    --device=/dev/video2 \
    --device=/dev/video3 \
    --device=/dev/video4 \
    --device=/dev/video5 \
    ...

USB 设备完整访问

# 挂载整个 USB 总线(更简单但权限更大)
podman run -it \
    -v /dev/bus/usb:/dev/bus/usb \
    --privileged \
    ...

视频组权限

# 获取 video 组 ID 并添加到容器
--group-add=$(getent group video | cut -d: -f3)

NixOS 特殊配置

在 NixOS 上,可能需要额外配置 udev 规则:

# /etc/nixos/configuration.nix
services.udev.extraRules = ''
  # RealSense 设备规则
  SUBSYSTEM=="usb", ATTRS{idVendor}=="8086", MODE="0666"
'';

GUI 支持配置

X11 转发

# 允许本地 X11 连接
xhost +local:

# 启动容器时挂载 X11 socket
podman run -it \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -e DISPLAY=$DISPLAY \
    -e QT_X11_NO_MITSHM=1 \
    ...

Wayland 支持(如适用)

podman run -it \
    -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY \
    -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
    -v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/$WAYLAND_DISPLAY \
    ...

测试 GUI

# 在容器内测试 GUI
podman exec -it rtabmap-realsense bash -c "
    source /opt/ros/humble/setup.bash
    rviz2
"

常用 Podman 命令速查

容器生命周期

# 查看所有容器(包括停止的)
podman ps -a

# 启动容器
podman start <container_name>

# 停止容器
podman stop <container_name>

# 重启容器
podman restart <container_name>

# 删除容器
podman rm <container_name>

# 强制删除运行中的容器
podman rm -f <container_name>

容器信息

# 查看容器日志
podman logs <container_name>

# 实时查看日志
podman logs -f <container_name>

# 查看容器详细信息
podman inspect <container_name>

# 查看容器资源使用
podman stats <container_name>

镜像管理

# 列出镜像
podman images

# 拉取镜像
podman pull docker.io/introlab3it/rtabmap_ros:humble-latest

# 删除镜像
podman rmi <image_id>

数据持久化

# 创建命名卷
podman volume create rtabmap-data

# 使用命名卷
podman run -v rtabmap-data:/root/.ros ...

# 备份容器
podman export rtabmap-realsense > rtabmap-backup.tar

# 恢复容器
podman import rtabmap-backup.tar

故障排查

问题 1:容器无法访问 RealSense 相机

症状No device connectedPermission denied

解决方案

# 1. 检查设备是否存在
ls -la /dev/video*
lsusb | grep Intel

# 2. 确保使用 --privileged 或正确挂载设备
podman run --privileged ...

# 3. 检查 udev 规则
sudo udevadm control --reload-rules
sudo udevadm trigger

问题 2:GUI 窗口无法显示

症状cannot open displayNo protocol specified

解决方案

# 1. 允许 X11 连接
xhost +local:

# 2. 检查 DISPLAY 变量
echo $DISPLAY

# 3. 确保挂载 X11 socket
-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY

问题 3:ROS 2 节点无法通信

症状ros2 topic list 看不到其他节点的话题

解决方案

# 1. 使用 host 网络模式
--network=host

# 2. 或配置 DDS 发现
-e ROS_DOMAIN_ID=0
-e RMW_IMPLEMENTATION=rmw_fastrtps_cpp

问题 4:容器内存不足

症状Out of memory 或进程被 kill

解决方案

# 限制内存使用
podman run --memory=8g --memory-swap=16g ...

# 或增加系统 swap
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

完整启动脚本示例

#!/bin/bash
# start_rtabmap.sh - RTAB-Map 开发环境启动脚本

CONTAINER_NAME="rtabmap-dev"
IMAGE="docker.io/introlab3it/rtabmap_ros:humble-latest"

# 允许 X11 连接
xhost +local: > /dev/null 2>&1

# 检查容器是否存在
if podman ps -a --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
    echo "容器 ${CONTAINER_NAME} 已存在"
    
    # 检查是否运行中
    if podman ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
        echo "容器正在运行,直接进入..."
    else
        echo "启动容器..."
        podman start ${CONTAINER_NAME}
    fi
    
    # 进入容器
    podman exec -it ${CONTAINER_NAME} bash
else
    echo "创建新容器 ${CONTAINER_NAME}..."
    podman run -it --name ${CONTAINER_NAME} \
        --network=host \
        --privileged \
        -v /dev/bus/usb:/dev/bus/usb \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -e DISPLAY=$DISPLAY \
        -e QT_X11_NO_MITSHM=1 \
        -v $(pwd):/workspace \
        -w /workspace \
        ${IMAGE} \
        bash
fi

使用方法:

chmod +x start_rtabmap.sh
./start_rtabmap.sh

🔗 相关链接

  • [[ROS2 Humble + OpenVINS 源码编译]]
  • [[RealSense D455 语义 SLAM]]
  • [[NixOS 开发环境配置]]
  • [[Docker vs Podman 对比]]

🔄 更新日志

  • 2025-12-22: 创建初始版本,涵盖 Podman 容器管理完整指南

最后更新: 2025-12-22
维护者: Jesse