SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-09-08

Rocky和Alma哪些更新需要重启?检查方法

dnf update 后旧内核和旧库仍可能在运行。本文说明 needs-restarting 的用法、退出代码 0/1,以及 Rocky 10 和 AlmaLinux 10 的 DNF 5 差异。

Rocky Linux 和 AlmaLinux 上哪些更新需要重启

在 Rocky Linux 和 AlmaLinux 上,dnf update 会将新文件写入磁盘,然后停止操作。正在运行的内核不会改变。已经打开某个库文件的进程会继续使用打开时的副本,因为只要仍有进程持有旧文件,Linux 就会让该文件继续保留在磁盘上。因此,即使系统报告没有可用更新,仍可能运行着已被这些更新替换的代码。这一点在两个发行版之间没有区别,因为它们都基于相同的 Red Hat 源代码重新构建;选择 Rocky 还是 Alma 取决于兼容性承诺和 CPU 支持,而不是本文介绍的内容。下面的命令也与 CentOS 主机使用的命令相同,这并非巧合:两个项目都是在 2020 年 Stream 公告后作为 CentOS 替代品构建的。

哪些更新需要重启,哪些只需要重启服务,必须由系统本身判断。用于回答这一问题的命令是 needs-restarting。更新分为 3 个级别。内核和一小部分核心软件包需要完整重启。普通库更新需要重启使用这些库的服务。其他更新在 RPM 完成安装后就已经生效。

安装 needs-restarting

needs-restarting 是一个 DNF 插件。该插件包含在 dnf-plugins-core 中,而大多数 Rocky 和 Alma 安装已预装该软件包。/usr/bin/needs-restarting 命令是 dnf-utils 提供的一个小型包装器。

sudo dnf install -y yum-utils
needs-restarting --help

这两种写法执行的是同一段代码,因为该包装器会调用 DNF 子命令:

needs-restarting -r
dnf needs-restarting -r

这两个软件包都来自发行版自己的软件仓库,因此无需为此启用 EPEL 或 CRB 软件仓库。

在 Rocky Linux 10 和 AlmaLinux 10 系列中,dnf 是 DNF 5,needs-restarting 是其自带的命令,来自 dnf5-plugins 软件包。在这些系统中,不带选项运行 dnf needs-restarting 会直接给出是否需要重启的结果。-r 仍然可用,手册说明它不起作用,仅用于让 DNF 4 脚本继续运行。

第 1 层:需要重启的更新

先运行重启检查。它只读取 RPM 数据库和系统启动时间,不读取其他内容,因此速度很快,也不需要 root 权限。

needs-restarting -r

如果系统启动后没有发生重要变化,它会输出两行:

No core libraries or services have been updated since boot-up.
Reboot should not be necessary.

如果检测到变化,它会输出 Core libraries or services have been updated since boot-up:,然后输出找到的软件包名称,最后输出:

Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943

退出代码传递相同的结果:不需要重启时为 0,需要重启时为 1。这才是脚本应依据的结果。

if ! needs-restarting -r >/dev/null; then
  logger -t updates "reboot pending on $(hostname -s)"
fi

这里的退出代码 1 是正常结果,不表示失败。在 set -e 下,未进行保护的 needs-restarting -r 会让脚本在该行退出,因此上面的示例将它放在 if 中处理。

触发需要重启结果的软件包,是插件内部一份较短的硬编码列表。当前版本包含 kernel、kernel-core、kernel-rt、glibc、linux-firmware、systemd、dbus、dbus-broker、dbus-daemon 和 microcode_ctl。较旧的插件构建版本包含的列表略短,因此请检查实际版本,不要直接假设。

列表中的每个条目都有明确原因。新的 kernel 软件包只会将文件写入 /boot 和 /lib/modules,而正在运行的内核无法在自身运行期间被替换,因此必须在启动新内核后才会生效。系统中的每个进程都链接到 glibc,这意味着“重启受影响的服务”也包括重启 PID 1,而重启系统是更安全的处理方式。dbus 和 dbus-broker 承载系统上的所有客户端连接,因此在运行中的计算机上停止总线会中断正在使用它的客户端。linux-firmware 和 microcode_ctl 会在启动时加载;在 VPS 中,微码部分通常不会产生可观察的变化,因为物理 CPU 由虚拟机管理程序所在的主机负责。

您可以添加自己的软件包。/etc/dnf/plugins/needs-restarting.d/ 下的任何 .conf 文件都会被读取为软件包名称列表,每行一个名称,这些名称会加入重启列表。

echo 'openssl-libs' | sudo tee /etc/dnf/plugins/needs-restarting.d/openssl.conf

这是策略选择,不是修复措施。它表示:“TLS 库发生变化时,我宁愿重启,也不愿逐一排查所有已映射该库的服务。”

重启提示实际上依据什么得出

needs-restarting -r不会将当前运行的内核版本与最新安装的内核进行比较。它比较的是时间戳。对于核心软件包列表中的每个软件包,它都会读取 RPM 安装时间,并将其与系统启动时间进行比较。如果某个核心软件包的安装时间晚于上次启动时间,结果就是“需要重启”。如果可用,启动时间通过 D-Bus 从 systemd 的 UnitsLoadStartTimestamp 获取;否则,使用 /proc/1 的修改时间和 /proc/stat 中的 btime 字段两者中较晚的时间。

