Docker 网络连接故障排查完整指南(含命令)&ubuntu22利用docker安装ROS1

1.初始问题
现象: 在 Ubuntu 系统上,docker run hello-world 命令因网络超时而失败。
核心问题: Docker 服务无法连接外部网络以下载镜像。

2.核心排查过程与关键发现
第一阶段:配置代理 (初步尝试)
目标: 为 Docker 服务本身配置网络代理。
命令: 创建 systemd 配置文件。

Docker 网络连接故障排查完整指南(含命令)

1. 初始问题

  • 现象: 在 Ubuntu 系统上,docker run hello-world 命令因网络超时而失败。
  • 核心问题: Docker 服务无法连接外部网络以下载镜像。

2. 核心排查过程与关键发现

第一阶段:配置代理 (初步尝试)

  • 目标: 为 Docker 服务本身配置网络代理。
  • 命令: 创建 systemd 配置文件。
    # 使用 vim 或其他编辑器创建文件
    sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
    
  • 文件内容 (注意: [proxy_address] 和 [proxy_port] 需替换为实际值, 可用ip a获取):
    [Service]
    Environment="HTTP_PROXY=http://[proxy_address]:[proxy_port]"
    Environment="HTTPS_PROXY=http://[proxy_address]:[proxy_port]"
    Environment="NO_PROXY=localhost,127.0.0.1"
    

第二阶段:验证代理与隔离问题 (关键转折点)

  • 目标: 测试代理本身是否工作正常,并将问题与 Docker 服务本身隔离开。
  • 关键命令: 使用 curl 强制通过代理访问 Docker Hub。
    # 注意替换 [proxy_address] 和 [proxy_port]
    curl --verbose --proxy http://[proxy_address]:[proxy_port] https://registry-1.docker.io/v2/
    
  • 关键发现: curl 命令成功连接,证明代理和网络是通的。问题确认出在 Docker 服务本身

3. 定位根本原因

  • 最终诊断命令: 检查 Docker 服务实际加载的配置信息。
    docker info | grep -i "proxy"
    
  • 根本原因: 该命令没有任何输出,证明 Docker 完全没有加载我们为其创建的所有配置文件。这通常是因为 Docker 是通过 Snap 包安装的,它不使用标准的系统配置路径。

4. 最终解决方案 (完整步骤)

步骤一:彻底卸载所有旧的 Docker 版本

  • 目标: 清理系统中可能存在的 Snap 版或旧的 apt 版 Docker,避免冲突。
  • 命令:
    # 卸载 Snap 版本
    sudo snap remove docker
    
    # 卸载 apt 版本并清理残留
    sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
    sudo apt-get autoremove -y
    sudo rm -rf /var/lib/docker
    sudo rm -rf /var/lib/containerd
    

步骤二:修复 apt 的 IPv6 网络问题

  • 目标: 在安装过程中,apt update 因 IPv6 连接失败。我们强制 apt 使用 IPv4。
  • 命令:
    echo 'Acquire::ForceIPv4 "true";' | sudo tee /etc/apt/apt.conf.d/99force-ipv4
    

步骤三:通过 Docker 官方源正确安装 Docker

  • 目标: 安装一个标准的、会读取正确配置文件的 Docker 版本。
  • 命令:
    # 1. 更新 apt 并安装依赖
    sudo apt-get update
    sudo apt-get install -y ca-certificates curl
    
    # 2. 添加 Docker 的官方 GPG 密钥
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
    
    # 3. 添加 Docker 的官方软件源
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    # 4. 再次更新 apt 并安装 Docker
    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    

步骤四:进行安装后配置

  • 目标: 允许当前用户免 sudo 使用 Docker,并最终应用所有网络配置。
  • 命令:
    # 1. 将用户添加到 docker 组 (需要重新登录或使用 newgrp生效)
    sudo usermod -aG docker $USER
    # (可选,在当前终端立即生效)
    newgrp docker
    
    # 2. 重新创建代理配置文件 (*注意: [your_lan_ip] 和 [proxy_port] 需替换*)
    sudo mkdir -p /etc/systemd/system/docker.service.d/
    sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<EOF
    [Service]
    Environment="HTTP\_PROXY=http://[your\_lan\_ip]:[proxy\_port]"
    Environment="HTTPS\_PROXY=http://[your\_lan\_ip]:[proxy\_port]"
    Environment="NO\_PROXY=localhost,127.0.0.1"
    EOF
    # 3. 重新创建 DNS 配置文件
    sudo tee /etc/docker/daemon.json > /dev/null <<EOF
    {
    "dns": ["8.8.8.8", "1.1.1.1"]
    }
    EOF
    
    
    

步骤五:启动并验证

  • 目标: 以正确的顺序加载所有配置并最终验证成功。
  • 命令:
    # 1. 重新加载 systemd 配置,识别新的代理文件
    sudo systemctl daemon-reload
    
    # 2. 重启 Docker 服务以应用所有新配置
    sudo systemctl restart docker
    
    # 3. 运行最终测试
    docker run hello-world
    

