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

使用 Docker 运行 ROS 1 (Noetic) 的完整流程总结
核心目标
在不支持 ROS 1 的 Ubuntu 22.04 系统上,通过 Docker 创建一个隔离的 Ubuntu 20.04 + ROS Noetic 环境,用于 ROS 1 的开发和学习,并确保图形化工具(如 RViz)能够正常使用。
一、一次性准备工作
在启动 Docker 容器之前,需要在你的主系统(Host,即 Ubuntu 22.04)上执行两个准备步骤。
-
拉取正确的 ROS 1 镜像
ROS 1 的官方镜像是托管在osrf/ros仓库下的。这个命令会下载一个包含完整桌面环境(RViz, Gazebo等)的 ROS Noetic 镜像。docker pull osrf/ros:noetic-desktop-full -
授予 Docker 显示图形界面的权限
为了让容器内的程序(如RViz)能在你的主系统桌面上显示窗口,你需要执行以下命令,授权 Docker 连接你的显示服务。这个授权会在重启后失效,每次重启电脑后第一次使用时需要重新运行。xhost +local:docker
二、日常开发工作流(需要两个终端)
这个工作流是你每次开始 ROS 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): 共同作用,用于实现图形界面显示。
-
启动
roscore
命令成功后,你的终端提示符会变为root@...:/#。你现在已经在容器内部了。在这里启动 ROS Master。# 1. 加载 ROS 环境变量 source /opt/ros/noetic/setup.bash # 2. 启动 ROS Master roscore -
保持此终端运行
这个终端现在是 ROS 的核心,不要关闭它。
➡️ 终端 2:执行具体开发任务
-
打开一个新的主系统终端
在你的 Ubuntu 22.04 桌面上打开一个全新的终端窗口。 -
使用
docker exec进入正在运行的容器
这个命令可以让你“进入”到已经在终端 1 中运行的那个容器里。docker exec -it ros_noetic_dev bash -
在容器内工作
你的提示符同样会变为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 参数,这意味着容器关闭后所有改动都会被删除。对于一个需要安装和编译的项目来说,这是不可接受的。
我们需要创建一个不会被自动删除,并且能将数据保存到你主机上的容器。
-
在你的主系统(Host)上创建一个项目文件夹
这个文件夹将存放你所有的代码和数据。# 在你的主目录下创建一个名为 khronos_project 的文件夹 mkdir ~/khronos_project -
用新的
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里,反之亦然。这样,即使容器停止,你的代码和编译结果也会被安全地保存在主机上。
- 我们用
- 与之前的区别:
-
进入你的新容器
容器已经在后台运行了。现在,使用docker exec命令进入它:docker exec -it khronos_dev bash现在,你已经进入了一个为你项目量身定做的、持久化的 ROS 开发环境。接下来的所有安装和编译步骤,都在这个容器内完成。
## 步骤一:在容器内安装 Khronos
现在,我们开始严格按照 README 的指示,在容器内执行命令。
-
安装 catkin 工具
# 在容器内执行 apt update apt install -y python3-catkin-tools python3-vcstool python3-tk(因为在容器内我们已经是 root 用户,所以
sudo可以省略) -
初始化和配置 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 -
安装系统依赖
# 在容器内执行 (同样,将 $ROS_DISTRO 替换为 noetic) apt install -y ros-noetic-gtsam libgoogle-glog-dev nlohmann-json3-dev -
获取 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 -
编译项目
# 在容器内执行 cd /root/catkin_ws catkin build khronos_ros编译过程可能会花费一些时间。如果一切顺利,你的项目就安装好了!
## 步骤二:下载并放置数据集
-
在你的主系统(Host)上下载
打开你主系统的浏览器,将README中提到的数据集(例如tesse_cd_office.bag)下载下来。 -
将数据移动到项目文件夹
将下载好的.bag文件移动到我们之前创建的项目文件夹里。为了方便管理,我们可以在里面再建一个datasets文件夹。# 在你的主系统上执行 mkdir -p ~/khronos_project/datasets mv ~/Downloads/tesse_cd_office.bag ~/khronos_project/datasets/ -
文件自动出现在容器中
由于文件映射,你现在可以在容器的/root/catkin_ws/datasets/目录下看到这个 rosbag 文件了。
## 步骤三:运行示例
-
修改 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。 -
运行 Khronos
# 在容器内执行 roslaunch khronos_ros uhumans2_khronos.launch如果一切配置正确,RVIZ 应该会自动启动,并开始处理 rosbag 数据。
日常使用
- 想继续工作时:
docker start khronos_dev然后docker exec -it khronos_dev bash。 - 想暂停时:在容器内
exit,然后在主机上docker stop khronos_dev。 - 下次开机后:你的容器和所有代码都还在,只需
start和exec即可恢复工作。
建议: 先不要尝试 "Semantic Inference (Optional)" 部分,先把基础的示例成功运行起来,再挑战更复杂的部分。

浙公网安备 33010602011771号