VPS 内核更新后无法启动的恢复与修复指南
VPS 内核更新后无法启动?本文详解通过服务商控制台进入 GRUB 菜单选择旧内核的方法,涵盖 initramfs 故障排查、救援模式使用及预防措施。无需重装系统,即可快速恢复服务器访问权限。
内核更新后 VPS 无法启动时的首要操作
如果 VPS 在内核更新后无法启动,通常几分钟内即可恢复,因为更新操作并未删除之前正常的内核。Ubuntu 会在安装新内核的同时保留旧内核,仅修改 GRUB 的默认启动项。因此,首要操作并非修复系统,而是在启动菜单中选择之前的内核,恢复登录提示符,然后在运行中的系统中进行诊断。
在服务器上修复此问题与修复笔记本电脑不同,因为服务器没有连接键盘,也没有显示器来展示内核崩溃信息。SSH 也无法连接,因为机器尚未运行到启动 sshd 的阶段。以下所有操作均需通过服务商提供的控制台完成。
在进行任何更改前,请先阅读控制台输出。屏幕上的文本决定了故障类别,两台同样“无法启动”的服务器可能需要截然不同的修复方案。
当 SSH 无法连接时,如何访问控制台?
打开服务商的控制面板并查找控制台入口。常见的名称包括 VNC console、web console、noVNC 和 serial console。如果两者同时存在,优先选择串口控制台(serial console),因为它提供可滚动和复制的真实文本,而 VNC 视图仅是屏幕的图像。请在机器运行正常时找到此功能并确认其可用。在故障期间临时寻找该功能会影响排障所需的冷静。此项检查应归入 新 VPS 的前十分钟配置,与防火墙规则和 SSH 密钥配置并列。
大多数面板还提供救援模式(rescue mode)或恢复镜像。它会从服务商网络引导一个小型系统,并将你的磁盘作为额外设备挂载,因此磁盘上的任何程序都不会运行。救援模式是 GRUB 本身损坏时的备用方案,也是当你决定放弃服务器时导出数据的途径。
你通常需要通过面板执行硬重启(hard reset)来进入引导菜单,因为无法登录的机器无法运行 sudo reboot。硬重启等同于断电。文件系统会因此遭遇非正常关机,因此请预期在下次启动时进行文件系统检查。
如何在 GRUB 菜单中选择旧版本内核?
从按下重启键的那一刻起,请密切监视控制台。在启动的前几秒内反复按下 Esc,如果机器处于传统 BIOS 引导模式,则按住 Shift。该窗口期很短,且控制台查看器通常需要一秒钟才能连接,因此请尽早开始并持续按键。
当菜单出现时,选择 “Advanced options for Ubuntu”。该子菜单会列出所有已安装的内核(按从新到旧排序),并为每个内核提供一个恢复模式条目。选择第二个正常条目(即版本次于最新的内核),然后按 Enter。恢复模式的作用不同:它会引导至最小化的单用户系统,仅用于修复工作,而非用于恢复服务运行。
如果旧内核能够引导,服务器即可恢复运行。确认当前使用的内核版本并记下版本号。
uname -r
dpkg -l 'linux-image-*' | grep '^ii'dpkg 的输出即为已安装内核的列表。如果列表中仅有一行,说明没有任何备用内核,这是首要需要解决的问题。
GRUB 菜单不显示,该怎么办?
云镜像通常会配置为隐藏菜单。Ubuntu 镜像通常会在 /etc/default/grub.d/ 下的文件中将超时时间设置为 0,因此系统会立即启动最新的内核,用户没有机会进行操作。
另一种情况则相反:菜单显示在屏幕上并处于等待状态,看起来像是系统挂起。GRUB 会记录启动失败,并在下次启动时保持菜单显示,直到有人按下按键。在没有键盘的服务器上,这种等待永远不会结束。如果控制台显示菜单且没有任何进展,就是这种情况。请选择一个条目并继续启动。
请在机器运行正常时修复这两个问题。编辑 /etc/default/grub:
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10
GRUB_RECORDFAIL_TIMEOUT=10
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200"随后应用更改并检查编辑是否生效,因为 /etc/default/grub.d/ 中的文件会在 /etc/default/grub 之后读取,可能会覆盖您的设置。
sudo update-grub
grep -rE 'TIMEOUT|TERMINAL' /etc/default/grub /etc/default/grub.d/GRUB_TERMINAL="console serial" 将菜单发送到图形控制台和串口,因此无论您使用哪种面板查看器,它都会显示出来。console= 内核参数对后续的启动消息执行相同的操作。每次启动延迟 10 秒,对于能在凌晨 2 点访问到的菜单来说,这是一个很小的代价。
我遇到了哪类故障?
查看控制台停止滚动前的最后 20 行日志。内核更新后的大多数故障都符合以下四种模式。
GRUB 无法找到其文件。 你会看到 grub rescue> 提示符,或者收到关于分区或文件不存在的错误,且没有任何内核消息出现。此时内核尚未介入。这通常是因为磁盘或分区发生变更,或者引导加载程序被写入了错误的设备,而非内核软件包本身的问题。
内核已启动但无法挂载根文件系统。 内核消息滚动后,你进入了一个提示符为 (initramfs) 的 busybox shell,或者启动过程因无法挂载根文件系统而崩溃(panic)。内核已加载。initramfs(用于查找并挂载真实根文件系统的临时小型根环境)未能找到磁盘。在 Ubuntu 上,此 shell 出现前通常会提示放弃等待根设备,并显示其查找的 UUID。复制该 UUID,稍后与 blkid 的输出进行比对。
逻辑卷未出现。 这是上述故障类别的特定原因。在 (initramfs) 提示符下,运行 ls /dev/mapper。如果输出中仅有 control,说明 LVM(逻辑卷管理器)卷未被激活,因此根设备尚未就绪。请手动激活卷组:
lvm vgchange -ay
ls /dev/mapper
exitexit 会将控制权交还给 initramfs 脚本,脚本将重试挂载。如果系统随后成功启动,说明新的 initramfs 缺少 LVM 组件,此时应重新构建该镜像,而非修改内核。
完全没有 Linux 的输出。 控制台显示固件文本、UEFI(统一可扩展固件接口)shell、黑屏且无内核输出,或者陷入重启循环。故障发生在 Linux 运行之前。系统恢复后,请检查服务器实际使用的模式,因为许多 VPS 实例在传统 BIOS 模式下启动,根本不会触及 EFI 路径:
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
mountpoint /boot/efi
sudo efibootmgr -v升级过程中 /boot/efi 未挂载是 UEFI 机器上的常见原因,因为负责维护 EFI 系统分区的软件包此时写入了一个普通的空目录。固件会持续启动旧的引导项,直到该项与磁盘上的内容不再匹配。
还有一种模式并非启动故障。如果你进入了提示系统处于紧急模式(emergency mode)的 root shell,说明内核已启动但用户空间停止运行。这通常意味着 /etc/fstab 中存在错误的配置行,或者文件系统检查失败。在该 shell 中运行 journalctl -xb,查看导致失败的单元名称。
内核软件包损坏还是 initramfs 损坏?
从控制台看,这两者表现一致,但修复方式不同。请引导至旧内核,然后对比文件。
ls -l /boot/vmlinuz-* /boot/initrd.img-*
df -h /boot对于每个已安装的版本,你需要一个 vmlinuz- 和一个匹配的 initrd.img-,且文件大小应合理。如果缺少 initrd,或者文件大小远小于其他版本,说明 initramfs 生成失败。常见原因是 /boot 已满,相关证据记录在软件包日志中:
sudo grep -iE 'no space|update-initramfs' /var/log/apt/term.log
sudo tail -n 40 /var/log/apt/history.loghistory.log 还会列出最近一次运行安装的软件包及其时间,这可以明确变更内容。
如果 /boot 已满,请先清理空间,然后为所需版本重建镜像并刷新菜单。请使用 ls 输出中的版本字符串,下方的占位符并非真实版本:
KVER=6.8.0-XX-generic
sudo update-initramfs -c -k "$KVER"
sudo update-grub
ls -l /boot/initrd.img-$KVER最后执行 ls 进行检查。如果文件大小正常,说明镜像已生成。如果内核镜像本身损坏,或者 dpkg -l 显示软件包状态不是 ii,请重新安装该软件包:
sudo apt install --reinstall linux-image-$KVER
sudo dpkg --configure -a当内核无法引导时从救援模式修复
如果引导菜单中的所有条目均失效,请引导服务商提供的救援镜像,并从外部修复磁盘。此时磁盘表现为未挂载的设备,因此系统内没有任何进程在运行,也不会产生资源冲突。
完整的 chroot 修复流程
首先运行 lsblk -f,从本机读取真实的设备名称。/dev/vda 在 KVM 上很常见,而 Ubuntu Server 安装通常将根分区置于 LVM 上,即 /dev/ubuntu-vg/ubuntu-lv。
sudo lsblk -f
sudo vgchange -ay
sudo mount /dev/ubuntu-vg/ubuntu-lv /mnt
sudo mount /dev/vda2 /mnt/boot
sudo mount /dev/vda1 /mnt/boot/efi跳过不适用于您的步骤。许多镜像没有单独的 /boot 分区,也没有 EFI 分区。随后绑定内核接口并进入系统:
for d in dev proc sys run; do sudo mount --rbind /$d /mnt/$d; done
sudo chroot /mnt /bin/bash在 chroot 环境内,您是在底层运行健康内核的情况下操作损坏的系统。请在此处执行修复:
df -h /boot
update-initramfs -u -k all
update-grub
grub-install /dev/vda
exitgrub-install 在 BIOS 系统上作用于整个磁盘,而非分区。在 UEFI 系统上请使用 grub-install --target=x86_64-efi --efi-directory=/boot/efi,并在运行前确认该目录已挂载。使用 exit 退出,通过 sudo umount -R /mnt 卸载所有挂载点,随后在控制面板切回正常引导并重启。
测试新内核而不影响下次启动
GRUB 支持单次启动某个条目,随后自动回退至默认配置。将默认项设为您信任的内核,然后仅为本次启动加载新内核。如果新内核启动失败,通过控制面板进行硬重启即可恢复至原内核,无需在有限的时间窗口内操作控制台。
在 /etc/default/grub 中设置 GRUB_DEFAULT=saved,运行 sudo update-grub,然后列出条目名称以便准确引用:
grep -E "(menuentry|submenu) " /boot/grub/grub.cfg | cut -d"'" -f2
sudo grub-set-default "Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-XX-generic"
sudo grub-editenv list
sudo grub-reboot 0
sudo rebootgrub-editenv list 应输出您选择的条目名称作为 saved_entry。该输出证明此机制生效,因为保存配置需要 /boot/grub/grubenv 可写,而某些分区布局下该操作可能静默失败。条目 0 位于菜单顶部,即最新内核。此处使用名称比使用数字更安全,因为每当安装或移除内核时,数字索引都会发生变化。
为什么在无头服务器上使用 autoremove 存在风险
APT 会维护一份内核包列表,禁止自动移除其中的内容。查看你的列表:
cat /etc/apt/apt.conf.d/01autoremove-kernels
dpkg -l 'linux-image-*' | grep -c '^ii'该文件会在内核包变更时重新生成,用于保护当前运行的内核及最近的内核版本。风险在于时间差。如果在重启进入新内核后立即运行 sudo apt autoremove --purge,受保护列表已经更新,你所依赖的旧内核将不再受保护。对于有键盘的机器,这只是不便;但对于无头服务器,这意味着你必须在引导菜单中手动选择,或者从救援镜像挂载磁盘。
建议保留至少两个内核,如果 /boot 空间充足则保留三个。在检查 uname -r 后按名称移除旧内核,这样可以确保永远不会删除当前正在运行的版本:
uname -r
sudo apt purge linux-image-6.8.0-XX-generic
dpkg -l 'linux-image-*' | grep '^ii'执行完上述最后一条命令后,再次运行查看命令。如果数量从三个变为两个,说明清理成功。如果数量变为一个,则意味着下一次重启时可能会发生故障。
升级前创建快照
在 apt upgrade 之前创建快照是无需引导系统即可恢复的唯一路径。恢复快照可将磁盘还原至旧内核为默认内核的状态,此时你可以保持控制台开启并重新尝试升级。运行中机器的快照属于崩溃一致性(crash consistent)快照,即捕获的磁盘状态等同于断电瞬间,因此若服务商支持离线快照,请先关闭服务器。快照不等同于备份,因为它通常存储在与源卷相同的基础设施上。理解 VPS 快照与真实备份的区别 决定了当故障范围超出内核层面时,哪种方式能挽救你的数据。
在进行版本升级时,这一点尤为重要,因为内核、initramfs 工具、引导加载程序和 GRUB 配置都会在一次操作中发生变更。请在开始 从 Ubuntu 24.04 升级到 26.04 之前立即创建快照,不要在前一天晚上创建,以确保还原点与你即将变更的机器状态完全匹配。
unattended-upgrades 如何处理内核软件包
Ubuntu 的 unattended-upgrades 会自动安装安全更新,内核软件包与其他更新一样通过安全源仓库获取。这会带来两个后果。
首先,新内核已安装但尚未运行。内核仅在引导时生效。系统会出现 /var/run/reboot-required 文件,/var/run/reboot-required.pkgs 会记录请求重启的原因,但除非你在 /etc/apt/apt.conf.d/50unattended-upgrades 中启用了 Unattended-Upgrade::Automatic-Reboot,否则系统不会自动重启。
cat /var/run/reboot-required.pkgs
grep -E 'Automatic-Reboot|Blacklist' /etc/apt/apt.conf.d/50unattended-upgrades其次,这种时间差会掩盖故障原因。服务器可能在 3 月安装了内核,却因完全无关的原因在 6 月重启,随后导致无法启动。导致引导失败的变更发生在三个月前,因此当天的操作无法解释该问题。你可以在 /var/log/apt/history.log 中找到安装该内核时的运行记录,从而排查当前故障。
请在选定的日期主动执行重启,并保持控制台窗口开启。这一习惯可将突发的故障排查转变为两分钟的常规操作。如果你希望保留自动化安装但避免意外重启,请保持自动安装开启并关闭自动重启,具体设置请参考 如何在 Ubuntu 上配置 unattended-upgrades。使用 sudo apt-mark hold linux-image-generic 锁定内核软件包会完全停止其更新,这同时也意味着停止了内核安全修复,因此请将其视为一种权衡决策,而非安全措施。
FAQ
如何在没有键盘的 VPS 上引导旧内核?
打开服务商提供的控制台(VNC 或串口),并在控制面板执行硬重启,因为此时无法通过正常登录进行重启。机器重启时,反复按 Esc,或在传统 BIOS 引导下按住 Shift,以停留在 GRUB 菜单。选择 "Advanced options for Ubuntu",然后选择最新内核下方的条目。进入登录提示符后,运行 uname -r 确认当前内核版本,并运行 dpkg -l 'linux-image-*' 查看已安装的其他内核。待系统恢复运行后再进行诊断。
为什么我的 VPS 完全不显示 GRUB 菜单?
云镜像通常会将 /etc/default/grub.d/ 下文件的 GRUB 超时时间设置为 0,因此系统会直接启动最新内核,不留任何按键时间。请在 /etc/default/grub 中设置 GRUB_TIMEOUT=10 和 GRUB_TIMEOUT_STYLE=menu,添加 GRUB_TERMINAL="console serial" 以便菜单输出到串口控制台,然后运行 sudo update-grub。最后使用 grep -r TIMEOUT /etc/default/grub /etc/default/grub.d/ 进行验证,因为该目录下的文件会在主文件之后读取,可能会覆盖你的修改。
我应该删除旧内核以释放 /boot 空间吗?
删除最旧的内核,但至少保留两个。/boot 空间占满本身就是一种故障模式,因为这会导致 initramfs 生成失败,最终使你只剩下一个没有可用镜像的内核。在检查 uname -r 后,通过精确的包名进行清理,确保当前运行的内核不会被误删。在无头服务器(headless machine)上避免使用批量 sudo apt autoremove --purge,因为受保护内核列表会在每次内核变更时重新生成,时机不当的操作可能导致你只剩下一个内核,且菜单中没有备用条目。
unattended-upgrades 会导致引导失败吗?
它可能会安装一个后续无法引导的内核,但除非在 /etc/apt/apt.conf.d/50unattended-upgrades 中将 Unattended-Upgrade::Automatic-Reboot 设置为 true,否则它不会自动重启机器。常见的模式是延迟故障:内核在自动更新期间安装,/var/run/reboot-required 出现,而问题直到几周后你下次重启时才会显现。请在打开控制台的情况下主动重启,并阅读 /var/log/apt/history.log 以查找是哪次运行安装了你当前引导的内核。