凌晨三点,我的 NVIDIA 驱动"炸"了:一次 Ubuntu 自动更新的惨案与彻底防御
TL;DR
Ubuntu 的
unattended-upgrades在后台静默升级了 NVIDIA 用户态库,但内核模块没跟上,导致nvidia-smi报Driver/library version mismatch。重装驱动只是治标,四层防护才是治本。
案发现场
机器开着没动,第二天早上 nvidia-smi 直接炸了:
Failed to initialize NVML: Driver/library version mismatch
经典的版本失配。dmesg 里躺着一条关键线索:
NVRM: API mismatch: the client has the version 580.xxx, but NVRM: this kernel module has the version 580.yyy.
用户态的 libnvidia 库被 apt 自动升级到了新版,但内核里的 nvidia.ko 模块还是旧版本——两者对不上,驱动直接拒绝工作。
根因锁定:Ubuntu 默认开启的 unattended-upgrades 服务,在凌晨静默执行了安全更新,把 NVIDIA 的用户态包偷偷升级了。
为什么重装驱动只是治标?
重装驱动(apt install --reinstall nvidia-driver-580)确实能让 nvidia-smi 恢复正常,但下一次自动更新到来时,同样的问题会再次上演。
真正的解决方案是:从源头掐断自动更新,并把关键包锁死。
四层防护体系
Layer 1:锁定内核包
自定义内核系统里没有 linux-image-generic 这类元包,只锁定实际存在的:
sudo apt-mark hold \
linux-image-7.0.0-31-generic \
linux-headers-7.0.0-31-generic \
linux-modules-7.0.0-31-generic
强行锁定不存在的包(如**
linux-modules-extra)只会收获一堆 **E: Unable to locate package,没必要。
Layer 2:锁定 NVIDIA 全家桶
sudo apt-mark hold \
nvidia-driver-580 \
nvidia-dkms-580 \
libnvidia-common-580 \
nvidia-utils-580
这四兄弟必须一起锁,缺一不可——libnvidia-common** 和 nvidia-utils **就是上次半夜偷偷升级的罪魁祸首。
Layer 3:禁用自动更新服务
sudo systemctl stop unattended-upgrades
sudo systemctl disable unattended-upgrades
sudo systemctl stop apt-daily.timer
sudo systemctl disable apt-daily.timer
sudo systemctl stop apt-daily-upgrade.timer
sudo systemctl disable apt-daily-upgrade.timer
三重定时器全部掐断,从 systemd 层面杜绝后台偷跑。
Layer 4:APT 配置文件双重保险
/etc/apt/apt.conf.d/10periodic:
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "0";
/etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Unattended-Upgrade "0";
两层配置文件互相兜底,就算某一层被覆盖,另一层还能兜住。
额外操作:把 Snap 连根拔起
Ubuntu 26.04 的 Snap 生态对追求纯净系统的用户来说过于臃肿,一并清理:
# 批量卸载所有 snap 包(保留 snapd 本身先不删)
sudo snap remove --purge $(snap list | awk 'NR>1 && $1!="snapd" {print $1}')
# 卸载 snapd
sudo apt purge snapd
# 清理残留目录
sudo rm -rf /snap /var/snap /var/lib/snapd /var/cache/snapd ~/snap
# 锁定 snapd 防止被自动装回
sudo apt-mark hold snapd
snap** **命令彻底消失,系统清净了。
最终验证
$ apt-mark showhold
libnvidia-common-580
linux-headers-7.0.0-31-generic
linux-image-7.0.0-31-generic
linux-modules-7.0.0-31-generic
nvidia-dkms-580
nvidia-driver-580
nvidia-utils-580
snapd
$ systemctl is-active unattended-upgrades apt-daily.timer apt-daily-upgrade.timer
inactive
inactive
inactive
$ cat /etc/apt/apt.conf.d/10periodic
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "0";
全部通过。
总结
这套四层防护(包锁定 + 服务禁用 + 配置修改 + Snap 移除)让系统彻底免疫"半夜自动更新搞崩驱动"的问题。以后想更新时手动执行 apt update && apt upgrade,所有被 hold 的包都会被跳过,完全可控。
核心原则 :生产环境 / 工作站机器,永远不要让包管理器在后台静默执行任何操作。一切更新,必须经过你的手。