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

news2025/4/15 2:41:04

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

在 Ubuntu(Noble 版本)上安装 Docker 时,我遇到了两个常见的网络问题:apt-get update 失败和无法拉取 Docker 镜像。通过逐步排查和配置,最终成功运行 docker run hello-world。这篇笔记整理了我的解决过程,重点讲解了禁用 IPv6为 Docker 守护进程配置代理的原理与操作,帮助读者理解并复现。


问题背景

我按照 Docker 官方文档的 Install using the apt repository 方法,在 Ubuntu 上安装 Docker。使用的命令如下:

# 更新软件源并安装依赖
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings

# 添加 Docker GPG 密钥
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

# 添加 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/null
sudo apt-get update

# 安装 Docker
sudo 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' locally
docker: 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 地址(2600:9000:...)是一个 IPv6 地址,表明系统尝试通过 IPv6 连接 Docker 仓库,但失败了。可能的原因包括:

  • 网络对 IPv6 支持不稳定:某些网络环境(如国内部分运营商)对 IPv6 的支持不完善,导致连接超时或失败。
  • Docker 仓库的 IPv6 配置问题:服务器可能优先返回 IPv6 地址,但实际连接不可靠。

解决方案:禁用 IPv6

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

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

然后再次运行:

sudo apt-get update

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

为什么禁用 IPv6?

  • IPv6 vs IPv4:IPv6 是下一代互联网协议,但许多网络和服务器对 IPv6 的支持仍不完善。如果系统优先尝试 IPv6 连接,而目标服务器的 IPv6 不可靠,就会导致超时或连接失败。
  • 命令解析
    • sysctl -w net.ipv6.conf.all.disable_ipv6=1:禁用所有网络接口的 IPv6。
    • sysctl -w net.ipv6.conf.default.disable_ipv6=1:为新创建的网络接口禁用 IPv6。
    • 这些命令通过修改内核参数(/proc/sys/net/ipv6/conf/...)临时禁用 IPv6,重启后会失效。
  • 适用场景:如果你的网络环境不支持 IPv6,或者目标服务器的 IPv6 连接不稳定,禁用 IPv6 是快速有效的解决方法。

注意事项

  • 临时性:上述命令仅在当前会话有效。如果需要永久禁用 IPv6,需编辑 /etc/sysctl.conf
    sudo nano /etc/sysctl.conf
    
    添加:
    net.ipv6.conf.all.disable_ipv6 = 1
    net.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' locally
docker: 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 守护进程配置代理?

  • Docker 架构:Docker 采用客户端-服务器架构。运行 docker run 时,客户端(docker 命令)与守护进程(dockerd)通信,守护进程负责拉取镜像和运行容器。
  • 环境变量隔离:用户的代理环境变量(HTTP_PROXYHTTPS_PROXY)只对客户端命令生效,守护进程默认不继承这些设置。
  • 网络限制:在国内,Docker Hub 的访问可能因网络限制而失败,代理或镜像加速器是常见解决方案。

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

