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

解决 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 InReleaseCould 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.mzph.cn/web/75528.shtml

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

相关文章

指针的进阶2

六、函数指针数组 字符指针数组 - 存放字符指针的数组 char* arr[10] 整型指针数组 - 存放整型指针的数组 int* arr[10] 函数指针数组 - 存放函数指针的数组 void my_strlen() {} int main() {//指针数组char* ch[5];int arr[10] {0};//pa是是数组指针int (*pa)[10] &…

速盾:高防CDN节点对收录有影响吗?

引言 搜索引擎收录是网站运营中至关重要的环节,它直接影响着网站的曝光度和流量。近年来,随着网络安全威胁的增加,许多企业开始采用高防CDN(内容分发网络)来保护其网站免受DDoS攻击和其他形式的网络攻击。然而&#x…

2025蓝桥杯省赛C/C++研究生组游记

前言 至少半年没写算法题了,手生了不少,由于python写太多导致行末老是忘记打分号,printf老是忘记写f,for和if的括号也老是忘写,差点连&&和||都忘记了。 题目都是回忆版本,可能有不准确的地方。 …

Quill富文本编辑器支持自定义字体(包括新旧两个版本,支持Windings 2字体)

文章目录 1 新版(Quill2 以上版本)2 旧版(Quill1版本) 1 新版(Quill2 以上版本) 注意:新版设置 style"font-family: Wingdings 2" 这种带空格的字体样式会被过滤掉,故需特…

dbt:新一代数据转换工具

dbt(Data Build Tool)一款专为数据分析和工程师设计的开源工具,专注于 ETL/ELT 流程的数据转换(Transform)环节,帮助用户以高效、可维护的方式将原始数据转换为适合分析的数据模型。 用户只需要编写查询&am…

【家政平台开发(39)】解锁家政平台测试秘籍:计划与策略全解析

本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…

Java中的Map vs Python字典:核心对比与使用指南

一、核心概念 1. 基本定义 Python字典(dict) :动态类型键值对集合,语法简洁,支持快速查找。Java Map:接口,常用实现类如 HashMap、LinkedHashMap,需声明键值类型(泛型&…

C语言基础之数组

1. 一维数组的创建和初始化 数组的创建 数组是一组相同类型元素的集合。 数组的创建方式: type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n是一个常量表达式,用来指定数组的大小 数组创建的实例: //代码1int arr1[10]; …

虚幻引擎5-Unreal Engine笔记之“将MyStudent变量设置为一个BP_Student的实例”这句话如何理解?

虚幻引擎5-Unreal Engine笔记之“将MyStudent变量设置为一个BP_Student的实例”这句话如何理解? code review! 文章目录 虚幻引擎5-Unreal Engine笔记之“将MyStudent变量设置为一个BP_Student的实例”这句话如何理解?理解这句话的关键点1.类&#xff08…

提示词 (Prompt)

引言 在生成式 AI 应用中,Prompt(提示)是与大型语言模型(LLM)交互的核心输入格式。Prompt 的设计不仅决定了模型理解任务的准确度,还直接影响生成结果的风格、长度、结构与可控性。随着模型能力和应用场景…

十二、C++速通秘籍—静态库,动态库

上一章节: 十一、C速通秘籍—多线程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm1001.2014.3001.5502 本章节代码: cpp2/library CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppst…

什么是继承?js中有哪儿些继承?

1、什么是继承? 继承是面向对象软件技术中的一个概念。 2、js中有哪儿些继承? js中的继承有ES6的类class的继承、原型链继承、构造函数继承、组合继承、寄生组合继承。 2.1 ES6中类的继承 class Parent {constructor() {this.age 18;} }class Chil…

Linux进程通信入门:匿名管道的原理、实现与应用场景

Linux系列 文章目录 Linux系列前言一、进程通信的目的二、进程通信的原理2.1 进程通信是什么2.2 匿名管道通讯的原理 三、进程通讯的使用总结 前言 Linux进程间同通讯(IPC)是多个进程之间交换数据和协调行为的重要机制,是我们学习Linux操作系…

探秘Transformer系列之(26)--- KV Cache优化 之 PD分离or合并

探秘Transformer系列之(26)— KV Cache优化 之 PD分离or合并 文章目录 探秘Transformer系列之(26)--- KV Cache优化 之 PD分离or合并0x00 概述0x01 背景知识1.1 自回归&迭代1.2 KV Cache 0x02 静态批处理2.1 调度策略2.2 问题…

十大PDF解析工具在不同文档类别中的比较研究

PDF解析对于包括文档分类、信息提取和检索在内的多种自然语言处理任务至关重要,尤其是RAG的背景下。尽管存在各种PDF解析工具,但它们在不同文档类型中的有效性仍缺乏充分研究,尤其是超出学术文档范畴。通过使用DocLayNet数据集,比…

HarmonyOS-ArkUI 装饰器V2 @ObservedV2与@Trace装饰器

参考文档: 文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-new-observedv2-and-trace-V14#trace%E8%A3%85%E9%A5%B0%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84由于V2的装饰器比V1的装饰器更加易用,尽管学习的过程中用到的都是V1的装饰器,但…

GPT - GPT(Generative Pre-trained Transformer)模型框架

本节代码主要为实现了一个简化版的 GPT(Generative Pre-trained Transformer)模型。GPT 是一种基于 Transformer 架构的语言生成模型,主要用于生成自然语言文本。 1. 模型结构 初始化部分 class GPT(nn.Module):def __init__(self, vocab…

基于FPGA的六层电梯智能控制系统 矩阵键盘-数码管 上板仿真均验证通过

基于FPGA的六层电梯智能控制系统 前言一、整体方案二、软件设计总结 前言 本设计基于FPGA实现了一个完整的六层电梯智能控制系统,旨在解决传统电梯控制系统在别墅环境中存在的个性化控制不足、响应速度慢等问题。系统采用Verilog HDL语言编程,基于Cyclo…

车载通信系统中基于ISO26262的功能安全与抗辐照协同设计研究

摘要:随着智能网联汽车的快速发展,车载通信系统正面临着功能安全与抗辐照设计的双重挑战。在高可靠性要求的车载应用场景下,如何实现功能安全标准与抗辐照技术的协同优化,构建满足ISO26262安全完整性等级要求的可靠通信架构&#…

Node.js种cluster模块详解

Node.js 中 cluster 模块全部 API 详解 1. 模块属性 const cluster require(cluster);// 1. isMaster // 判断当前进程是否为主进程 console.log(是否为主进程:, cluster.isMaster);// 2. isWorker // 判断当前进程是否为工作进程 console.log(是否为工作进程:, cluster.isW…