VPS实时内核修补和重启有什么区别?
实时内核修补会把修复后的函数加载到运行中的内核,无需断开连接。了解非托管VPS如何启用、能覆盖什么,以及为何最多只是推迟重启。
VPS 上的实时内核修补可以做什么
实时内核修补可在运行中的计算机上应用内核安全修复,无需重启,也不会断开现有连接。修复后的函数副本会作为内核模块加载。系统会将对旧函数的每次调用重定向到新副本,同时服务器继续处理网络流量。这一机制同时说明了实时修补的作用及其局限。
它只能争取时间,不能免除重启。运行实时内核修补达六个月的服务器,磁盘上的旧内核映像仍然是当前启动使用的映像,而且这些修补内容都只存在于内存中。
实时内核修补通常被作为托管方案的功能销售。在非托管服务器上,您可以使用两条命令自行启用它。在支付 托管 VPS 与非托管 VPS 之间的差价前,了解这一点很有必要。
实时内核修补如何工作?
内核内置了实时修补核心,并通过 CONFIG_LIVEPATCH 编译启用。检查正在运行的内核是否包含该核心:
grep CONFIG_LIVEPATCH /boot/config-$(uname -r)如果输出中包含 CONFIG_LIVEPATCH=y,表示当前运行的内核在构建时已包含该核心。没有该核心时,任何实时修补服务都无法在这台机器上执行操作。
重定向本身使用 ftrace,即内核的函数跟踪器。大多数内核函数在编译时,都会在函数最开头生成一条调用指令,此时函数参数和栈尚未被修改。ftrace 使用这个调用位置作为钩子。应用补丁时,实时修补核心会在目标函数上注册 ftrace 处理程序,由该处理程序将执行转到替代函数。内核文档对此有明确说明:“实时修补通常需要在函数入口最开始处重定向代码,此时函数参数或栈尚未发生任何修改。”
这句话带来两个后果,后文都会涉及。只有 ftrace 可以挂钩的函数才能修补,因此,未编译入口调用指令的函数完全无法修补。修补的基本单位是整个函数,不能只修补函数中的某一行。
更复杂的部分是如何安全地切换正在运行的系统。如果替换函数时,旧代码仍在某个 CPU 的栈上运行,系统就会同时出现新旧行为。上游 Linux 使用每任务一致性模型处理这一问题。内核文档将其描述为一种混合模型:“它结合了 kGraft 的每任务一致性和系统调用屏障切换,以及 kpatch 的栈回溯切换。”任务会逐个迁移到新代码,但只有在内核能够确认该任务当前不在已修补函数内部时才会迁移。在所有任务完成迁移前,补丁都处于过渡状态。
您可以自行查看结果。已应用的补丁会显示在 /sys/kernel/livepatch 下,每个补丁对应一个目录,目录中列出了已修补的函数。
ls /sys/kernel/livepatch/列表为空表示内存中没有加载实时补丁。对于刚部署的服务器,这是正常的初始状态。
实时内核修补无法修复的内容
只有函数体会被修补。其他内容不会被修补。
- 已更改的数据结构。 如果上游修复向某个 struct 添加字段,或改变现有字段的含义,就无法安全地重写已经分配并正在使用的对象。kpatch 项目直接说明了对应情况:“不直接支持修改静态分配数据的补丁。”可以使用影子变量和回调作为变通方案,但这些方案需要针对每个补丁手工编写,并非自动完成。
- 同时分布在多个函数中的修复。 如果修复需要改变一组函数之间的锁顺序,就必须同时修改所有这些函数;而一致性模型会切换任务,而不是在同一时刻冻结整台机器。
- 初始化代码。 标记为
__init的函数在服务器启动完成时已经运行并被释放,因此没有可供重定向的内容。 - 新的内核版本和新功能。 实时修补只能在同一个内核系列内移动补丁级别。它不会将内核从一个系列升级到下一个系列,也不会添加功能。如果需要更新系列中的内容,例如 Linux 7.1 中引入的更改,就必须安装该内核并启动它。
- 用户空间。 Canonical 明确说明了边界:“Canonical Livepatch 不会修补 OpenSSL 或 glibc 等用户空间库,因为这属于 unattended-upgrades 或系统管理工具的职责。”实时修补的内核与过时的 OpenSSL 并存,并不表示服务器已完成修补,因此应让同一台服务器上的 unattended upgrades 负责处理用户空间软件包。
Ubuntu 的这项服务还存在严重性边界。Canonical 表示,它“会修补具有严重和高 Common Vulnerability Scoring System (CVSS) 及 Ubuntu 优先级评级的内核漏洞”。CVE(common vulnerabilities and exposures)标识符用于命名单个缺陷,CVSS 则是附加到该缺陷上的评分。中等评级的内核 CVE 会在磁盘上的软件包中修复,但不会进行实时修补,因此要等到下一次重启时才会应用到正在运行的内核,之前不会生效。
有哪些在线内核修补方案?
目前常用的方案有三条技术路线,但它们都使用相同的内核机制。
Canonical Livepatch 通过 Ubuntu Pro 提供。个人用户可免费使用 Ubuntu Pro。Canonical 的表述是,该服务“现在以及未来始终对个人用户免费”,最多支持 5 台物理机;Ubuntu 官方社区成员最多可使用 50 台。这是截至 2026 年 8 月的文档规定上限。商业用途需要付费订阅。支持范围按内核系列和内核 flavour 分配,覆盖受支持长期支持(LTS)版本的通用可用性(GA)内核及其硬件支持(HWE)内核,flavour 包括 generic、aws、azure、gcp、oracle、ibm 和 lowlatency。在依赖该服务前,请将自己的内核与 Canonical 发布的内核列表进行核对。
KernelCare 由 TuxCare 提供,是一款商业代理,支持许多发行版,包括没有第一方服务的发行版。其文档规定的安装方式是运行供应商脚本 curl -s -L https://kernelcare.com/installer | bash,然后运行 /usr/bin/kcarectl --register KEY 配置基于密钥的许可证。代理会按自身计划检查新补丁,运行 /usr/bin/kcarectl --update 可强制执行检查。在服务器上执行将脚本通过管道传给 shell 之前,请先阅读安装脚本。
kpatch 和 kGraft 是早期方案。kGraft 源自 SUSE,kpatch 源自 Red Hat。如今上游 Linux 中的在线内核修补核心融合了两者的设计。kpatch 本身正在逐步退出使用:其 README 声明,从 Linux 6.19 起,“kpatch 项目已弃用并进入维护模式”;在上游内核中,kpatch-build 将由 klp-build 取代。在 RHEL 及其重构发行版上,应使用发行版自带的服务,而不是手动构建补丁。
请根据发行版支持范围和许可证条件进行选择。每种方案在内核层面产生的结果相同。
如何在 Ubuntu 上启用 Canonical Livepatch
首先从 Ubuntu Pro 账户页面获取令牌。下面两个命令都需要正常的出站网络访问,因为客户端需要与 Canonical 服务器通信,以完成关联并获取补丁。
sudo pro attach TOKEN
sudo pro status不带令牌运行 sudo pro attach 时,会改为启动基于浏览器的流程,并输出一个需要在 Canonical 网站上输入的代码。完成关联后,系统会自动启用推荐的服务;在当前的 LTS 版本中,这包括 Livepatch。如果希望自行选择服务,请使用 sudo pro attach --no-auto-enable。
如果 Livepatch 尚未启用:
sudo pro enable livepatch
sudo canonical-livepatch status该服务通过 canonical-livepatch snap 运行,因此必须确保 snapd 正常工作,启用操作才能完成。pro status 会输出包含服务授权状态和运行状态的表格。canonical-livepatch status 会输出每个内核的详细信息。Canonical 文档中的输出格式如下:
last check: 52 seconds ago
kernel: 5.4.0-216.236-generic
server check-in: succeeded
kernel state: ✓ kernel series 5.4 is covered by Livepatch
patch state: ✓ all applicable livepatch kernel modules applied
patch version: 113.1其中两行可以直接判断结果。kernel state 表示当前运行的内核系列是否受该服务支持。如果启动的内核不受 Livepatch 支持,该行会显示异常。patch state 表示适用于该内核的补丁是否已实际加载。受支持但没有应用补丁,说明是客户端问题。不受支持则是内核问题,任何客户端设置都无法解决。
如何判断系统是否等待重启?
实时内核修补消除了紧急性,因此待重启状态不再明显。您需要主动检查。
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs当已安装的软件包需要重启才能生效时,软件包管理器会创建 /var/run/reboot-required;每次安装新的 linux-image 软件包时,也一定会创建该文件。.pkgs 文件会列出发出请求的软件包。如果第一条命令返回 No such file or directory,则表示自上次启动以来没有任何软件包请求重启。在当前版本的 Ubuntu 中,/var/run 是指向 /run 的符号链接,因此使用任一路径都能访问同一个文件。
该标记位于 tmpfs 中,每次启动都会重置。因此,请直接对照内核进行确认:
uname -r
dpkg -l 'linux-image-*' | grep ^iiuname -r 会输出当前正在运行的内核。第二条命令会输出磁盘上已安装的内核软件包。如果列表中的 linux-image 比 uname -r 报告的版本更新,说明系统仍在运行旧内核,无论 Livepatch 状态如何。这项检查最重要,因为实时内核修补的目标是确保正在运行的内核安全,而不是使其保持最新。
对于同一问题的用户空间部分,needrestart 默认安装在 Ubuntu Server 上,并会列出仍持有已删除库文件的运行中服务。
sudo needrestart -r l-r l 标志组合表示“仅列出”,因此只报告结果,不会进行任何更改。
为什么重启始终无法避免
磁盘上的内核没有变化。实时补丁会加载到正在运行的内核中,但不会写入引导映像。因此,重启后系统会使用引导加载程序选择的 linux-image 启动,Livepatch 客户端随后会重新应用仍然适用的补丁。在这两个时刻之间,系统运行的是未打补丁的代码。这也是应启动当前内核而不是旧内核的另一个原因。
补丁覆盖范围按内核系列划分,内核系列也会停止维护。当正在运行的系列从支持列表中移除后,kernel state 行将不再报告覆盖范围,唯一的解决方法是使用更新的内核。这就需要重启。在 LTS 版本中,更新的系列通常会以硬件支持内核的形式随 26.04.1 等点版本提供。因此,替换用的内核已经位于软件仓库中,剩下的只是安排一次启动。
中等和低严重性级别的内核修复从不使用实时补丁。它们会保存在磁盘上的软件包中,只有启动后才会生效。
长时间运行的内核还会积累实时打补丁无法清理的状态。Canonical 的立场值得引用,因为这是一种诚实的说法:Livepatch “不能替代重启。它是一种工具,可以通过避免非计划重启,让您获得更多控制权。”其中承载核心含义的词是 非计划。您仍然需要重启,只是可以自行选择时间。
如何安排可恢复的重启
如果无法访问控制台,VPS 重启就是单向操作。在输入 reboot 之前,请先确认机器未能恢复时您仍能重新登录。
- 确认服务商在控制面板中提供串行控制台或 VNC(虚拟网络计算)视图,并立即打开,而不要等到发生中断时再打开。
- 使用
df -h /boot检查可用空间。/boot已满时,内核软件包在写入其 initramfs(初始 RAM 文件系统)时会失败,可能导致引导加载程序条目指向一个未完成写入的镜像。 - 至少保留一个已知可用的旧内核。GRUB 会在“Ubuntu 的高级选项”下列出它。新内核启动失败时,启动旧内核是最快的恢复方法。
- 提前找到服务商的救援模式。重启后,如果控制台显示 initramfs 提示符,应在该环境中进行修复。
然后选择您清醒且便于操作的时间执行重启:
sudo shutdown -r +5 "Kernel update, back in a moment"该命令会将重启安排在 5 分钟后,并向已登录用户发送消息。sudo shutdown -c 可取消该计划。机器恢复后,确认以下两部分:
uname -r
sudo canonical-livepatch status此时 uname -r 应报告较新的内核,状态输出也应报告新系列已涵盖。如果机器完全无法恢复,故障几乎总是出在引导路径,而不是网络。此时应使用VPS 内核更新后无法启动的排障指南中的恢复方法。
为什么仍需清理旧内核
实时内核修补并没有解决这个问题,反而会使问题加重,因为在 linux-image 软件包持续安装的情况下,系统不再有重启的压力。每个内核都会安装启动镜像、initramfs、模块树,通常还会安装 headers 软件包。在只有几百兆字节独立 /boot 分区的小型 VPS 上,安装三四个内核就会将其占满。
/boot 已满后,下次安装内核就会失败,导致系统无法安装自己需要的更新。apt autoremove 流程会在旧内核符合条件后将其清理,但对于从不重启的服务器,这些内核不一定已经符合条件,因为软件包管理器不会删除您可能仍在使用的内核。
因此,请检查已安装的内核,保留正在运行的内核和一个已知正常的备用内核,然后按照在 Ubuntu 上安全删除旧内核的操作步骤删除其余内核。绝不要删除 uname -r 当前报告的内核。
FAQ
实时内核修补是否意味着 VPS 永远不需要重启?
不需要。实时补丁会加载到正在运行的内核中,不会写入启动映像,因此磁盘上的 linux-image 仍保持为您启动时使用的版本。Canonical 明确表示,Livepatch “不能替代重启,而是一种让您更好地控制重启时机的工具,可避免非计划重启”。当您的内核系列停止维护后,补丁覆盖范围也会结束;中等严重性内核修复也不会进行实时修补。请按照您选择的周期安排维护重启,不要等到系统被强制重启。
如何检查实时内核修补是否确实正在应用补丁?
运行 sudo canonical-livepatch status,查看两行输出。kernel state 报告当前运行的内核系列是否受该服务覆盖,patch state 报告该内核的补丁是否已加载。您也可以使用 ls /sys/kernel/livepatch/ 直接检查内核状态;该命令会为每个已加载的补丁列出一个目录。如果输出为空,表示当前没有任何补丁驻留在内存中,无论客户端报告什么状态。
Ubuntu Pro 在个人 VPS 上是否免费?
是,但有明确的限制。截至 August 2026,Canonical 的表述是,Ubuntu Pro “对个人用户始终免费,最多支持 5 台物理机器”;Ubuntu Community 官方成员最多可使用 50 台机器。商业用途需要付费订阅。您可以在 Ubuntu Pro 帐户页面获取令牌,然后使用 sudo pro attach TOKEN 绑定机器,再使用 sudo pro enable livepatch 启用该服务。
为什么 Livepatch 运行后,内核 CVE 仍显示为未修复?
通常有两个原因。修复可能低于严重性阈值,因为 Canonical 只对“具有严重和高 Common Vulnerability Scoring System (CVSS) 及 Ubuntu Priority 评级的内核漏洞”提供实时补丁,其余修复交由磁盘上的软件包处理。或者,该修复无法表示为对函数体的修改。例如,上游更改了数据结构,而实时修补无法安全地修改已经分配的对象。这两种情况的处理方式相同:安装更新后的内核软件包,并启动到该内核。
实时内核修补完全不覆盖哪些内容?
用户空间。Canonical 明确表示,Livepatch “不会修补 OpenSSL 或 glibc 等用户空间库,因为这属于 unattended-upgrades 或系统管理工具的职责”。它也无法提供新的内核版本或新功能,因为它只能替换您当前运行的内核系列中的函数体。此外,它无法修补 __init 函数,因为服务器启动后,这些函数已经运行完毕并从内存中释放。