我通过以下步骤为 Docker 守护进程配置了代理:

  1. 创建代理配置文件

    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
    

    添加以下内容:

    [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,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,::1"
    
    • 解析
      • HTTP_PROXYHTTPS_PROXY:指定代理地址(127.0.0.1:7897 是本地代理服务地址)。
      • NO_PROXY:定义不需要代理的地址范围(如本地地址和常见内网 IP 段),避免本地通信走代理。
      • 文件路径 /etc/systemd/system/docker.service.d/:Systemd 允许为服务添加自定义配置,http-proxy.conf 会覆盖 Docker 的默认服务设置。
  2. 重新加载并重启 Docker

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    • daemon-reload:通知 Systemd 重新加载配置文件。
    • restart docker:重启 Docker 服务以应用新配置。
  3. 验证服务状态

    sudo systemctl status docker
    

    确认服务状态为 active (running)

  4. 测试拉取镜像

    sudo docker run hello-world
    

    这次命令成功运行,输出:

    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    ...
    

理解代理配置

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

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

  • 适用场景
    如果你的网络环境需要代理访问外部资源(如国内访问 Docker Hub),或者企业网络有代理要求,必须为守护进程配置代理。


最终结果

通过禁用 IPv6 和为 Docker 守护进程配置代理,我成功解决了网络问题,docker run hello-world 正常运行。输出表明 Docker 客户端、守护进程和 Docker Hub 的通信都正常。


经验总结与建议

  1. 禁用 IPv6 的场景

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

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

    • 考虑配置镜像加速器(如阿里云、腾讯云)以提高拉取速度:
      sudo nano /etc/docker/daemon.json
      
      添加:
      {
        "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
      }
      
      重启 Docker:
      sudo systemctl restart docker
      
  4. 权限优化

    • 为避免每次使用 sudo,将用户添加到 docker 组:
      sudo usermod -aG docker $USER
      
      注销后重新登录即可。
  5. 进一步学习

    • 尝试运行复杂容器:docker run -it ubuntu bash
    • 探索 Docker Hub 和官方文档:https://docs.docker.com/get-started/。

结语

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


这篇博客简洁明了,涵盖了问题的现象、原因、解决方案以及背后的原理,适合初学者和有一定经验的用户参考。如果你有其他需求(例如添加图片、代码高亮,或调整语气),请告诉我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows for Redis 后台服务运行

下载 redis 安装包 地址:https://github.com/tporadowski/redis/releases 解压zip压缩包,执行 redis-server.exe 即可以窗口模式运行(窗口关闭则服务关闭) 运行窗口可以看到,端口是 6379 我这里使用 nvaicat 客服端测…

C语言超详细指针知识(二)

在上一篇有关指针的博客中,我们介绍了指针的基础知识,如:内存与地址,解引用操作符,野指针等,今天我们将更加深入的学习指针的其他知识。 1.指针的使用和传址调用 1.1strlen的模拟实现 库函数strlen的功能是…

华为机试—最大最小路

题目 对于给定的无向无根树&#xff0c;第 i 个节点上有一个权值 wi​ 。我们定义一条简单路径是好的&#xff0c;当且仅当&#xff1a;路径上的点的点权最小值小于等于 a &#xff0c;路径上的点的点权最大值大于等于 b 。 保证给定的 a<b&#xff0c;你需要计算有多少条简…

[Linux]从零开始的ARM Linux交叉编译与.so文件链接教程

一、前言 最近在项目需要将C版本的opencv集成到原本的代码中从而进行一些简单的图像处理。但是在这其中遇到了一些问题&#xff0c;首先就是原本的opencv我们需要在x86的架构上进行编译然后将其集成到我们的项目中&#xff0c;这里我们到底应该将opencv编译为x86架构的还是编译…

Rag实现流程

Rag实现流程 目录 Rag实现流程1. 加载问答链代码解释`chain_type="stuff"` 的含义其他 `chain_type` 参数选项及特点1. `map_reduce`2. `refine`3. `map_rerank`示例代码展示不同 `chain_type` 的使用其他参数类型2. 提出问题3. 检索相关文档代码解释其他参数类型4. …

【c语言】指针习题

练习一&#xff1a;使用指针打印数组内容 #include <stdio.h> void print(int* p, int sz) {int i 0;for (i 0; i < sz; i) {printf("%d ", *p);//printf("%d ", *(p i));} } int main() {int arr[] { 1,2,3,4,5,6,7,8,9,10 };int sz sizeof…

银行业务知识序言

银行业务知识体系全景解析 第一章 金融创新浪潮下的银行业务知识革命 1.1 数字化转型驱动金融业态重构 在区块链、人工智能、物联网等技术的叠加作用下&#xff0c;全球银行业正经历着"服务无形化、流程智能化、风控穿透化"的深刻变革。根据麦肯锡《2023全球银行业…

智慧水务项目(八)基于Django 5.1 版本PyScada详细安装实战

一、说明 PyScada&#xff0c;一个基于Python和Django框架的开源SCADA&#xff08;数据采集与监视控制系统&#xff09;系统&#xff0c;采用HTML5技术打造人机界面&#xff08;HMI&#xff09;。它兼容多种工业协议&#xff0c;如Modbus TCP/IP、RTU、ASCII等&#xff0c;并具…

畅游Diffusion数字人(23):字节最新表情+动作模仿视频生成DreamActor-M1

畅游Diffusion数字人(0):专栏文章导航 前言:之前有很多动作模仿或者表情模仿的工作,但是如果要在实际使用中进行电影级的复刻工作,仅仅表情或动作模仿还不够,需要表情和动作一起模仿。最近字节跳动提出了一个表情+动作模仿视频生成DreamActor-M1。 目录 贡献概述 核心动…

【Unity网络编程知识】C#的 Http相关类学习

1、搭建HTTP服务器 使用别人做好的HTTP服务器软件&#xff0c;一般作为资源服务器时使用该方式&#xff08;学习阶段建议使用&#xff09;自己编写HTTP服务器应用程序&#xff0c;一般作为Web服务器或者短连接游戏服务器时使用该方式&#xff08;工作后由后端程序员来做&#…

SpringBoot企业级开发之【用户模块-更新用户头像】

功能如下所示&#xff1a; 我们先看一下接口文档&#xff1a; 为什么头像是一串字符串呢&#xff1f;因为我们是将头像图片放到第三方去存储&#xff0c;比如&#xff1a;阿里云等 开发思路&#xff1a; 实操&#xff1a; 1.controller 注意!这里使用【PatchMapping】注解…

DAPP实战篇:使用ethersjs连接智能合约并输入地址查询该地址余额

本系列目录 专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读400次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你…

网络流量管理-流(Flow)

1. 传统网络的问题&#xff1a;快递员送信模式 想象你每天要寄100封信给同一个朋友&#xff0c;传统网络的处理方式就像一个固执的快递员&#xff1a; 每封信都单独处理&#xff1a;检查地址、规划路线、盖章、装车…即使所有信的目的地、收件人都相同&#xff0c;也要重复100…

每日文献(十一)——Part two

今天从第四章&#xff1a;快速RCNN&#xff0c;方法细节开始介绍。 目录 四、快速RCNN&#xff1a;方法细节 4.1 快速R-CNN回顾 4.2 对抗网络设计 4.2.1 遮挡的对抗空间信息损失 4.2.2 对抗空间Transformer网络 4.2.3 对抗融合 五、实验 5.1 实验设置 5.2 PASCAL VOC…

Laravel 实现 队列 发送邮件功能

一. 什么是队列 在构建 Web 应用程序时&#xff0c;你可能需要执行一些任务&#xff0c;例如解析文件&#xff0c;发送邮件&#xff0c;大量的数据计算等等&#xff0c;这些任务在典型的 Web 请求期间需要很长时间才能执行。 庆幸的是&#xff0c;Laravel 可以创建在后台运行…

一、绪论(Introduction of Artificial Intelligence)

写在前面&#xff1a; 老师比较看重的点&#xff1a;对问题的概念本质的理解&#xff0c;不会考试一堆运算的东西&#xff0c;只需要将概念理解清楚就可以&#xff0c;最后一个题会出一个综合题&#xff0c;看潜力&#xff0c;前面的部分考的不是很深&#xff0c;不是很难&…

Web攻防—SSRF服务端请求伪造Gopher伪协议无回显利用

前言 重学Top10的第二篇&#xff0c;希望各位大佬不要见笑。 SSRF原理 SSRF又叫服务端请求伪造&#xff0c;是一种由服务端发起的恶意请求&#xff0c;SSRF发生在应用程序允许攻击者诱使服务器向任意域或资源发送未经授权的请求时。服务器充当代理&#xff0c;执行攻击者构造…

【时时三省】(C语言基础)选择结构程序综合举例

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 下面综合介绍几个包含选择结构的应用程序。 例题1&#xff1a; 写一程序&#xff0c;判断某一年是否为闰年。 程序1&#xff1a; 先画出判别闰年算法的流程图&#xff0c;见下图用变量le…

File 类 (文件|文件夹操作)

一、File 类 1.1 前言 在 JDK 中 通过 java.io.File 类&#xff0c;可以实现操作系统重文件|文件夹的创建、删除、查看、重命名等操作。 1.2 File 类构造方法 File 一共提供了四个构造方法&#xff0c;都是有参构造。其中最常使用的是 File(String) 和 File(String, String)…

Hadoop文件操作指南:深入解析文件操作

1 Hadoop文件系统概述 Hadoop分布式文件系统(HDFS)是Hadoop生态的核心存储组件&#xff0c;专为大规模数据集设计&#xff0c;具有高容错性和高吞吐量特性。 HDFS核心特性: 分布式存储&#xff1a;文件被分割成块(默认128MB)分布存储多副本机制&#xff1a;每个块默认3副本&…