十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Ubuntu安装包备份与系统恢复实战:从apt缓存到Clonezilla

Ubuntu安装包备份与系统恢复实战:从apt缓存到Clonezilla 装完Ubuntu又要重装系统的时候你最头疼的是什么不是壁纸不见了不是终端配色要重新调而是那些当初花了一个下午才装好的软件搜狗输入法的deb包、JDK17的安装包、微信的离线包源地址失效了网盘链接过期了官网下载慢得像蜗牛。我经历过一次彻底的重装之后就养成一个习惯所有安装包必须备份。这件事听起来简单真做起来门道不少这篇就分享我在Ubuntu系统上做安装包备份的完整方案覆盖deb缓存、手动归档、已装软件重打包、离线批量部署、以及系统级快照的取舍。1. 装完系统最怕的事为什么要给安装包留一条后路先聊动机。很多人觉得备份安装包是多此一举Ubuntu有apt源想装什么apt install一条命令搞定备份干嘛但真实世界没那么理想化我列几个自己遇到的场景你就明白了。公司内网服务器不允许连外网只能通过离线包安装软件。这种环境下手头有没有一份完整的安装包归档直接决定你能不能在半天内把一台空机器变成可用状态。还有软件源的问题Ubuntu每个大版本都有官方源但第三方软件源说挂就挂比如某些Pinyin输入法、企业微信、Sogou输入法的官方deb下载页过个一年半载可能连入口都找不到了。再加上国内网络环境的下载速度一个几十MB的包挂在官方源上下到一半断线重来那体验谁试谁知道。所以我把“安装包备份”定义为一件正经事不是随手把deb文件扔U盘里就完事。它其实是环境可复现的基础设施。所谓环境可复现就是你拿到一台全新的Ubuntu机器通过你备份的东西能原原本本恢复出和你当前工作机一样的软件环境。备份的粒度可以从三层来看。第一层是安装包本身也就是deb、AppImage、tar.gz这类文件对应的是“软件装得上”第二层是软件配置像conda环境、Docker镜像、数据库导出文件对应的是“环境变得回”第三层是整个系统快照对应的是“状态回得去”。这三层递进普通人做前两层就够了但如果你管着多台服务器或者喜欢折腾系统第三层关键时刻能救命。我见过太多人备份时只顺手拷贝了deb文件恢复的时候才发现一堆依赖缺失装一个包要手动找五个依赖直接从下午折腾到晚上。要避免这个坑不能只备份安装包还得搞清楚这个包是从哪来的、依赖了什么、版本是什么这就是后面几节要展开的东西。2. apt缓存目录Ubuntu默认留给你的一笔隐形财富说到备份安装包第一个该盯上的地方就是/var/cache/apt/archives。这是apt在安装软件时存放下载的deb包的目录很多人装了几年系统都不知道它的存在。每次执行apt installapt会先把.deb包下载到这个目录然后才解包安装。正常情况下这个目录里积累的是你最近装过的软件包。如果你重装前把这个目录整体拷走理论上就能离线安装这些包。默认配置下apt清理缓存的时机有两个手动执行apt clean清空所有缓存或者执行apt autoclean只删除无法再下载的无用包。如果你从没主动清理过这个目录可能已经存了不少好东西。我建议的做法是这样# 查看当前缓存了多少包 ls /var/cache/apt/archives/*.deb | wc -l # 备份到外部存储 sudo mkdir -p /backup/ubuntu-apt-cache sudo cp -r /var/cache/apt/archives/*.deb /backup/ubuntu-apt-cache/ # 如果有额外U盘或移动硬盘也可以直接指定挂载点 sudo cp -r /var/cache/apt/archives/*.deb /media/your-username/backup-drive/但要泼一盆冷水直接这么备份有坑。第一个坑是apt缓存并不完整。如果你是用apt install安装的软件大多数情况下deb会留在缓存里。但如果你是通过snap安装的或者从官网下载的.deb手动安装apt缓存里根本没有。另外系统自动更新的包缓存里往往只有最新版本旧版本早就被清理了。第二个坑是版本匹配。你在A机器上缓存了某个软件包的2.0版本恢复时如果目标机器的系统版本不一样存在依赖库版本不一致的可能性直接dpkg -i大概率报依赖错误。在我的工作流里/var/cache/apt/archives只是一个基础来源真正的资产是自己的归档目录。也就是说我不建议把apt缓存当作唯一的备份而是把它当作材料来源之一配合后面的手动归档和重打包方案一起使用。3. 手动下载的安装包从“用完就删”到“归档为资产”从官网、第三方源下载的deb、AppImage、tar.gz这些是你最需要养成归档习惯的东西。为什么因为它们往往有这几个特征官网下载链接不保证长期有效网盘链接可能失效版本更新后旧版入口被替换更关键的是它们通常不在apt源里重装后你只能再去网上翻一圈。我自己在/home下建了一个专门的目录结构大概是这样的/home/tony/software-backup/ ├── deb/ │ ├── sogoupinyin_4.2.1.145_amd64.deb │ ├── wechat_2.1.5_amd64.deb │ ├── jdk-17_linux-x64_bin.deb │ └── code_1.86.2_amd64.deb ├── appimage/ │ └── obsidian-1.4.16.AppImage ├── tarball/ │ └── golang1.21.5.linux-amd64.tar.gz ├── fonts/ │ └── JetBrainsMono-2.304.zip └── drivers/ └── nvidia-driver-535.run目录按类型分好有一种安全感。但光分类还不够我在每个目录里都放了一个README.md或者install-notes.txt记录这个包的下载来源、安装方式、是否需要额外配置。很多人忽略这个步骤等到半年后翻出来一个包完全想不起来当初是怎么装的有没有改过环境变量就非常被动。举个例子如果你备份了JDK17的deb包恢复时直接sudo dpkg -i jdk-17_linux-x64_bin.deb它会装到/usr/lib/jvm下但JAVA_HOME不会自动设置你得手动改/etc/environment或~/.bashrc。这种信息不记下来等于没有完全备份。另外一个实用技巧是记录校验和防止备份介质损坏或者下载过程中文件残缺# 生成校验和清单 cd /home/tony/software-backup find . -type f -name *.deb -exec sha256sum {} \; SHA256SUMS.txt # 恢复前校验 sha256sum -c SHA256SUMS.txt这一步操作成本很低十几秒的事但能帮你排除“备份文件本身坏了”这种最让人崩溃的问题。我自己的习惯是每次往归档目录里放新包就把整个校验和文件重新生成一次保持它是最新的。还有一点要专门提醒不要只备份.deb忽略AppImage和tar.gz。AppImage的好处是免安装双击就能跑重装系统后甚至不需要安装直接把整个文件拷过去就能用。tar.gz类的绿色版软件更简单解压即用但环境变量配置一定要记下来。像Go语言、Miniconda的安装包都属于这种类别。4. 已装软件的重新打包dpkg-repack与源码包保留有时候你会遇到更尴尬的情况某个软件当初是通过编译源码装的或者从一台上古机器上手动装好的现在那台机器上跑得好好的但你已经找不到原始安装包了。这时候最好的办法就是用dpkg-repack把已安装的软件重新打包成deb。这个工具的存在意义很简单它把一个已经安装到系统里的软件包连同它的配置和文件重新封装成一个.deb包。之后你可以把这个deb拿去别的机器装效果和原来那台机器上的一致。安装和基本用法如下# 安装dpkg-repack sudo apt install dpkg-repack # 重新打包指定的已安装软件 dpkg-repack sogoupinyin # 批量重新打包所有已安装的软件谨慎使用 dpkg-repack $(dpkg --get-selections | awk {print $1} | grep -v remove)注意批量打包这个操作我特意标注了“谨慎使用”。为什么因为系统里很多软件之间是相互依赖的你把一百多个包全部打出来恢复的时候很容易出现版本冲突、依赖循环反而比只打包十来个核心软件要难搞得多。我建议只对以下两类软件做重打包通过编译安装、无法通过apt直接安装的软件比如某些Python工具链、定制的Nginx。在apt源里下架或升级过头的旧版本软件而你恰好需要那个特定版本。dpkg-repack打出来的deb安装时要小心我用dpkg -i装过几个重打包的包有的直接报“已安装的postinst脚本失败”。这种情况多半是打包时把配置也带了进去而新系统里已经存在同名配置。解决办法是加--force-all参数或者先手动备份配置文件再安装。但我得提醒一句对系统底层包比如systemd、grub、linux-image这类尽量不要用dpkg-repack风险太高。除了dpkg-repack还有一种情况要考虑你编译安装的软件怎么备份最好的习惯是在源码目录保留一份当时下载的源码压缩包同时把编译参数写进README。比如编译Nginx时要带上某些模块参数如果你不记下来恢复时就得重新查文档、试错时间成本很高。5. 离线批量部署备份到私有源和局域网仓库如果只是家用电脑重装前面几种方式已经够用了。但如果你是给部门配机器或者维护一个实验室的几台Ubuntu服务器那就不能一台台拷贝deb了得把备份升级成“离线仓库”的模式。最简单、最可靠的做法是选一台有网的机器把需要用到的deb包全部下载好做成一个迷你apt源放到局域网共享目录里。客户端设置源指向这台机器就能离线批量安装。制作迷你源的核心步骤就是准备好一批deb文件之后跑一遍dpkg-scanpackages生成索引# 在装有deb包的目录下生成Packages索引 cd /opt/ubuntu-offline-repo dpkg-scanpackages . /dev/null | gzip -9c Packages.gz然后要知道apt能用的源需要一个Release文件。一般还要加一个Release文件并签名不过在内网信任环境里可以用apt-get update --allow-insecure-repositories绕过签名检查。更省事的方案是直接使用apt-mirror同步整个Ubuntu源到本地服务器但这个工程量大动辄几百GB适合需要完整支持全量安装的场景普通办公环境没必要。如果你只是想临时给几台机器装几个包用apt-offline更轻量。它的工作思路是在目标机器上生成一个安装包请求清单把这个清单文件拿到有网的机器上下载对应的deb包再带回目标机器执行安装。# 无网目标机上生成请求 sudo apt-offline set /tmp/offline_request.pkg # 有网机器上根据请求下载 sudo apt-offline get /tmp/offline_request.pkg -d /backup/offline-packages/ # 离线机器上安装 sudo apt-offline install /tmp/offline_request.pkg这种方式比整个源同步要轻得多适合网络条件受限又需要保持系统干净整洁的场景。最常见的应用就是内网服务器安装Docker、数据库客户端这些有固定依赖的软件。还有一个小技巧把备份好的deb目录直接用NFS或者Samba共享出来在目标机器上把源配置成这个共享地址。这样不仅省去了U盘拷贝的功夫多人多机器安装时效率更高。6. 系统级快照备份再生龙Clonezilla与tar方案的取舍聊完安装包层面的备份必须得提系统级快照。很多人一听到“备份安装包”第一反应是整个系统重装时软件得重新装一遍但其实如果你做了系统快照连“重新装”这个动作都可以省掉。热词里频繁出现的“再生龙”就是Clonezilla的中文俗称。它的能力是把你整个磁盘或者某个分区做成一个镜像文件之后恢复的时候直接把这个镜像还原到硬盘上。好处是不言而喻的整个系统的状态、已安装的软件、用户的配置、环境变量全部原样保留。我自己的经验是Clonezilla适合在以下场景用同一型号多台机器批量部署。做好一台“黄金母机”做镜像然后批量还原到其他机器比一台台装快一个数量级。系统升级或大改动之前先做镜像万一改崩了10分钟就能恢复原状。把整个系统迁移到新硬盘直接用Clonezilla做“磁盘对拷”省去重装和配置的时间。Clonezilla的缺点也很明显镜像文件非常大一般要占原磁盘用量的50%到80%而且恢复时要求目标机器的硬件配置和源机器基本一致。如果你把一台Intel的机器镜像恢复到AMD的机器上驱动层面很容易出问题。所以我个人的分层策略是日常靠安装包备份系统级快照只在大变动之前做。这不矛盾两者是互补关系。如果你不想用Clonezilla这种重量级方案还想做全量备份可以用tar打包系统目录。这种方式更灵活可以只打包某个目录也可以做整个根文件系统的快照。模板命令如下sudo tar -cvpzf /backup/system-backup.tar.gz \ --exclude/proc \ --exclude/sys \ --exclude/dev \ --exclude/tmp \ --exclude/run \ --exclude/mnt \ --exclude/media \ --exclude/var/cache \ --exclude/backup \ /注意排除了/proc、/sys、/dev这些虚拟文件系统也排除了/var/cache因为这里有你之前备份过的apt缓存没必要每次打包都重复占用空间。恢复的时候先把系统盘格式化然后解开这个tar包再重新挂载/proc、/sys这些目录。tar全量备份的优点是通用、可见可控缺点是没有增量机制每次都要全量打包时间成本和存储成本都高。如果你想要自动化定期快照我更推荐Timeshift。它本质上是rsync加硬链接的增量快照既能恢复文件也不会占用多份全量空间。Timeshift在Ubuntu下有图形界面配置好之后点几下就能创建快照适合不想折腾命令行的人。我自己现在的组合是这样的每半年做一次Clonezilla镜像存档每个月用Timeshift做两三次增量快照每次下载新安装包随手丢进归档目录。这三层互不干扰哪一层出了问题都有退路。7. 环境依赖备份conda、Docker镜像与数据库导出有时候软件本身不算难装难的是它的环境。热词里不少人搜“如何备份conda配置”这就是典型的环境依赖备份需求。装包好办环境变态。conda环境里几十个包版本配得刚好能跑一旦重装系统手动一个个装必出问题。这个场景太常见了。conda环境备份有两个层次。如果你只想要一份环境描述用来重新创建环境conda env export myenv.yml恢复时conda env create -f myenv.yml。但注意conda env export导出的是包名和channel恢复时还是需要联网下载。对于内网环境这个方法不太行。更扎实的备份是把conda的环境目录整个拷贝也就是打包~/miniconda3/envs/这个目录或者用conda pack这个专门工具conda install conda-pack conda pack -n myenv -o myenv.tar.gzconda pack打出来的包可以在没有conda的机器上直接解压使用相当于是环境级的一键迁移比yml文件可靠太多。这也是我更推荐的方案尤其是目标机器网络不好、或者你想要绝对一致的版本。Docker环境的备份思路类似。一个镜像已经包含了软件和运行环境你在机器A上构建好的镜像最常用的备份是docker save -o myapp-image.tar myapp:latest恢复时docker load -i myapp-image.tar。如果你自己搭了私有Registry更优雅的方式是docker push到私服在别的机器上docker pull。这里多说一句如果用docker export导出的tar包它和docker save不一样前者不含镜像层信息还原后不是镜像而是文件系统目录用法完全不同别混淆。数据库的备份也值得一提因为“安装包备份”做完软件能装上但它里面的数据如果不备份等于白做。数据库的备份方式分逻辑备份和物理备份。PostgreSQL用pg_dump导出SQL脚本MySQL用mysqldump这些是逻辑备份跨版本、跨平台兼容性好。物理备份则直接拷贝数据库的数据目录速度快但对版本和平台非常敏感。我对生产数据库的一贯建议是逻辑备份每天做物理备份配合定期快照做。至于达梦、瀚高这些国产数据库备份思路也是一样的逻辑导出加上物理文件拷贝关键点在于备份文件的存放位置一定不能和数据库本身在同一块硬盘上。8. 备份脚本与恢复演练我的目录结构与实测经验最后说点落地的。我把自己这一套备份动作写成了一个脚本放在/home/tony/backup-ubuntu.sh手动跑或者扔进crontab定时跑都行。脚本做三件事同步apt缓存、归档手动下载目录、生成校验和清单。#!/bin/bash # backup-ubuntu.sh - Ubuntu安装包备份脚本 BACKUP_DIR/media/backup/ubuntu-packages DATE$(date %Y%m%d) mkdir -p $BACKUP_DIR/apt-cache mkdir -p $BACKUP_DIR/my-debs # 1. 备份apt缓存 sudo cp -r /var/cache/apt/archives/*.deb $BACKUP_DIR/apt-cache/ 2/dev/null # 2. 备份手动归档的安装包 cp -r /home/tony/software-backup/*.deb $BACKUP_DIR/my-debs/ 2/dev/null # 3. 生成校验和 cd $BACKUP_DIR find . -type f \( -name *.deb -o -name *.AppImage -o -name *.tar.gz \) -exec sha256sum {} \; SHA256SUMS-$DATE.txt echo 备份完成时间: $DATE这个脚本很简单但很实用。你不用追求一步到位关键是养成习惯。我现在每次下载了一个新的deb包会随手放到~/software-backup隔一两个月跑一次脚本同步到移动硬盘。但比备份更重要的是恢复演练。我吃过一次大亏备份了三个月的安装包系统真崩了之后用这些包恢复结果装了将近一半软件就出现依赖无法解决的情况最后还是要联网补包。原因就是我在备份时有些依赖包没有覆盖到。自那以后我给自己定了一条规矩每次备份方案调整之后必须在一台VMware虚拟机里模拟一次完整恢复。虚拟机里恢复演练的步骤就是新建一台Ubuntu虚拟机尽量和真实工作机版本一致。尝试只用备份介质里的apt缓存和归档debdpkg -i *.deb安装核心软件。尝试用apt install安装一个需要编译的软件看缺的依赖在不在备份里。尝试解压tar.gz类软件验证环境变量配置笔记有没有遗漏。恢复conda环境、加载Docker镜像确认业务能跑通。这一套演练流程走下来你才会真正知道自己的备份有多“厚”。很多你以为备份了就万无一失的东西演练时才会暴露出来比如某个小依赖包没备份、某个配置文件的路径记错了、某个校验和不一致。在演练中发现问题总比系统真挂了再发现好。还有一个细节我想特别强调备份介质不能只有一个。移动硬盘会摔坏U盘会莫名其妙丢数据网盘可能服务到期。我现在是移动硬盘为主、另一块淘汰下来的旧硬盘做定期同步有条件的人可以再加一个云存储或者NAS。备份本身不产生价值恢复成功才产生价值。这一整套做下来我的Ubuntu机器才真正实现了“重装系统不慌”的状态。每次系统大版本升级前把快照做一次、安装包目录同步一遍改崩了大不了退回去重来。工具和方法不是越多越好核心是找到适合自己场景、能坚持执行的那一套。现在这套方案我用了一年多中间真实重装过两次恢复过程从第一次的手忙脚乱到后来的半小时搞定全靠平时随手归档和定期演练。你可以直接抄作业也可以按自己的习惯调整目录和脚本但有一点千万别省备份之后一定在干净机器上恢复一次试试。
返回列表