这一机制有一个需要注意的后果。如果你安装内核后重启,但由于启动默认项被固定,系统又进入了较旧的内核,那么安装时间现在早于启动时间,needs-restarting -r 就不会再提示。它正确回答了自己的问题,但不是你提出的问题。请单独检查内核。

uname -r
rpm -q --last kernel
sudo grubby --default-kernel

第一条命令显示当前运行的内核。rpm -q --last kernel 的第一行是最近安装的内核。grubby --default-kernel 显示引导加载程序下次将选择的内核。如果这三者不一致,请先修复启动默认项,再重启无法通过控制台访问的机器。

第 2 级:需要重启服务的更新

当 RPM 替换共享库时,它会解除旧文件的链接并写入新文件。已经映射旧文件的进程会继续保留旧 inode,并继续执行旧代码。openssl-libs 是最需要关注的情况:libcrypto 中的修复只有在 Web 服务器重启后才会生效。

sudo needs-restarting -s

此命令会列出以下 systemd 服务:服务自身的文件,或其依赖项的文件,在服务启动后已被更新。请使用 sudo。如果没有 root 权限,该工具只能读取属于您自己进程的 /proc 条目,因此会静默漏报,较短的列表看起来像是好消息。

sudo needs-restarting
sudo needs-restarting --exclude-services

第一个命令会输出每个受影响进程的 PID 和命令行。第二个命令会排除已经由 systemd 服务覆盖的进程,留下登录 shell、tmux 会话、cron 作业以及您手动启动的进程。这些进程不会自行重启。

如果列表中的服务同时属于重启级别的软件包,该工具会在其上方输出 Warning: The following services should not be restarted but require a reboot:。请按字面含义处理,并改为重启系统。

依次重启其余服务。每重启一个服务后,先检查确认,再处理下一个。

sudo systemctl restart nginx
systemctl status nginx

不要将列表通过管道传给 systemctl restart。原因是您自己的 SSH 会话。在 RHEL 系列系统中,sshd.service 随 KillMode=process 一起提供,因此重启它时只会向监听守护进程发送信号,而不会终止每个连接对应的进程,打开的会话可以继续保持。请在您自己的服务器上使用 systemctl cat sshd | grep KillMode 确认这一点;无论如何,第一次操作时都应保留第二个会话。

不使用 DNF 也可以找到相同的进程。需要查看涉及的文件路径时,这种方式很有用:

sudo dnf install -y lsof
sudo lsof -n +c 0 2>/dev/null | grep -w DEL

DEL 表示某个已映射的文件已从磁盘删除。执行操作前先查看路径。已删除的临时文件和以内存为后端的文件也会出现在这里,但它们并不是重启任何服务的理由。

第 3 级:其他所有情况

大多数更新都属于这一类,无需执行任何额外操作。某个软件包中的文件只有在命令启动时才会读取,例如 curl、tar、vim 本身或 dnf。RPM 完成后,更新就已完全生效,因为下次运行时会读取新的二进制文件。配置文件、脚本、文档和数据软件包的处理方式相同。needs-restarting 不会提到其中任何一个,这种没有提示的结果是正确答案,并不表示检测遗漏。

这一类唯一需要注意的是进程持续运行时间。更新前启动的进程会继续使用旧的可执行文件,直到进程退出,即使该软件包看似不重要。这正是 sudo needs-restarting --exclude-services 的作用。

为什么使用 dnf-automatic 的机器数周都可能带有未应用的修复

这正是三层机制不再只是概念的地方。使用 dnf-automatic 自动更新会按计划安装软件包,而 /etc/dnf/automatic.conf 中的默认 reboot 设置是 never。启用 apply_updates = yes 和 reboot = never 后,机器可以在 6 周内安装 6 次内核更新和一次 glibc 修复,但仍然运行第 0 周启动时使用的内核和 C 库。更新日志看起来完全正常,但正在运行的系统没有应用这些更新。

修复方法是在 /etc/dnf/automatic.conf 中添加以下 3 行:

[commands]
upgrade_type = security
apply_updates = yes
reboot = when-needed
reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"

reboot 接受 never、when-changed 和 when-needed。never 是默认值,所有决定都由您手动作出。when-changed 会在任何改变软件包的事务完成后重启系统,方式简单直接,但行为可预测。when-needed 会询问 DNF 刚刚执行的事务是否要求重启,因此仅更新用户空间的更新夜间任务可以不重启。reboot_command 是实际执行的操作,默认会提前 5 分钟通知已登录的用户。设置 random_sleep 和计时器的计划,使重启发生在您可以观察机器恢复的维护窗口内。

使用 systemctl list-timers 'dnf-*' 检查您启用的是哪个单元。dnf-automatic 会随附多个变体,它们的行为并不完全相同,因此仅查看配置文件无法确定实际运行的内容。

计划任务运行后,不要只看日志,直接向机器确认:

needs-restarting -r; echo "exit: $?"
uname -r
rpm -q --last kernel | head -1

如果无法安排重启,在 VPS 上实时修补内核是另一种方案。它可以在不重启的情况下,将某些内核修复应用到正在运行的内核。它只能处理一部分内核问题,对 glibc 或您的服务不起作用,因此应将其视为延长重启间隔的方法,而不是完全停止重启。需要重启时,请有意执行并保持登录,直到机器响应,因为内核更新是机器无法恢复的最常见原因。对于没有控制台访问权限的主机,重启前请阅读VPS 在内核更新后无法启动时的处理方法,并将重启检查纳入定期服务器维护清单,避免只有发生故障后才想起这项检查。

Ubuntu 和 Debian 上执行同一任务

混合使用多种发行版的服务器需要对应的实现。在 Ubuntu 和 Debian 上,重启标志是一个文件,而不是命令:软件包脚本会创建 /run/reboot-required,/run/reboot-required.pkgs 会列出请求创建该标志的所有软件包,因此 [ -f /run/reboot-required ] 是 needs-restarting -r 的直接等价用法。较早的文档会写成 /var/run/reboot-required,它指向同一个文件,因为 /var/run 是指向 /run 的符号链接。服务端对应的是 needrestart。近期的 Ubuntu Server 版本默认会安装它。该服务会在 apt upgrade 期间运行,也可以单独使用 sudo needrestart -r l,仅列出需要重启的内容而不执行任何操作。这里同样存在自动更新方面的缺口,修复方法也相同:Ubuntu 上的 unattended-upgrades 会在 /etc/apt/apt.conf.d/50unattended-upgrades 中接收 Unattended-Upgrade::Automatic-Reboot "true"; 和 Unattended-Upgrade::Automatic-Reboot-Time "02:00";。

故障模式及其现象

  • needs-restarting: command not found 表示未安装 yum-utils。请安装它,或改为调用 dnf needs-restarting;只要存在 dnf-plugins-core,后者即可工作。
  • 脚本在重启检查处停止,且不显示错误消息,说明 set -e 返回了退出码 1。该退出码表示“需要重启”。应根据该退出码进行分支处理,不要让它直接终止脚本。
  • 库更新后,needs-restarting -s 通常不输出任何内容,说明运行时未使用 sudo。没有 root 权限时,它只能看到当前用户自己的进程。
  • needs-restarting -r 报告无需重启,但 uname -r 显示旧版本,说明系统启动时使用的是较旧的内核。该检查会比较安装时间和启动时间,而这两个时间点都已早于当前时间。请查看 grubby --default-kernel。
  • 服务重启后几分钟,在下一次运行时又出现,通常表示它被其他组件重新启动,或该单元未能成功恢复。再次重启前,请先读取该单元的 systemctl status。

FAQ

dnf update 会在 Rocky Linux 上重启服务吗?

通常不会。事务会写入文件,然后结束。部分软件包包含 RPM scriptlet,升级时会重启自身服务,因此具体行为取决于软件包,而不是系统级保证。应以 sudo needs-restarting -s 的结果为准:它会列出服务启动后发生变化的服务文件,或其依赖项中发生变化的文件,无论 scriptlet 执行了什么操作。

为什么安装了更新的内核后,needs-restarting -r 仍显示不需要重启?

因为它会将少量核心软件包的 RPM 安装时间与系统启动时间进行比较。它不会比较当前运行的内核版本与已安装的最新内核版本。如果安装内核后重启,但由于引导加载程序的默认配置指向旧内核,系统又使用旧内核启动,那么安装时间早于启动时间,检查结果就不会提示需要重启。运行 uname -r、rpm -q --last kernel 和 sudo grubby --default-kernel,查看实际情况。

Rocky 和 Alma 上哪些软件包会触发重启提示?

插件内部有一个硬编码列表。在当前版本中,该列表包含 kernel、kernel-core、kernel-rt、glibc、linux-firmware、systemd、dbus、dbus-broker、dbus-daemon 和 microcode_ctl。您可以扩展该列表:将包含软件包名称的 .conf 文件放入 /etc/dnf/plugins/needs-restarting.d/,每行写一个名称。这些名称也会计入重启判断结果。

dnf-automatic 能自行重启服务器吗?

可以。在 /etc/dnf/automatic.conf 的 [commands] 部分设置 reboot = when-needed,只有它执行的事务要求重启时才会重启服务器。when-changed 会在任意软件包发生更改后重启,never 是默认设置。reboot_command 控制重启方式,其默认值会向已登录用户提前五分钟发出警告。只有在您能够恢复系统启动的机器上启用此功能,因为无法访问控制台的 VPS 发生无人值守重启时,可能会进入难以恢复的故障状态。

needs-restarting 能检测容器内的进程吗?

不能有效检测。它会将运行中的进程与主机的 RPM 数据库进行匹配,而容器镜像中的软件包不在该数据库中,因此镜像中预置的过期库不会显示出来。请重新构建镜像并重新部署。主机侧仍然相关:容器运行时和容器共享的内核都属于主机软件包,并且会被检测到。