image

使用 Docker 运行 ROS 1 (Noetic) 的完整流程总结

核心目标

在不支持 ROS 1 的 Ubuntu 22.04 系统上,通过 Docker 创建一个隔离的 Ubuntu 20.04 + ROS Noetic 环境,用于 ROS 1 的开发和学习,并确保图形化工具(如 RViz)能够正常使用。

一、一次性准备工作

在启动 Docker 容器之前,需要在你的主系统(Host,即 Ubuntu 22.04)上执行两个准备步骤。

  1. 拉取正确的 ROS 1 镜像
    ROS 1 的官方镜像是托管在 osrf/ros 仓库下的。这个命令会下载一个包含完整桌面环境(RViz, Gazebo等)的 ROS Noetic 镜像。

    docker pull osrf/ros:noetic-desktop-full
    
  2. 授予 Docker 显示图形界面的权限
    为了让容器内的程序(如RViz)能在你的主系统桌面上显示窗口,你需要执行以下命令,授权 Docker 连接你的显示服务。这个授权会在重启后失效,每次重启电脑后第一次使用时需要重新运行。

    xhost +local:docker
    

二、日常开发工作流(需要两个终端)

这个工作流是你每次开始 ROS 1 开发时需要遵循的步骤。

➡️ 终端 1:启动并“住持”容器

  1. 运行 docker run 命令
    这个命令会启动一个全新的 ROS 1 容器。它看起来很长,但每个参数都至关重要。

    docker run -it \
      --name ros_noetic_dev \
      --rm \
      --net=host \
      --env="DISPLAY" \
      --env="QT_X11_NO_MITSHM=1" \
      --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
      osrf/ros:noetic-desktop-full
    
    • --name ros_noetic_dev: 给容器起个名字,方便管理。
    • --rm: 当你退出这个终端时,容器会自动删除,保持系统干净。
    • --net=host: 让容器共享主机的网络,简化 ROS 通信。
    • 其余参数 (--env, --volume): 共同作用,用于实现图形界面显示。
  2. 启动 roscore
    命令成功后,你的终端提示符会变为 root@...:/#。你现在已经在容器内部了。在这里启动 ROS Master。

    # 1. 加载 ROS 环境变量
    source /opt/ros/noetic/setup.bash
    
    # 2. 启动 ROS Master
    roscore
    
  3. 保持此终端运行
    这个终端现在是 ROS 的核心,不要关闭它。

➡️ 终端 2:执行具体开发任务

  1. 打开一个新的主系统终端
    在你的 Ubuntu 22.04 桌面上打开一个全新的终端窗口。

  2. 使用 docker exec 进入正在运行的容器
    这个命令可以让你“进入”到已经在终端 1 中运行的那个容器里。

    docker exec -it ros_noetic_dev bash
    
  3. 在容器内工作
    你的提示符同样会变为 root@...:/#。现在你可以在这个终端里执行所有 ROS 相关的任务了。

    # 1. 同样需要先加载 ROS 环境变量
    source /opt/ros/noetic/setup.bash
    
    # 2. 运行你需要的任何 ROS 命令,例如启动 RViz
    rviz
    
    # 3. 或者运行你自己的 ROS 节点
    # rosrun my_package my_node
    

三、结束工作

  • 当你完成开发后,只需关闭终端 1(或在其中按下 Ctrl+C),roscore 会停止。
  • 因为我们使用了 --rm 参数,容器会自动被删除,不会在你的系统里留下任何垃圾。你的主系统保持了完美的纯净。

这个流程结合了 Docker 的隔离性、ROS 的强大功能以及图形界面的便利性,是现代机器人开发的标准实践之一。

复现Khronos

https://github.com/MIT-SPARK/Khronos
你提供的 README 文件是为常规 Linux 系统编写的,我们需要把它“翻译”成在我们的 Docker 环境中执行的步骤。核心思路是:

  • 系统和软件的安装在容器内部完成。
  • 代码和数据集的管理通过主机和容器之间的文件共享来完成,这样更灵活,且数据不会丢失。

下面,我将为你分解这个过程。


## 准备工作:创建一个“持久化”的开发容器

我们之前用于测试的 docker run 命令包含 --rm 参数,这意味着容器关闭后所有改动都会被删除。对于一个需要安装和编译的项目来说,这是不可接受的。

