> 技术文档 > 解决 Ubuntu 上 Docker 安装与网络问题:从禁用 IPv6 到配置代理_docker禁用ipv6

解决 Ubuntu 上 Docker 安装与网络问题:从禁用 IPv6 到配置代理_docker禁用ipv6


解决 Ubuntu 上 Docker 安装与网络问题的实践笔记

在 Ubuntu(Noble 版本)上安装 Docker 时,我遇到了两个常见的网络问题:apt-get update 失败和无法拉取 Docker 镜像。通过逐步排查和配置,最终成功运行 docker run hello-world。这篇笔记整理了我的解决过程,重点讲解了禁用 IPv6为 Docker 守护进程配置代理以及**Docker Daemon 的额外配置(如关闭 IPv6)**的原理与操作,帮助读者理解并复现。适用于遇到网络连接问题、无法更新源或拉取镜像的 Docker 用户,特别是使用中文网络环境的开发者。


🧩 问题背景

我按照 Docker 官方文档 提供的步骤,在 Ubuntu 上安装 Docker。使用的命令如下:

# 更新软件源并安装依赖sudo apt-get updatesudo apt-get install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyrings# 添加 Docker GPG 密钥sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc# 添加 Docker 软件源echo \\ \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \\ $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable\" | \\ sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update# 安装 Dockersudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

安装过程顺利,但运行测试命令时遇到问题:

sudo docker run hello-world

报错如下:

Unable to find image \'hello-world:latest\' locallydocker: Error response from daemon: Get \"https://registry-1.docker.io/v2/\": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

此外,最初运行 sudo apt-get update 时也遇到错误,提示无法连接 Docker 仓库。


📶 问题 1:apt-get update 失败

🔍 现象

运行 sudo apt-get update 时,出现以下错误:

错误:1 https://download.docker.com/linux/ubuntu noble InRelease Could not handshake: Error in the pull function. [IP: 2600:9000:2804:5800:3:db06:4200:93a1 443]W: 无法下载 https://download.docker.com/linux/ubuntu/dists/noble/InRelease

🧠 原因分析

错误信息中的 IP 地址是一个 IPv6 地址,表明系统尝试通过 IPv6 连接 Docker 仓库,但失败了。可能的原因包括:

  • 网络对 IPv6 支持不稳定
  • Docker 仓库的 IPv6 配置问题

🛠️ 解决方案:禁用 IPv6

为了强制系统使用 IPv4,我临时禁用了 IPv6:

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

然后再次运行:

sudo apt-get update

这次更新成功,没有报错。

❓ 为什么禁用 IPv6?

  • IPv6 vs IPv4:IPv6 是下一代互联网协议,但许多网络和服务器对 IPv6 的支持仍不完善。
  • 命令解析
    • sysctl -w net.ipv6.conf.all.disable_ipv6=1:禁用所有网络接口的 IPv6。
    • sysctl -w net.ipv6.conf.default.disable_ipv6=1:为新创建的网络接口禁用 IPv6。
  • 适用场景:如果你的网络环境不支持 IPv6,或者目标服务器的 IPv6 连接不稳定,禁用 IPv6 是快速有效的解决方法。

⚠️ 注意事项

  • 临时性:上述命令仅在当前会话有效。如果需要永久禁用 IPv6,需编辑 /etc/sysctl.conf
    sudo nano /etc/sysctl.conf

    添加:

    net.ipv6.conf.all.disable_ipv6 = 1net.ipv6.conf.default.disable_ipv6 = 1

    保存后应用:

    sudo sysctl -p
  • 风险:禁用 IPv6 可能影响依赖 IPv6 的服务,建议在确认网络环境后使用。

🐳 问题 2:无法拉取 hello-world 镜像

🔍 现象

安装 Docker 后,运行 sudo docker run hello-world 报错:

Unable to find image \'hello-world:latest\' locallydocker: Error response from daemon: Get \"https://registry-1.docker.io/v2/\": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

🧠 原因分析

