本节摘要:APT 与 DNF 分别是 Debian 系与红帽系的包管理前端,常用操作一一对应、细节立场有别。本节从一次生产环境升级翻车的标准处置讲起,给出两族命令的完整对照、版本锁定的用法、离线环境依赖搬运的方法,最后交付一份可复用的升级操作规程。
某团队的月度升级窗口,计划给生产环境的数据库客户端库升级。测试环境演练通过,生产执行:
sudo apt update && sudo apt upgrade -y
升级过程顺利结束,但五分钟后应用健康检查大面积飘红——新版客户端库与业务代码里一段老协议实现不兼容,测试环境的数据形态没覆盖到那个分支。值班按预案走回滚。因为升级前做过版本记录(下面马上讲的技巧),回滚清单现成:
apt list --installed | grep libpg > /var/tmp/rollback-manifest.txt
按清单把相关包降回旧版,五分钟服务恢复。事后追加两条改进:客户端库这类"被业务直接依赖"的包,升级从"随大流升级"改为"单独评审后显式升级";引入版本锁定,防止它再被顺带升上去。
这个案例的看点不是事故多严重,而是回滚为什么能这么快——因为升级是受控变更:有记录、有预案、有验证动作。下面把这背后的操作体系完整铺开。
先给总表,下文挑高频项展开。同一个意图,两族说法:
| 意图 | APT | DNF |
|---|---|---|
| 刷新仓库元数据 | apt update | dnf makecache 或自动 |
| 搜索包 | apt search 关键词 | dnf search 关键词 |
| 查看包详情 | apt show 包名 | dnf info 包名 |
| 安装 | apt install 包名 | dnf install 包名 |
| 升级全部 | apt upgrade | dnf upgrade |
| 卸载保留配置 | apt remove 包名 | dnf remove 包名 |
| 卸载含配置 | apt purge 包名 | dnf remove 包名 加清理选项 |
| 已装清单 | dpkg 列表 | dnf list installed |
| 锁定版本 | apt-mark hold | dnf versionlock |
| 事务历史 | 无内建 | dnf history |
表里最值得注意的差别是最后一行:DNF 有内建的事务历史,每次安装升级都是一条可查询、可回滚的事务;APT 生态没有对等物,所以 Debian 系的运维要靠"升级前手工留台账"补位——开篇案例的清单文件正是这个用途。设计立场差异一眼可见:红帽系把回滚做进了工具,Debian 系把回滚留给流程。
搜索与查看,装前先看依赖与体积是基本动作:
apt show nginx | head -8
Package: nginx Version: 1.18.0-6ubuntu14.4 Depends: libssl3 (>= 3.0.0), nginx-common (= 1.18.0-6ubuntu14.4) Download-Size: 698 kB Description: small, powerful, scalable web server
依赖行、体积、描述一目了然。安装与确认:
sudo apt install -y nginx dpkg -l nginx | tail -1
ii nginx 1.18.0-6ubuntu14.4 amd64 small, powerful, scalable web server
ii 状态正常,版本符合预期。卸载的两种粒度要分清:remove 留配置、purge 连配置一起清。重新装回时 purge 过的包不会有旧配置干扰,这个差别在排查"重装了还是老行为"时是第一嫌疑——配置没删干净,重装当然复现老问题。
缓存治理是被忽视的日常:下载的包文件堆在缓存目录里越积越大。定期清理,或设置保留策略只留最近两个版本。3.1 节的磁盘巡检清单值得加上这一项。
版本锁定,把"不许被顺带升级"的包钉住:
sudo apt-mark hold libpq5 apt-mark showhold
libpq5
被钉住的包在批量升级时会被跳过,showhold 随时可查钉子清单。解除用 unhold。钉子是纪律不是装饰:每颗钉子应该有注释说明为什么钉(进团队的变更记录),否则一年后没人敢拔。
同样的操作在 DNF 侧:
sudo dnf install -y nginx dnf history | head -5
ID Command line Date and time Action(s) Altered 47 install nginx 2026-08-16 23:50 I 3 46 upgrade 2026-08-09 03:00 U 28 45 install htop 2026-07-30 11:12 I 1
历史表是 DNF 的招牌:第四十六号事务升级了二十八个包。逐条细看与回滚:
sudo dnf history undo 46
这条命令撤销整个事务,二十八个包回到升级前状态——开篇案例要的那种回滚,在红帽系是一条原生命令。事务历史也让审计变得简单:这台机器装过什么、动过什么,按时间线可查,与 sudo 日志(4.2 节)拼起来就是完整的操作账本。
DNF 的版本锁定用插件形态:
sudo dnf install python3-dnf-plugin-versionlock sudo dnf versionlock add nginx
语义与 apt-mark hold 一致,钉住的包不参与自动升级。两族工具在这个需求上殊途同归,验证了它是真实刚需。
隔离网络里装软件是运维常见任务。思路是把"安装方案"在联网机器上算好,把所需包全部下载,搬到目标机器安装。APT 侧:
apt install --download-only -y htop ls /var/cache/apt/archives/*.deb | head -3
/var/cache/apt/archives/htop_3.0.5-7build2_amd64.deb
下载而不安装,包文件全在缓存目录,打包搬走(2.4 节的 tar 技能),目标机器上用底层工具直接装:
sudo dpkg -i htop_3.0.5-7build2_amd64.deb
dpkg 不解析依赖,如果报缺依赖,把缺的包一起搬来,或者用 apt 的本地修复能力补齐。DNF 侧更直接:
dnf download --resolve htop
带解析选项的下载会把依赖一并列出,搬运体验友好得多。离线安装的关键在"两台机器的仓库配置要一致",否则联网机算出的方案在目标机对不上号——这也是企业环境统一仓库镜像的动机之一。

前者只刷新元数据(知道有什么新版本),后者才执行升级(动系统)。分成两步的好处是可控:可以先看升级清单再决定动不动。生产环境永远先 update 再人工审清单再 upgrade,别用一条命令把两步连起来自动跑。
桌面与测试环境建议开,堵漏洞的及时性最重要。生产环境分两派:开的人看重及时,不开的人看重可控。折中做法是只开安全类更新的自动应用、其余走窗口,这是多数团队的落点。
两步:purge 清包自带配置;自动安装的依赖在主包卸载后成了孤儿,用自动清理命令回收。定期做一次,系统的包台账保持精干。清之前看一眼清单,确认没有手动标记为必须的包被误回收。
按提示刷新元数据即可,多数时候一条更新命令解决。若仓库地址本身失效(镜像站迁移、版本停止维护),要改仓库配置换源——这又回到 5.1 节"停服检查"的老话题,仓库失效是老系统最常见的报警器。
把本节内容收拢成一份可以直接照做的升级操作单,供你在自己环境里演练。目标:给一台测试机做全量升级并全程可控。
第一步,评估与记录。刷新元数据,导出可升级清单存档,同时导出关键包的当前版本:
apt update apt list --upgradable | tee /var/tmp/upgrade-plan.txt | wc -l dpkg -l | grep -E "nginx|libpq" > /var/tmp/rollback-manifest.txt
清单里逐项过一遍,标记出"被业务直接依赖"的包——它们要单独评审,必要时提前钉住。
第二步,执行。小步走,先升库再升应用,每步之间跑一次服务健康检查:
sudo apt upgrade -y systemctl status nginx --no-pager | head -3
第三步,验证与收尾。核心业务路径实测通过后,把升级记录归档,钉子清单核对一遍,缓存清理。任何一步异常,按第二环节留的版本清单降级回去——回滚清单就是你的安全绳。
整套流程在测试机上完整走两遍:第一遍照着操作单做,第二遍假设中途翻车练回滚。练过回滚的升级和没练过的,是两种完全不同的心理状态。
生产环境里,任何包操作前先问三个问题:这个包被谁依赖着?升级后谁需要重启?回滚方案是什么?三个问题都有答案再动手。包管理的事故几乎都不是命令敲错,是没问就敲了。
个别现实场景里,一台机器不得不面对两族包格式——最典型的是在红帽系机器上装一个只有 deb 打包的内部工具,或反之。此时守住三条底线就不会失控:第一,一族为主、一族为客,客方工具与包全部登记在台账备注里,标明来源与用途;第二,绝不混用两族的依赖解析器去解对方的包——客方包必须是自包含的(静态链接或捆绑依赖),否则依赖地狱分分钟重演;第三,给客方软件划定独立的安装前缀与数据目录,卸载时整体回收。三条底线的本质是把客方包当成"受管理的源码编译产物"对待——回到 5.1 节的原则:可以例外,但例外必须可见、可查、可回收。见过太多环境从"就装一个 deb"开始,两年后变成两族包犬牙交错、谁也不敢动的沼泽。例外管理的能力,比不产生例外的能力更真实。
企业环境里包仓库本身也需要运维,三件小事值得知道。其一,镜像加速:把发行版官方仓库镜像到内网服务器,几十台机器的升级流量不再出公网,速度快且可控。主流方案都有现成的同步工具,定时任务拉取即可。其二,内网软件的发布通道:内部开发的工具打成正式包格式,发布到内网仓库,同事一条命令安装——从此告别"去网盘下载压缩包解压改权限"的原始时代。其三,仓库的版本冻结:重大保障期间把机器的仓库指向冻结的快照版本,确保任何安装操作拿到的都是经过验证的版本组合。三件事都不难,做完之后整个环境的软件流转就从"野生"进入"驯化",这是包管理实战的深水区,也是本章给你留下的进阶路标。
包管理的尽头是习惯而不是命令:装前看依赖、动前留清单、升完做验证、钉子写注释。四个习惯养成了,两族命令的具体参数忘了都能现查;四个习惯没有,命令背得再熟也是裸奔。
两族对照学完,你可能想知道日常到底该把哪族练精。答案还是那句:跟你环境走。但无论哪族,都建议做一次跨族练习——在虚拟机里把另一族从装系统到锁版本的完整流程跑一遍。跨族练习的价值不在命令本身,在视角:见过另一种设计的人,对自己习以为常的工具会突然多出几个为什么这样设计的疑问,而疑问是理解的开端。很多资深运维对包系统的深刻理解,正是从一次跨族对照开始的。
到这里,五章全部结束。从黑屏滚字的恐慌,到能独立完成一次完整的故障复盘——你已经走完了这条路的起点。剩下的,去生产环境(先从测试环境开始)里练吧。