debian/ubuntu用apt-mark hold,rhel/centos/rocky用dnf versionlock——这是最可靠、易验证且经生产环境广泛验证的包版本锁定方式。

直接结论:Debian/Ubuntu 用 apt-mark hold,RHEL/CentOS/Rocky 用 dnf versionlock(或旧版 yum versionlock)——这是最可靠、最易验证、且被生产环境广泛验证的方式。
Debian/Ubuntu 怎么用 apt-mark hold 锁定包
这是最轻量、最不容易出错的方案,对 apt upgrade、apt full-upgrade、apt-get upgrade 全部生效,且不破坏依赖解析(比如你锁了 nginx,装 certbot 仍能正常拉取它需要的 python3-requests)。
- 锁定单个包:
sudo apt-mark hold nginx - 一次锁多个:
sudo apt-mark hold nginx curl wget - 查看当前所有被锁的包:
apt-mark showhold(不用sudo) - 解除锁定:
sudo apt-mark unhold nginx
注意:apt-mark hold 不影响手动安装指定版本(如 sudo apt install nginx=1.24.0-1ubuntu1),但 Ubuntu LTS 的 unattended-upgrades 可能绕过它——若需绝对隔离,必须同步修改 /etc/apt/apt.conf.d/50unattended-upgrades,关闭自动安全更新或显式加入 Package-Blacklist。
RHEL/CentOS/Rocky 怎么用 dnf versionlock 精确锁版本
dnf versionlock 插件默认不启用,必须先装插件再加锁。它支持精确到 epoch:version-release.arch 的规则,比单纯锁包名更严谨,适合内核、容器运行时等敏感组件。
- 安装插件:
sudo dnf install python3-dnf-plugins-extras-versionlock - 锁住当前已安装的
httpd版本:sudo dnf versionlock add httpd - 锁死特定构建(推荐用于上线镜像):
sudo dnf versionlock add httpd-2.4.57-1.el9 - 查看锁表:
dnf versionlock list - 删掉某条规则:
sudo dnf versionlock delete httpd-2.4.57-1.el9
规则实际写入 /etc/dnf/plugins/versionlock.list,支持通配符(如 kernel-*)和注释。但要注意:dnf reinstall 或 dnf distro-sync 仍可能覆盖锁定版本——versionlock 只干预 upgrade 类操作。
为什么别用 dpkg --set-selections 或 /etc/apt/preferences
这两个方法底层虽有效,但在真实运维中容易翻车:
-
dpkg --set-selections是状态标记,不是策略控制;apt-mark hold实际调用它,但做了封装和校验,而直接操作容易被其他工具(如 GUI 包管理器、Ansibleapt模块)覆盖或忽略 -
/etc/apt/preferences(APT pinning)依赖优先级数值,配置稍有偏差就会导致整个源失效或无法升级——比如把官方安全源 priority 设低了,连openssl安全补丁都拉不到 - 两者都不如
apt-mark hold直观可查、可批量、可脚本化
除非你在做极特殊的多源混合部署,否则没必要碰它们。
临时排除 vs 永久锁定:什么时候该用 exclude
exclude 是粗粒度过滤,只适合简单、临时场景:
- 单次跳过内核升级:
dnf update --exclude=kernel* - 永久禁用(影响所有
dnf操作):在/etc/dnf/dnf.conf的[main]段加exclude=kernel* centos-release*
但它不校验版本,也不阻止依赖引发的间接升级(比如你 exclude=nginx,但 certbot 依赖新版本 python3-requests,而后者又依赖新 openssl,最终可能触发连锁更新)。真正的生产环境,必须用 versionlock 或 apt-mark hold 打底。
真正容易被忽略的是:锁定后必须验证是否生效——不是执行完命令就完事了。要跑一次 dnf list upgrades 或 apt list --upgradable 看目标包是否还在列表里,再用 rpm -q 或 dpkg -l 确认版本没变。否则锁了个寂寞。