此错误表明 Docker 无法从 Docker Hub(registry-1.docker.io)拉取镜像,原因是连接超时。进一步排查发现:

  • 我使用了本地代理(http://127.0.0.1:7897),通过以下命令验证:
    curl -v https://registry-1.docker.io/v2/

    输出显示 curl 通过代理成功连接(返回 401 Unauthorized,正常现象,因为需要认证)。

  • 但是,Docker 守护进程(dockerd)并未使用代理,导致无法访问 Docker Hub。

🛠️ 解决方案:为 Docker 守护进程配置代理

✅ 步骤一:创建代理配置文件
sudo mkdir -p /etc/systemd/system/docker.service.dsudo tee /etc/systemd/system/docker.service.d/proxy.conf > /dev/null <<EOF[Service]Environment=\"HTTP_PROXY=http://127.0.0.1:7897\"Environment=\"HTTPS_PROXY=http://127.0.0.1:7897\"Environment=\"NO_PROXY=localhost,127.0.0.1,registry.local,nuclio,*.local,172.17.0.0/16,.docker.internal,docker.io,*.docker.io,docker.com,*.docker.com\"EOF
✅ 步骤二:重新加载并重启 Docker 服务
sudo systemctl daemon-reloadsudo systemctl restart docker
✅ 步骤三:验证是否生效
sudo systemctl status docker

确保状态为 active (running)

sudo docker run hello-world

输出成功,表示 Docker 守护进程已正确使用代理。


🐧 补充:Docker Daemon 配置(可选)

如果你还希望在 Docker Daemon 中禁用 IPv6(不仅限于系统层面),可以添加以下配置:

sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json > /dev/null <<EOF{ \"ipv6\": false}EOF

然后重启 Docker:

sudo systemctl restart docker

这一步并非必须,但有助于确保 Docker 内部网络也避免使用 IPv6,特别是在自定义网络桥接等场景中。

💡 查看当前配置是否生效:

sudo docker info | grep \'IPv6\'

🌐 理解代理配置

  • 为什么单独配置守护进程?
    Docker 守护进程是一个独立运行的后台服务(通过 Systemd 管理),它不读取用户的 shell 环境变量(如 export HTTPS_PROXY)。因此,必须通过 Systemd 配置文件显式设置代理。

  • NO_PROXY 的作用
    NO_PROXY 防止本地通信(如守护进程与客户端之间的通信)被代理拦截。例如,localhost127.0.0.1 是 Docker 客户端与守护进程通信的常用地址,192.168.0.0/16 等内网地址常用于容器网络。

  • 示例解释:哪些地址应加入 NO_PROXY?

    • localhost,127.0.0.1:避免本地通信走代理
    • 172.17.0.0/16:容器默认桥接网络范围
    • .docker.internal:Docker 内部服务域名

✨ 经验总结与建议

  • 📶 禁用 IPv6 的场景

    • 当遇到类似 Could not handshake 的错误,且 IP 地址是 IPv6 时,禁用 IPv6 是快速排查方法。
    • 注意检查网络环境,确认是否需要长期禁用 IPv6。
  • 🌐 代理配置的通用性

    • 如果使用代理,确保客户端和守护进程都配置正确。
    • NO_PROXY 需根据网络环境调整,包含所有本地和内网地址。
  • 🐳 Docker Daemon 配置建议

    • 若网络环境中存在 IPv6 不稳定问题,可在 daemon.json 中显式禁用 IPv6。
    • 可同时配置镜像加速器以提高拉取速度。
  • 🚀 国内用户优化

    • 考虑配置镜像加速器(如阿里云、腾讯云)以提高拉取速度:
      sudo nano /etc/docker/daemon.json

      添加:

      { \"registry-mirrors\": [\"https://mirror.ccs.tencentyun.com\"]}

      重启 Docker:

      sudo systemctl restart docker
  • 👥 权限优化

    • 为避免每次使用 sudo,将用户添加到 docker 组:
      sudo usermod -aG docker $USER

      注销后重新登录即可。

  • 📚 进一步学习

    • 尝试运行复杂容器:docker run -it ubuntu bash
    • 探索 Docker Hub 和官方文档:Docker Getting Started

🙌 结语

这次安装 Docker 的过程让我深入理解了网络配置对 Docker 的影响。禁用 IPv6 解决了软件源更新的问题,而为守护进程配置代理确保了镜像拉取的成功。希望这篇笔记能帮助你在遇到类似问题时快速定位和解决,同时对 Docker 的网络机制有更深的认识!

如果你也在使用 Docker 并遇到了类似问题,欢迎尝试上述方法并留言分享你的经验。你也可以参考官方文档继续深入学习:Docker Getting Started