ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu apt update 报 Failed to fetch 换源修复

Ubuntu apt update 报 Failed to fetch 换源修复 Ubuntu 上用apt update的时候撞到E: Failed to fetch http://mirrors.cloud.aliyuncs.com这行红字的人绝大多数都不是把系统搞坏了而是手里这台机器的软件源地址“认错了门牌号”。这个报错最典型的样子是更新列表跑到一半卡住刷出一串红字最后告诉你有些源拿不到索引文件apt install也跟着失败。它常出现在从云主机镜像导出的虚拟机里也出现在 VMware、VirtualBox、双系统这类自己动手装的 Ubuntu 上。下面我把这条报错从根上拆开讲域名到底是谁、为什么只有你这里解析不了、三种不同思路的修法、以及一套可以直接照着敲的完整实操流程。不管你是刚装完 Ubuntu 24.04 的新手还是手里管着几十台机器的运维都能找到对应自己场景的那一段。1. 这条报错的真实含义与排查地图1.1 逐行拆解 apt update 到底在干什么要把这事说清楚先得知道apt update背后干了哪些活。它其实是一套固定流程读取/etc/apt/sources.list以及/etc/apt/sources.list.d/目录下的所有源文件逐条拼出形如http://域名/ubuntu/dists/版本代号/InRelease的完整 URL然后挨个发起 HTTP 请求把索引文件下载到本地的/var/lib/apt/lists/缓存目录里最后做签名校验。所以一笔 apache 请求只要在“解析域名 → 建立连接 → 拿到文件 → 校验签名”这四步里任何一步失败你都会看到E: Failed to fetch。关键在于这个报错本身只说“取不到”它并不会替你定位是哪一步出的问题。同一句 Failed to fetch底下的附加说明才是真凶写Could not resolve xxx是域名解析阶段就挂了写Connection timed out是能解析但连不上写404 Not Found是地址拼错了或者版本代号写错了写NO_PUBKEY或Release file is not valid yet那就是走到了最后一步验签才翻车。看报错先看尾巴别只看开头的红色这是我踩过不少次坑之后总结出来的第一原则。1.2 mirrors.cloud.aliyuncs.com 到底是什么来头mirrors.cloud.aliyuncs.com这个域名是给特定环境准备的软件源地址属于内网专用。它的特点是只有在对应环境内部的网络里才能被正常解析和访问一旦你把系统搬到别的网络比如家里的宽带、公司的办公网、本地 VMware 虚拟机的 NAT 网络它就没法正常解析了请求自然也就发不出去。那为什么会有一大堆镜像、快照默认写着这个地址呢原因很实在在内网环境里走这个地址流量不出内网速度快、也不用额外花钱所以做好的标准系统镜像默认就把它设成了软件源。如果你是从别人那里拷贝了一份云主机系统镜像或者拿了一个云厂商直接导出的.img文件装进本地虚拟机那这套内网源就会原封不动地跟着系统一起搬过来——但它只在原产地的网络里才“认识路”搬出去以后就成了坏地址这正是绝大多数人第一步apt update就翻车的原因。1.3 哪些场景最容易撞上这个错把这个错按场景分个类你对号入座会更快。第一种本地虚拟机里装了从云上导出的镜像VMware、VirtualBox、Hyper-V 都算这是出现频率最高的一类。第二种双系统安装很多人下载的 Ubuntu 镜像本身就是别人处理过的定制版源地址没改回公共站。第三种在公司内网跑 Ubuntu网络只放行了白名单里的域名这个内网域名不在名单里于是解析不了。第四种用 WSL 导入别人的 rootfs 压缩包同样会把原环境的源配置带进来。第五种自己从某处克隆的系统盘原机在特定内网环境里克隆到本地后源地址不匹配。这五种的共同点是系统本身完全健康坏的只是那一行源地址。所以你不需要重装系统也不需要怀疑硬件改一个字符串就能解决。2. 动手之前五分钟完成分层定位2.1 一句话判断是网络层还是配置层遇到这类问题最忌讳的就是一头扎进去乱改文件。正确做法是先分层把问题钉死在哪一层。判断逻辑很简单如果这台机器本来就该在能访问内网源的网络里那先怀疑网络如果这台机器明显不在那个网络环境里比如你家客厅的台式机那基本可以直接判定是配置层的源地址不对不用再浪费时间测网络。再具体一点打开终端敲cat /etc/apt/sources.list看看里面有没有那个内网域名。如果有而且你人不在对应的内网环境里答案就已经出来了源地址要换。这一步花不到十秒却能帮你省掉后面一堆瞎折腾。很多人绕远路就是跳过了这一步先去查 DNS、查路由、查网卡最后才发现是源文件里写着一个根本不该出现的域名。2.2 用 ping、getent、curl 把问题钉死判断完配置层如果想确认网络侧的细节三条命令就够了。第一条getent hosts mirrors.cloud.aliyuncs.com它比nslookup、dig更贴近系统实际使用的解析方式因为它走的是系统的名称服务配置链本地的 hosts 文件、各种解析服务都会算进去。如果这条命令没有任何输出说明解析阶段就断了属于典型的域名不通。第二条ping -c 3 mirrors.aliyun.com用来确认你能正常访问公共镜像站的网络。第三条curl -I http://mirrors.aliyun.com/ubuntu/dists/jammy/InRelease这一步直接模拟 apt 的请求把请求头打出来。如果 curl 能返回HTTP/1.1 200 OK说明网络和目标站都正常那么换成正确地址后 apt 就一定能好如果 curl 报Could not resolve或者卡住那就是网络层出了问题得先解决上网再说。getent hosts mirrors.cloud.aliyuncs.com ping -c 3 mirrors.aliyun.com curl -I http://mirrors.aliyun.com/ubuntu/dists/jammy/InRelease我把这三条命令叫做“十秒体检”跑一遍基本就能定性。省下的是你后面反复apt update却始终不知道问题在哪的时间。2.3 解析失败和连接超时是两回事这里要单独拎出来讲一个细节因为很多人会把它们混为一谈。Could not resolve意思是域名到 IP 这一步就没成请求压根没发出去Connection timed out意思是域名解析成功了IP 也拿到了但连不上对方端口请求发出去了没回音。这两种情况的处理方向完全不同前者要么改源地址、要么检查本机解析配置后者要检查防火墙、路由、目标地址是否可达。还有一种隐藏更深的坑某些企业网络会用内网解析服务把不存在的域名统一指到一个内部 IP 上。这种时候你 ping 那个域名居然能通但 curl 过去返回 404 或者连接被拒绝特别有迷惑性。之前有个朋友排查了一下午就是被这个“能 ping 通却用不了”的现象带偏了。记住能 ping 通不代表能用一定要用 curl 实际请求一下索引文件才算数。3. 三套修复方案从应急到根治3.1 应急方案只替换这一个域名如果你现在就要装某个软件没时间深究那就用最小改动方案只把源文件里那一个内网域名替换成公共镜像站的域名其余原样不动。这种改法风险最低改动面最小出问题也好回退。sudo sed -i.bak s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g /etc/apt/sources.list sudo apt update这个方案的优点很明显一条命令搞定还顺手生成了.bak备份。注意 sed 的替换分隔符我用的是竖线|而不是默认的斜杠/因为原字符串里带着斜杠用斜杠当分隔符会导致语法解析混乱这是个细节但很容易踩。这个方案适用于应急也适用于你只想快速把环境跑起来、不打算深究的场景。3.2 常规方案整体切换到公共镜像如果你不赶时间我建议顺势把整套软件源统一换成公共镜像站顺手挑一个离你网络近、速度好的。常见的公共镜像站各有特点我把对比整理成表方便你按需选。镜像站源地址前缀特点适合场景阿里云公共源http://mirrors.aliyun.com/ubuntu/节点多全国速度均衡家庭宽带、常规云主机清华源https://mirrors.tuna.tsinghua.edu.cn/ubuntu/教育网内速度极快校园网、科研机构中科大源https://mirrors.ustc.edu.cn/ubuntu/稳定同步及时通用备选官方源http://archive.ubuntu.com/ubuntu/全球通用速度慢国外网络环境选源的核心逻辑是“就近原则”镜像站和你之间的网络跳数越少、运营商链路越短速度就越快。不要迷信某一个站实测才是硬道理同一台机器换个源下载速度可能差好几倍。切换时记得保留备份方便随时回滚。3.3 特殊方案留在内网环境里的正规做法如果你确实是在对应内网环境里使用这个源那这个地址本身没问题不用改。这种情况下报错通常是别的原因比如安全组或网络规则没放行、系统时间和实际时间偏差太大导致索引验证失败、或者内网 DNS 一时抽风。这种场景下我一般先跑sudo timedatectl status看时间同步是否开启再确认网络规则是否放行了对内网镜像的访问。还有一个常被忽略的点如果内网镜像站临时在做同步索引文件可能短暂不可用等几分钟再apt update往往就好了。不要一看到报错就立刻大改配置先确认是不是临时抖动。4. 手把手实操换源全过程与格式差异4.1 老格式 sources.list 的改法Ubuntu 22.04 及更早版本软件源用的是单行格式写在/etc/apt/sources.list里每一行长这样deb http://mirrors.cloud.aliyuncs.com/ubuntu/ jammy main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ jammy-updates main restricted universe multiverse deb http://mirrors.cloud.aliyuncs.com/ubuntu/ jammy-security main restricted universe multiverse改的时候先备份再替换顺序不能反。备份这一步千万别省改错了能一键回滚sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak.$(date %F) sudo sed -i s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g /etc/apt/sources.list sudo apt update$(date %F)这一段会在备份文件名里带上当天日期方便你日后区分不同时间点的备份。判断有没有改成功直接grep aliyun /etc/apt/sources.list看一眼就知道了。4.2 新格式 ubuntu.sources 的改法Ubuntu 24.04 换了一套软件源格式叫 deb822文件位置变成了/etc/apt/sources.list.d/ubuntu.sources内容长这样Types: deb URIs: http://mirrors.cloud.aliyuncs.com/ubuntu/ Suites: noble noble-updates noble-backports Components: main restricted universe multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg改法和老格式一样还是替换域名只是路径变了sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak.$(date %F) sudo sed -i s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g /etc/apt/sources.list.d/ubuntu.sources sudo apt update很多人踩的坑就在这里在 24.04 上照着老教程改/etc/apt/sources.list改完发现一点效果没有因为系统根本不读那个文件了。判断当前系统用哪套格式最简单的办法就是两条路径都cat一下看哪个文件里真的有源配置。4.3 sources.list.d 里还藏着别的源改完主源别急着收工/etc/apt/sources.list.d/这个目录里往往还躺着别的软件源比如 Docker、显卡驱动、某编程语言的官方源等等它们也可能用了奇怪的域名。用一条命令把整个目录和主文件扫一遍能一次找干净grep -rn aliyuncs\|cloud /etc/apt/sources.list /etc/apt/sources.list.d/有输出就说明还有地方没改干净。这个动作很有必要因为只要有一个源地址不通apt update就会报错哪怕其他几十个源都是好的。一次改干净比反复调试省事得多。我之前就因为漏了 Docker 那个源白折腾了半小时。4.4 清理缓存并验证结果源改完了还有最后一步容易被忽略清缓存。因为之前失败的请求可能在/var/lib/apt/lists/里留下了残缺的索引文件不清掉的话apt 可能会用旧数据报出一些让人看不懂的错。sudo apt clean sudo rm -rf /var/lib/apt/lists/* sudo apt updateapt clean清的是下载的包缓存rm -rf /var/lib/apt/lists/*清的是索引缓存。清完之后重新apt update如果一路绿字跑完、最后没有红字报错那就彻底修好了。如果还有零星报错回到第 2 节的分层排查把没清干净的那个源单独揪出来。5. 常见问题速查与踩坑记录5.1 报错对照速查表我把这类问题常见的报错和对应处理整理成表遇到对不上号的情况先来这张表里查一遍命中率很高。报错关键词含义处理方向Could not resolve域名解析失败换源地址或检查网络解析配置Connection timed out能解析但连不上检查网络规则、路由、目标可达性404 Not Found路径或版本代号错核对 Ubuntu 版本代号是否写对NO_PUBKEY缺少签名公钥导入对应镜像站的公钥Release file is not valid yet系统时间偏差过大开启时间自动同步Temporary failure resolving临时解析故障检查网络解析服务稍后重试这张表的价值在于它让你不用记那么多细节看到报错尾巴就能直接跳到对应处理动作特别适合赶时间排障的时候用。5.2 几个反复踩的坑第一个坑用 sed 全局替换时误伤注释行。源文件里可能有被注释掉的备用地址全局替换会把它们也改了虽然不影响功能但会让文件变得混乱。稳妥做法是替换后grep扫一遍确认改动符合预期。第二个坑只改了主源文件忘了sources.list.d目录。前面讲过这是最常见的遗漏点。第三个坑版本代号写错。每个 Ubuntu 版本有固定代号22.04 是jammy24.04 是noble20.04 是focal。写错了就是 404apt update会告诉你找不到某个路径。不确定的话用lsb_release -cs直接查出来。第四个坑系统时间不同步导致验证失败。这个问题很隐蔽因为网络明明是通的但 apt 就是报索引文件无效。解决办法是开启时间自动同步让系统时间保持准确。提示改源之前一定先备份改完之后一定用 grep 复核这两步是省钱省时间的关键。5.3 一键换源脚本与长期维护建议如果你经常要处理这类问题比如手头有一批机器要批量处理可以写个小脚本一次搞定不再手动敲#!/bin/bash OLDmirrors.cloud.aliyuncs.com NEWmirrors.aliyun.com STAMP$(date %F) for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do [ -f $f ] || continue cp $f $f.bak.$STAMP sed -i s|$OLD|$NEW|g $f echo 已处理: $f done apt clean rm -rf /var/lib/apt/lists/* apt update脚本的逻辑很直白遍历所有可能的源文件逐个备份、替换、打印处理结果最后清缓存并更新。[ -f $f ] || continue这一行是为了跳过不存在的文件避免报错。这类脚本我建议放在自己的工具箱里不一定要提交到公共仓库因为每个人的镜像站选择不一样。长期来看还有几个习惯值得养成一是新装系统后第一件事就是检查源地址是否匹配当前网络环境二是保持系统时间自动同步开启三是定期清理 apt 缓存避免索引文件越积越多四是如果换了网络环境比如从公司带回家顺手确认一下源地址是否还适用。这些动作都很小但能让你少遇到很多莫名其妙的报错。最后再分享一个我自己的习惯遇到这类报错先在纸上或脑子里列出“配置、网络、时间、签名”这四个可能的方向然后从最可疑的那个开始查一次只改一个变量改完立刻验证。这样排查效率最高也最不容易把好端端的系统改坏。别一上来就大改特改那才是真正让人头疼的开始。
返回列表