我们需要创建一个不会被自动删除,并且能将数据保存到你主机上的容器。

  1. 在你的主系统(Host)上创建一个项目文件夹
    这个文件夹将存放你所有的代码和数据。

    # 在你的主目录下创建一个名为 khronos_project 的文件夹
    mkdir ~/khronos_project
    
  2. 用新的 docker run 命令启动一个持久化的容器
    这个命令我们只在第一次创建容器时使用。

    docker run -itd \
      --name khronos_dev \
      -v ~/khronos_project:/root/catkin_ws \
      --net=host \
      --env="DISPLAY" \
      --env="QT_X11_NO_MITSHM=1" \
      --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
      osrf/ros:noetic-desktop-full
    
    • 与之前的区别:
      • 我们用 -itd 代替了 -it-d 表示在后台运行(detached)。
      • --name 改为了 khronos_dev,一个专门用于本项目的名字。
      • 最重要的: 我们去掉了 --rm 并增加了 -v ~/khronos_project:/root/catkin_ws
        • -v 是 volume mount(卷挂载)的缩写。
        • 这句话的意思是:把你主系统上的 ~/khronos_project 文件夹 映射 到容器内部的 /root/catkin_ws 文件夹。
        • 效果: 你在主机 ~/khronos_project 里做的任何文件修改,会立即出现在容器的 /root/catkin_ws 里,反之亦然。这样,即使容器停止,你的代码和编译结果也会被安全地保存在主机上。
  3. 进入你的新容器
    容器已经在后台运行了。现在,使用 docker exec 命令进入它:

    docker exec -it khronos_dev bash
    

    现在,你已经进入了一个为你项目量身定做的、持久化的 ROS 开发环境。接下来的所有安装和编译步骤,都在这个容器内完成。


## 步骤一:在容器内安装 Khronos

现在,我们开始严格按照 README 的指示,在容器内执行命令。

  1. 安装 catkin 工具

    # 在容器内执行
    apt update
    apt install -y python3-catkin-tools python3-vcstool python3-tk
    

    (因为在容器内我们已经是 root 用户,所以 sudo 可以省略)

  2. 初始化和配置 catkin 工作区
    我们的工作区就是 /root/catkin_ws

    # 在容器内执行
    cd /root/catkin_ws
    catkin init
    # 将 $ROS_DISTRO 替换为 noetic
    catkin config --extend /opt/ros/noetic
    catkin config --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo -DKIMERA_VERIFY_GTSAM_CONFIG=OFF -DOPENGV_BUILD_WITH_MARCH_NATIVE=OFF
    catkin config --merge-devel
    
  3. 安装系统依赖

    # 在容器内执行 (同样,将 $ROS_DISTRO 替换为 noetic)
    apt install -y ros-noetic-gtsam libgoogle-glog-dev nlohmann-json3-dev
    
  4. 获取 Khronos 源码
    README 建议没有 SSH 密钥的用户使用 https.rosinstall,这是更简单的方法。

    # 在容器内执行
    # 首先进入 src 目录
    mkdir -p /root/catkin_ws/src
    cd /root/catkin_ws/src
    
    # 使用 HTTPS 克隆主仓库
    git clone https://github.com/MIT-SPARK/Khronos.git khronos
    
    # 使用 vcs 和 https.rosinstall 文件导入所有依赖的源码
    vcs import . < khronos/install/https.rosinstall
    
  5. 编译项目

    # 在容器内执行
    cd /root/catkin_ws
    catkin build khronos_ros
    

    编译过程可能会花费一些时间。如果一切顺利,你的项目就安装好了!


## 步骤二:下载并放置数据集

  1. 在你的主系统(Host)上下载
    打开你主系统的浏览器,将 README 中提到的数据集(例如 tesse_cd_office.bag)下载下来。

  2. 将数据移动到项目文件夹
    将下载好的 .bag 文件移动到我们之前创建的项目文件夹里。为了方便管理,我们可以在里面再建一个 datasets 文件夹。

    # 在你的主系统上执行
    mkdir -p ~/khronos_project/datasets
    mv ~/Downloads/tesse_cd_office.bag ~/khronos_project/datasets/
    
  3. 文件自动出现在容器中
    由于文件映射,你现在可以在容器的 /root/catkin_ws/datasets/ 目录下看到这个 rosbag 文件了。


## 步骤三:运行示例

  1. 修改 launch 文件
    README 要求修改 launch 文件中的 rosbag 路径。

    # 在容器内执行
    # 首先加载工作区环境,这非常重要!
    source /root/catkin_ws/devel/setup.bash
    
    # 使用 vim 或 nano 编辑 launch 文件
    vim src/khronos/khronos_ros/launch/uhumans2_khronos.launch
    

    在文件中找到 rosbag 的路径,并将其修改为它在容器内的绝对路径/root/catkin_ws/datasets/tesse_cd_office.bag

  2. 运行 Khronos

    # 在容器内执行
    roslaunch khronos_ros uhumans2_khronos.launch
    

    如果一切配置正确,RVIZ 应该会自动启动,并开始处理 rosbag 数据。


日常使用

  • 想继续工作时docker start khronos_dev 然后 docker exec -it khronos_dev bash
  • 想暂停时:在容器内 exit,然后在主机上 docker stop khronos_dev
  • 下次开机后:你的容器和所有代码都还在,只需 startexec 即可恢复工作。

建议: 先不要尝试 "Semantic Inference (Optional)" 部分,先把基础的示例成功运行起来,再挑战更复杂的部分。

posted @ 2025-08-27 14:28  asandstar  阅读(228)  评论(0)    收藏  举报