我们搞运维的,最烦的就是给一堆机器装环境的时候走公网,要么慢得要死,要么干脆断网没法装。Ubuntu 18.04系统到现在还有不少老项目在用,如果你手头刚好有几十台机器要按同样的软件包列表部署,与其一台台去apt update蹭外网,不如花一小时在自己的内网服务器上搭一个本地Mirror源,一劳永逸。这篇文章就完整记录我自建Ubuntu 18.04本地镜像源的整个过程,包括工具选型、配置细节、坑点排查和客户端切换方式,直接照着抄就能落地。
1. 自建本地Mirror源的价值与适用场景
1.1 到底解决什么问题
本地Mirror源说白了,就是在你自己的内网服务器上放一份Ubuntu官方软件仓库的完整副本,然后把所有需要装软件的内网机器都指向这台服务器。这样做最直接的好处有三个:
第一,速度碾压公网。局域网内千兆网络下,apt下载软件包的速度基本能跑满磁盘和网卡的瓶颈,比从外网拉包快几个数量级。我们曾经内部测试,同样一个一百多MB的软件包,外网高峰期可能要等5到10分钟,走内网源3秒就完了,完全不是一个体验。
第二,不依赖外部网络。很多单位的机房是物理隔离的,或者对外带宽极小,没有本地源的话,批量装系统、装软件的日子就是灾难。有了本地源,断外网也能正常装软件、打补丁。
第三,软件版本可控。对于生产环境来说,最怕的就是上游仓库里的包版本更新了,导致大规模升级后出现兼容性问题。自建镜像后,你可以选择不更新、延迟更新或者只同步安全更新,把这批机器的软件版本完全锁死在你验证过的状态。
1.2 哪些人需要这个方案
如果你属于下面这几类情况之一,这个方案就是为你准备的:
- 管理着超过5台的Ubuntu 18.04服务器,尤其是需要定期重装、批量部署的场景。
- 工作环境是内网离线的,但又有安装软件包、更新依赖的需求。
- 你需要固定软件版本做测试或生产交付,不希望开发环境跑着跑着依赖变了。
- 想折腾一下Linux下常用基础服务的搭建,把它当成练手项目也不错。
当然也要泼盆冷水:如果你只有一两台机器,而且外网速度还不错,那没必要搭Mirror源,直接apt install就完事了。本地镜像源需要消耗一定的磁盘空间、维护精力,对于小规模场景属于过度设计。我们实际装机时对Ubuntu 18.04的amd64架构做了一个完整同步,主仓库加更新仓库加安全更新仓库加起来差不多100GB左右,如果再加上universe组件,体积会更大。所以动手之前先确认一下你的服务器磁盘是否够用。
2. 方案选型:为什么我选了apt-mirror
2.1 常见的三种自建方案对比
搭本地源的技术路线不止一条,我自己这几种都试过,分别说下感受,方便你按需选择。
方案一:apt-mirror这是一个老牌工具,通过配置文件指定要同步的仓库地址和组件,然后一条命令就把整个仓库镜像到本地。它最大的优点就是简单直接,配置文件写明白,跑起来就完事,后期用cron定时同步就行。缺点是同步效率一般,而且它是基于Perl的,有些环境可能需要解决依赖问题。我最终选的就是它,理由后面细说。
方案二:debmirror工具本身跟apt-mirror功能类似,但它在做增量同步、删除无用包方面更专业一些。它的配置方式比较复杂,命令行参数多,上手成本高。如果你需要做大规模、多架构、多发行版的镜像站,debmirror更合适。
方案三:rsync直接同步Ubuntu官方仓库这是最"裸"的方式,直接拿rsync去拉Ubuntu官方镜像站的目录结构。好处是同步结果跟官方一模一样,坏处是你要自己把仓库目录结构研究明白,而且官方rsync放开了限速,同步一次要跑很久很久。我之前试过一次,好几T的仓库全量同步,跑了3天没跑完,后来果断放弃。
提示:说实话,对于绝大多数中小规模场景,apt-mirror就是最合适的选择。你不需要理解Ubuntu仓库的复杂目录规则,也不需要折腾rsync的过滤器规则,把源列表配置好就完事。把复杂的事情交给成熟工具,把精力留给真正重要的业务,这个原则在运维里不吃亏。
2.2 apt-mirror的核心工作流程
apt-mirror的运行机制其实没那么神秘:它读取一个配置文件,里面描述了需要镜像哪些仓库、哪些组件、哪些架构,然后它会先下载仓库根目录的索引文件(Packages.gz、Sources.gz这些),解析之后得到一份完整的软件包清单,再按照这份清单逐个下载缺失的deb包文件。
这个"先拉索引、再拉数据"的流程有个好处:它不会盲目下载整个仓库,而是只下载你指定范围内的包。比如你只想同步amd64的main和restricted组件,那配置文件里写好,它就会通过索引过滤,帮你跳过i386的包,跳过universe的大量源码包。这就是为什么100GB左右的体积基本上是个合理的基线,如果你全组件全架构同步,那个体积轻松翻好几倍。
另外,apt-mirror还有一个关键特性是增量同步。它会在本地保留一个之前同步的状态记录,第二次运行的时候,只需要对比索引文件就能知道哪些包是新增的、哪些包更新了版本,然后只拉有变化的部分。这个机制能大幅节省带宽和同步时间,我后面配置定时任务的时候也依赖这个特性。
2.3 工具安装前的准备工作
在正式安装apt-mirror之前,我建议先把下面这些基础工作做掉,省得后面抓瞎。
确认磁盘空间Ubuntu 18.04的amd64架构,只同步main、restricted、universe这三个组件的二进制包,实测需要60~120GB,取决于你选择了哪些仓库(发行版主仓、更新仓、安全更新仓)。如果你把extra组件、i386架构、源码包也全拉下来,那至少要准备300GB以上的空间。我的建议是最低预留150GB,毕竟磁盘还得留出余量给操作系统和其他服务。
确认网络带宽与稳定性首次全量同步的数据量在几十GB量级,如果你的外网带宽只有几MB,那很可能要跑好几个小时甚至一整天。这个过程最怕断线,不过apt-mirror支持断点续传,中断后重新执行会跳过已下载的文件,这点倒是很省心。
准备一个独立的同步目录我习惯上把镜像数据跟系统盘分开,挂在独立的数据盘上,路径用起来也清晰。比如我这边是:
sudo mkdir -p /data/mirror sudo chmod -R 755 /data/mirror注意:不要用
/var/www/html下面直接挂一个大目录,虽然技术上没问题,但web服务跟数据混在一起,后续维护和扩展都不方便。而且镜像数据本身对权限要求不复杂,755就够了。
准备工作做完,接下来就是实际安装了。
3. 完整部署步骤:从安装到首次全量同步
3.1 安装apt-mirror与必要依赖
Ubuntu 18.04可以直接从系统仓库里装上apt-mirror,命令很简单:
sudo apt update sudo apt install -y apt-mirror装完之后,验证一下版本:
apt-mirror --version我环境中装出来的版本是0.5.4,这个版本比较老了,但是从功能上看完全够用。如果你遇到依赖问题,比如缺了Perl模块,可以执行下面的命令把常用依赖模块补上:
sudo apt install -y perl libcpan-mirror-perl libwww-perl这个步骤不是必须的,很多干净的系统上直接装apt-mirror就能跑,我是因为环境里之前精简过Perl,报过模块缺失的错误,所以习惯性把依赖补牢。
装好之后,默认会生成配置文件/etc/apt/mirror.list和同步脚本/usr/bin/apt-mirror。配置文件的默认读写权限是644,修改的时候需要加sudo。
3.2 配置mirror.list:关键参数逐行说明
这个文件是整个方案的核心,把配置逻辑搞明白,后面的操作就顺理成章了。我先把最终使用的配置贴出来,然后逐行拆解。
sudo vim /etc/apt/mirror.list配置内容如下:
#### 基础配置 #### ############# config ################## set base_path /data/mirror set mirror_path $base_path/mirror set skel_path $base_path/skel set var_path $base_path/var set postmirror_script $var_path/clean.sh set nthreads 20 set _tilde 0 ############# end config ############## #### 仓库源配置 #### deb-amd64 http://archive.ubuntu.com/ubuntu bionic main restricted universe multiverse deb-amd64 http://archive.ubuntu.com/ubuntu bionic-updates main restricted universe multiverse deb-amd64 http://archive.ubuntu.com/ubuntu bionic-security main restricted universe multiverse deb-src http://archive.ubuntu.com/ubuntu bionic main restricted universe multiverse #### 清理脚本配置 #### clean http://archive.ubuntu.com/ubuntu bionic clean http://archive.ubuntu.com/ubuntu bionic-updates clean http://archive.ubuntu.com/ubuntu bionic-security下面逐个解释这些配置的含义。
set base_path这个指定的是镜像数据的根目录,你可以改成任何你有足够空间的路径。我这里用的是前面建好的/data/mirror。
set mirror_path / skel_path / var_path这三个是apt-mirror内部使用的子目录:
mirror_path:存放实际镜像下来的软件包文件,整个仓库体积的大头都在这里。skel_path:存放从仓库索引里生成的目录结构模板,就是那些二进制包对应的索引信息。var_path:存放同步过程中的状态文件、日志文件和脚本,包括后面要用的clean脚本也放在这。
这三个路径一般用默认的子目录结构就行,不需要改,只要base_path正确,它们都会自动创建。
set postmirror_script这是同步完成后自动执行的清理脚本路径。它的作用是把本地已经不存在于上游仓库的旧包删掉,防止镜像目录无限膨胀。这个脚本通常由apt-mirror在首次同步时自动生成到$var_path下,你需要确认它存在并有执行权限。后面我会单独讲这个清理机制。
set nthreads 2018.04自带的版本默认线程数是10,我调到20。这是并发下载线程数,如果你的服务器CPU核数多、带宽大,可以再调高一些。但注意,线程数过高可能导致源站把你拉黑,悠着点来。
set _tilde 0这个参数控制是否启用来宾用户组支持,普通使用场景直接设为0即可。
deb-amd64 vs deb仓库源配置这里有几个容易踩坑的细节。deb-amd64表示只同步64位架构的二进制包,deb-i386同理。如果你直接写deb,不指定架构,默认只会同步当前机器架构的包。对于需要多架构的场景,必须显式写多个deb-架构名。
关于Ubuntu 18.04的仓库代号Ubuntu 18.04的仓库代号是bionic,老版本系统这个绝对不能写错。它有四个组件:main、restricted、universe、multiverse,其中main和restricted是官方维护的核心组件,universe是社区维护的,multiverse包含版权受限的软件。绝大多数场景下,前三个就够了,multiverse的内容很多不常用,所以我配置里把它带上但你自己按需取舍。
deb-src这是源码包仓库。如果你不搞开发、不编deb包,其实可以不需要同步源码包。我这边是保留着,因为它对排查一些编译类问题有帮助,代价是额外占用一些磁盘。
clean指令配置末尾的clean指令用于标记哪些仓库路径需要做清理。注意它不直接执行清理动作,而是告诉apt-mirror在同步完成后,基于该仓库路径下的索引对比,把本地已经不在上游的包清掉。这个配置必须跟上面的仓库配置一一对应,否则可能出现清理不完整的情况。
3.3 首次全量同步:实测记录与耗时分析
配置写完之后,就可以开始第一次全量同步了。我习惯用nohup挂在后台跑,避免SSH断开会话导致同步中断。
sudo nohup apt-mirror > /var/log/apt-mirror.log 2>&1 &想实时看进度的话,直接看日志尾部:
sudo tail -f /var/log/apt-mirror.log我这边清理完的首次同步耗时大约45分钟到1小时,同步下来的总数据量在85GB左右。这个数据是建立在外网带宽有100Mbps的基础上,如果你的带宽更小,时间会成倍增加。
同步完成后,日志末尾会出现类似这样的输出:
Proceed indexes [Y/n] ... Y ... Generated 5100 indexes in 332 seconds这表示索引处理完毕。同步完之后,验证一下目录结构:
sudo du -sh /data/mirror/mirror/archive.ubuntu.com/ubuntu sudo ls /data/mirror/mirror/archive.ubuntu.com/ubuntu/dists/bionic正常情况下,你会在dists/bionic下面看到main、restricted、universe、multiverse这几个组件目录,以及Release、InRelease等索引文件。
重要提示:首次全量同步的过程中,尽量不要中途强行kill进程。apt-mirror虽然支持断点续传,但如果你在写索引文件的时候强杀进程,很可能留下半截索引,下次同步会报解析错误。如果确实想中断,等当前正在下载的包下完再Ctrl+C,或者直接kill然后重新执行让它自己校验。
3.4 处理postmirror_script清理脚本
apt-mirror在首次同步完成后,会在/data/mirror/var目录下面生成一个clean.sh脚本。这个脚本的作用就是根据clean配置清理本地稀疏文件。我第一次用的时候不知道这个机制,结果仓库越攒越大,后来才发现是clean脚本没有执行权限。
检查并处理:
sudo ls -l /data/mirror/var/clean.sh sudo chmod +x /data/mirror/var/clean.sh如果你像我一样设了postmirror_script,apt-mirror会在每次同步完成后自动调用这个脚本。这个机制是防止仓库无限膨胀的关键。如果你不配置清理脚本,那些在上游仓库下架或者更新过的旧包会一直躺在本地,日积月累极其占空间。
4. 构建Web发布服务与apt客户端切换
4.1 用Nginx把镜像目录发布出去
镜像数据同步下来了,但还不能直接用,你要通过HTTP服务把这些目录暴露给客户端。我这里用的是Nginx,因为轻量、稳定、配置简单。如果你不想装Nginx,用Apache的alias也行,但Nginx在并发处理能力上明显更强。
安装并配置:
sudo apt install -y nginx sudo vim /etc/nginx/sites-available/mirror配置内容如下:
server { listen 80; server_name mirror.local; root /data/mirror/mirror; autoindex on; autoindex_exact_size off; autoindex_localtime on; location / { try_files $uri $uri/ =404; } }解释一下关键点:
root直接指向/data/mirror/mirror,也就是实际同步数据的父目录。这样访问http://你的服务器IP/archive.ubuntu.com/ubuntu/时就能直接映射到仓库目录。autoindex on开启目录列表,方便浏览器直接看仓库结构,排查问题时非常有用。try_files $uri $uri/ =404是防止目录不存在时报奇怪的错误,没有这个配置,某些情况下会403。
启用配置并重载:
sudo ln -s /etc/nginx/sites-available/mirror /etc/nginx/sites-enabled/mirror sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx注意:
server_name mirror.local只是给了一个内部主机名,实际访问时直接用IP完全没问题。如果你有内部DNS,可以把这个域名解析到这台服务器上;没有DNS也不影响使用。
然后本机验证一下服务是否正常:
curl -I http://127.0.0.1/archive.ubuntu.com/ubuntu/dists/bionic/Release如果能正常返回200,说明Web服务已经就绪。
4.2 客户端sources.list切换:官方源换成本地源
这是整个方案最后落地的一步,也是最容易翻车的地方。拿一台要安装软件的客户端机器,修改软件源配置。
Ubuntu 18.04的源配置通常在/etc/apt/sources.list文件里,某些场景也可能分布在/etc/apt/sources.list.d/下面,先看清楚再动手。先备份原配置:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak然后清空并写入新的配置:
sudo vim /etc/apt/sources.list配置文件最核心的内容如下:
deb http://192.168.1.100/archive.ubuntu.com/ubuntu bionic main restricted universe multiverse deb http://192.168.1.100/archive.ubuntu.com/ubuntu bionic-updates main restricted universe multiverse deb http://192.168.1.100/archive.ubuntu.com/ubuntu bionic-security main restricted universe multiverse这里把192.168.1.100换成你实际的内网Mirror源服务器IP。
这里有一点我反复踩过:路径里的/archive.ubuntu.com/ubuntu必须保留,不能省略。因为镜像目录结构就是按照官方仓库域名作为顶级目录存放的,如果你只写http://192.168.1.100/ubuntu,就会404,apt会报Failed to fetch的错误。
写完配置后,执行更新验证:
sudo apt update如果输出里出现Get:并且后面的地址都指向你的内网IP,说明切换成功。
sudo apt install -y vim随便装一个包验证实际下载是否走内网。用apt install拉包的同时,可以用iftop或者观察Nginx的访问日志来确认:
sudo tail -f /var/log/nginx/access.log如果你能看到大量指向.deb文件的GET请求,那就完全跑通了。
4.3 多架构与特殊组件支持的进阶配置
你如果只需要最简单的amd64源,上面那几行就够了。但如果需要给32位环境做源,或者需要i386架构的兼容库,那么客户端配置要改动一下。
比如你要让客户端能装32位兼容包(常见于运行老旧商业软件):
sudo dpkg --add-architecture i386 sudo apt update同时在配置里增加i386仓库行:
deb [arch=amd64,i386] http://192.168.1.100/archive.ubuntu.com/ubuntu bionic main universe这里要注意,mirror.list里如果只同步了amd64的包,即使你客户端配置了i386,apt也会因为找不到对应架构的索引而报警。所以服务端同步什么架构、客户端就配置什么架构,两边必须要对齐。
5. 定时同步、自动化更新与安全加固
5.1 配置定时任务确保镜像长期有效
镜像源不是搭完就一劳永逸的,上游仓库每天都在更新安全补丁,你的本地源如果一直不更新,相当于你的内网机器也永远打不上新补丁。所以定时同步是必须的。
使用cron做定时计划,编辑cron任务:
sudo crontab -e我这边设置的是每天凌晨2点同步一次,这个时间段一般业务压力小、网络占用低:
0 2 * * * /usr/bin/apt-mirror > /var/log/apt-mirror-cron.log 2>&1保存后cron会自动加载。你可以临时把时间调近一点测试,比如改成每分钟一次,确认cron配置无误后再改回计划时间。
有一个很实用的细节:apt-mirror本身会生成一个锁文件,防止多个同步进程同时运行。如果你设置cron的时候不小心写了多个任务,也不需要太担心并发问题——第二个进程会因为拿不到锁直接退出。
5.2 手动增量同步与状态验证
定时任务跑了一段时间后,你可能需要手动触发一次增量同步,或者想看看当前仓库状态是否健康。操作很简单:
sudo apt-mirror增量同步的速度非常快。如果上游没有更新,同步可能几秒就结束了;如果上游有新增包,就只拉新增的部分。我观察过,日常增量同步通常都在几分钟内完成,完全不会影响正常业务。
验证仓库健康状态看几个地方:
/data/mirror/var下面有同步日志,可以看最近一次同步是否成功。/data/mirror/skel目录里有索引文件,可以对比文件的更新时间。- 抽查几个软件包是否从上游正常更新,比如:
ls -l /data/mirror/mirror/archive.ubuntu.com/ubuntu/pool/main/v/vim/如果时间戳是最近日期的,说明同步链路正常。
5.3 Nginx访问控制与安全加固
内网Mirror源虽然主要服务内网,但该做的安全措施还是要做。至少要做两件事。
限制访问来源IP如果只有特定网段的机器需要访问这个源,最好在Nginx配置里限制来源IP:
server { listen 80; server_name mirror.local; root /data/mirror/mirror; allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; autoindex on; autoindex_exact_size off; autoindex_localtime on; }配置后重载Nginx。
做基本的访问日志监控
Nginx默认会记录访问日志。我建议你定期扫一眼日志,确认没有异常IP的大量请求。如果有一天日志量暴增,说明可能有内网机器被入侵后大肆下载软件包,或者是配置错误导致客户端疯狂重试。这时候及时排查一下总比后知后觉好。
不建议给Mirror源加密码认证,因为apt客户端本身不支持交互式输入密码(除非配置复杂繁琐的apt-auth机制),加了密码反而会让所有客户端的自动更新流程失效。内网环境做好IP限制就够了。
6. 常见问题与排查技巧实录
6.1 磁盘空间相关
问题现象:同步到一半提示No space left on device。
排查思路:这个是磁盘爆了。不要光看df -h的剩余空间,也要看inode是否耗尽,因为deb包都是海量的小文件,inode耗尽也是常见问题。
df -h /data/mirror df -i /data/mirror如果inode耗尽,只能清理掉一些不用的组件重来。如果是空间不够,最简单的办法是把不常用的multiverse或者deb-src同步临时停掉,在mirror.list里注释掉对应行,然后重新跑同步。等以后有空间了再加回来。
6.2 客户端apt update报404
问题现象:客户端执行apt update时,报类似这样的错误:
Err:1 http://192.168.1.100/archive.ubuntu.com/ubuntu bionic InRelease 404 Not Found排查思路:这个90%的原因是Nginx的root路径配置不对,或者客户端sources.list里的路径多写少写了层级。
按这个顺序排查:
- 在浏览器里直接访问
http://你的IP/archive.ubuntu.com/ubuntu/dists/bionic/Release,看能不能打开。 - 如果不能打开,检查Nginx配置里的
root是否指向了/data/mirror/mirror,而不是/data/mirror或者/data/mirror/mirror/archive.ubuntu.com。 - 检查sources.list里的地址,确认包含完整的
/archive.ubuntu.com/ubuntu路径。
6.3 同步过程中索引错误
问题现象:apt-mirror运行时报错:
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease Could not resolve host: archive.ubuntu.com排查思路:这通常是DNS问题。能解析外网域名是前提,如果服务器本身无法访问外网,那本地源的第一步就进行不下去。
ping archive.ubuntu.com如果ping不通,检查DNS配置和路由。还有一种情况是服务器能解析域名但访问不了443端口,但apt-mirror走的是80/443端口,也要确认防火墙放行。
6.4 同步完成但包不完整
问题现象:同步日志显示完成,但一些客户端安装某些包时报Hash Sum mismatch。
排查思路:这个最常见的原因是同步过程中网络抖动导致下载的deb包损坏,或者同步目录里有之前残留的旧文件。apt-mirror虽然校验索引,但不会对每个deb做哈希校验。解决办法比较简单,把这些异常包从本地目录删掉,然后重新跑一次同步,让它重新下载。
sudo rm -rf /data/mirror/mirror/archive.ubuntu.com/ubuntu/pool/main/v/vim/ sudo apt-mirror实操心得:我在实际维护中发现,这个"删包重拉"的操作比全量同步要靠谱得多。遇到Hash Sum mismatch,不要第一时间想着全量重来,先从报错信息里定位到具体软件包,删掉对应的目录再增量同步一次,通常一分钟内就能解决。
6.5 多台客户端同时更新导致负载高
问题现象:几十台机器同一时间跑apt update或apt upgrade,Mirror源服务器负载飙升,更新变慢。
排查思路:这本质上是并发问题。Nginx处理并发能力其实很强,但磁盘I/O可能成为瓶颈。建议:
- 把同步任务安排在业务低峰期,比如凌晨。
- 客户端
apt update的时间可以稍微错开,比如用cron随机化执行时间。 - 给Nginx的访问日志做切割,方便追查高负载时段来源。
sudo vim /etc/logrotate.d/nginx默认logrotate已经帮你做好了,不用太担心日志无限膨胀的问题。
6.6 通过外部健康检查验证源站
最后分享一个我常用的验证技巧:用排除法快速判断源站是否健康。
curl -I http://127.0.0.1/archive.ubuntu.com/ubuntu/dists/bionic/Release curl -I http://127.0.0.1/archive.ubuntu.com/ubuntu/dists/bionic-updates/Release curl -I http://127.0.0.1/archive.ubuntu.com/ubuntu/dists/bionic-security/Release三条命令都能返回200,说明源站服务正常。如果某一条404,去对比mirror.list里的配置,八成是同步时漏掉了对应仓库段落。
还可以抽查一个具体包来验证内容完整性:
curl -I http://127.0.0.1/archive.ubuntu.com/ubuntu/pool/main/v/vim/vim_8.0.1453-1ubuntu1_amd64.deb返回200就说明包文件在本地是真实存在的。
7. 踩坑经验与维护建议
7.1 千万不要盲目全量同步
我第一次搭镜像源的时候,直接在mirror.list里把所有组件、所有架构、源码包全写上,然后跑了两天的全量同步,下载了600多GB的数据,最后发现大部分根本用不上。后来我就明白了,镜像源跟业务需求强相关,先明确你需要什么,再配置同步范围。
比如你只是要装一些常用软件和编译工具,那最好的配置是:
deb-amd64 http://archive.ubuntu.com/ubuntu bionic main restricted universe deb-amd64 http://archive.ubuntu.com/ubuntu bionic-updates main restricted universe deb-amd64 http://archive.ubuntu.com/ubuntu bionic-security main restricted universe不要加deb-src,不要加multiverse,不要加i386。等真需要了再改配置同步,那时候增量同步也快。
7.2 定期检查同步日志比定期同步更重要
我见过太多人设置了cron之后就不管了,半年后发现Mirror源早就同步失败,内网机器一直在用半年前的旧软件源打补丁。实际上,定时同步任务只是一个保障,真正重要的是定期审查同步日志。
我自己一般每周花一分钟看一眼:
sudo tail -100 /var/log/apt-mirror-cron.log确认没有连续报错。如果发现连续几天同步失败,优先检查服务器外网连通性和磁盘空间。
7.3 关于Mirror源服务器的系统盘数据盘分离
镜像数据几百GB的规模,如果当初图省事放在系统盘,后面系统分区满了会很尴尬。我这边是把镜像目录放到挂载的数据盘上,数据盘独立分区、独立挂载,对系统盘零压力。就算是搭着玩,也建议至少用一个单独的目录而不是系统根目录下面随便放,这样后续要迁移、扩容都方便。
你如果计划长期维护这个Mirror源,还可以考虑在本地同步完成后做一次打包归档,把整个镜像目录打个tar包传到备份机器上。这样就算服务器磁盘挂了,也能快速恢复,不用重新同步几百GB。这个操作成本不高,但关键时刻能救命。
7.4 升级Ubuntu 20.04及更新的版本时要注意什么
如果你后续要把这个方案迁移到Ubuntu 20.04或22.04,思路完全一样,只需要把仓库代号从bionic改成focal或jammy,然后把apt-mirror重新装一下即可。Ubuntu 20.04以上版本仓库还默认支持deb [arch=amd64]的写法,这个跟18.04并没有本质差别。
不过我自己的体会是:Ubuntu 18.04的apt-mirror方案是最成熟稳定的,毕竟它已经存在很多年,各种坑都被前人踩平了。新版本系统虽然也兼容,但个别工具依赖变化可能导致小问题,需要临时排查。
7.5 最后一个小技巧
每次修改mirror.list配置之后,跑同步之前,先手动执行一次apt-mirror --verify之类的前置检查(不同版本参数可能略有差异),或者干脆先备份一下原来的配置文件:
sudo cp /etc/apt/mirror.list /etc/apt/mirror.list.bak这是一个特别小的习惯,但能让你在改坏配置之后半分钟内回滚,而不是花半小时回忆之前配置是怎么写的。
根据我个人经验,自建本地Mirror源这东西,做完前期部署之后,后面基本就是"养"的过程——每天定时同步,每周看一次日志,每月抽查几个包,只要这几件事按时做了,整个系统可以非常稳定地跑上几年。把这篇文章里的配置和坑点都消化掉,你那边搭出来的源大概率不会被常规问题绊倒。