服务器无法引导怎么救:GRUB 损坏与 fstab 写错的救援模式完整排查实战

服务器彻底起不来了,先把「能不能救」和「怎么救」分清

几乎每个个人站长都遇到过一次这样的夜晚:重启服务器之后 SSH 连不上、网站全白、面板也打不开,机房的救援控制台上只留下几行看不懂的报错。这时候最危险的不是故障本身,而是慌乱中乱敲命令——很多本来十分钟能修好的机器,是被误操作的 mkfs、dd 或者错误的 grub-install 彻底判了死刑。

这篇文章不讲空泛的运维理论,而是把「服务器无法引导」这一类故障拆成三条可执行的路:先判断故障发生在引导链的哪一环,再决定进救援模式用哪种方式挂载磁盘,最后用两种最典型的方式把开机救回来。整套流程在 Debian/Ubuntu 上是通用的,CentOS/Rocky 只是包管理器名字不同。

先把引导链拆开:BIOS/UEFI → GRUB → initramfs → 内核 → init

一台 Linux 服务器从按下电源到出现登录提示,中间会依次经过五个环节。故障定位的本质,就是判断「这台机器走到了哪一步才停住」。

  • 固件阶段:UEFI 固件读取 NVRAM 里的启动项,找到 /boot/efi/EFI/<distro>/grubx64.efi;传统 BIOS 则读 MBR 里的第一阶段引导代码。
  • GRUB 阶段:读取 /boot/grub/grub.cfg,加载内核和 initramfs。如果卡在这里,屏幕上通常会出现 grub> 提示符或 error: unknown filesystem。
  • initramfs 阶段:这是个临时根文件系统,负责加载磁盘控制器驱动、做 LVM/RAID 激活、按 UUID 找根分区。卡在这里的标志是 (initramfs) 提示符,或 Unable to find root device。
  • 内核阶段:内核开始接管硬件。这里的故障往往是内核 panic,屏幕上有 Kernel panic - not syncing。
  • init 阶段:systemd 开始拉起服务。走到这一步说明引导链已经通了,问题变成「某个服务起不来」,那属于另一个排查方向。

判断方法很简单:救援控制台截图上的最后一行文字,就是断点位置。看到 grub> 是 GRUB 阶段的问题;看到 (initramfs) 是 initramfs 的问题;看到 systemd 的 journal 输出,那就不用按这篇文章的思路救,直接去查服务。

进救援模式的三种方式,优先选哪一种

VPS 商家一般都会提供救援模式(Rescue Mode / Rescue System)。但「进救援模式」这个动作背后,其实有三种形态,能力差别很大:

方式一:救援系统 + 手工 chroot(最通用)

机房把一个独立的 Linux 镜像挂到你的机器上启动,你的原磁盘以 /dev/vda 之类的形式存在但不自动挂载。这种方式最灵活,也最接近「真实的根文件系统」,适合 GRUB 损坏、/boot 被清空、/etc/fstab 写错这一类故障。

方式二:救援系统 + 自动挂载原磁盘

部分商家(如 Hetzner)提供「挂载原磁盘到 /mnt 并自动 chroot」的选项。省事,但如果你的 fstab 本身是错的,自动挂载可能失败,于是又回到方式一。

方式三:VNC / KVM 控制台 + GRUB 命令行

如果故障仅仅在 GRUB 配置层面(比如 grub.cfg 里根分区 UUID 写错,但分区和内核文件都还在),完全不需要救援系统。直接在 GRUB 菜单按 e 编辑启动项,把 root=UUID=xxxx 改成正确的 UUID,Ctrl+X 启动,进去之后再永久修复。这是最省事的一条路,很多人却一上来就去开救援模式,白白多花二十分钟。

决策顺序建议是:能进 GRUB 菜单 → 用方式三改参数试;进不去或改完还是起不来 → 用方式一。

救援模式下手工挂载原系统:一套可复用的命令序列

这是整篇文章最核心的一段。很多教程轻描淡写地写一句「挂载后 chroot」,但真正卡住人的是挂载顺序——尤其是用了 LVM、独立 /boot、或者软件 RAID 的机器。

第一步:确认磁盘和分区布局

lsblk -f
blkid
fdisk -l /dev/vda

lsblk -f 会把分区树、文件系统类型和 UUID 一起列出来,是救援模式下最重要的一个命令。注意看有没有 lvm 类型的成员分区,以及哪个分区承载的是 /、哪个是 /boot、哪个是 /boot/efi。

第二步:激活 LVM(如果用了)

vgscan
vgchange -ay
lvs

救援镜像里的 LVM 缓存和你原来的系统是两套,vgchange -ay 之前 /dev/mapper/ 下什么都不会有,这是「挂载时报 no such device」的最常见原因。

第三步:按依赖顺序挂载

mkdir -p /mnt
mount /dev/mapper/vg0-root /mnt
mount /dev/vda2 /mnt/boot          # 如果有独立 /boot
mount /dev/vda1 /mnt/boot/efi      # UEFI 机器才有

顺序不能反:先挂根,再挂 /boot,最后挂 /boot/efi。挂错顺序会让后续的 grub-install 把东西写到 RAM 里的临时目录,重启后一切照旧,你会以为自己没修好。

第四步:绑定内核接口再 chroot

for d in dev dev/pts proc sys run; do mount --rbind /$d /mnt/$d; done
chroot /mnt /bin/bash
export PATH=/usr/sbin:/usr/bin:/sbin:/bin

少了 --rbind 这一步,chroot 之后 grub-install 会报 /dev/null: Permission denied 之类的怪错,或者更糟——静默写出一个不完整的引导记录。这一步是整套流程里最容易被跳过、后果最隐蔽的一步。

场景一:GRUB 损坏或被覆盖,如何重装引导

典型症状是开机直接进入 grub rescue>,或者提示 error: no such partition。常见起因有三个:装了双系统或重装了另一个系统覆盖了 MBR/EFI 分区;/boot 所在的 LV 被重建过;磁盘被 dd 或分区工具动过。

chroot 进原系统之后,先确认引导文件是否还在:

ls /boot/grub/grub.cfg
ls /boot/vmlinuz-* /boot/initrd.img-*

如果文件都还在,只是引导记录丢了,那么:

BIOS/Legacy 机器

grub-install /dev/vda
update-grub

注意 grub-install 后面跟的是磁盘(/dev/vda),不是分区(/dev/vda1)。写成分区是新手最常犯的错,会出现 Installing for i386-pc platform 之后直接报错的情况。

UEFI 机器

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck
update-grub

--efi-directory 必须指向已经挂载好的 ESP 分区。如果救援模式下忘了挂 ESP,命令会「成功」退出但实际什么都没装。装完之后建议再检查一下 NVRAM 里的启动项:

efibootmgr -v

如果列表里没有对应的启动项,可以用 efibootmgr -c -d /dev/vda -p 1 -L "debian" -l '\EFI\debian\grubx64.efi' 手动补一条。有些主板的 NVRAM 会被写满(常见于反复安装系统的机器),这时候要先 efibootmgr -b XXXX -B 删掉无用的旧条目。

场景二:fstab 写错导致启动卡在 initramfs

这是另一类高频故障,而且比 GRUB 损坏更隐蔽,因为引导链前半段完全正常。症状是:GRUB 菜单正常出现、内核开始加载、然后卡在 (initramfs) 提示符,或者反复输出 Timed out waiting for device dev-disk-by\x2duuid-xxxx.device。

根因通常是三件事之一:

  • 数据盘被摘掉或重建,但 /etc/fstab 里还留着它的 UUID 条目,systemd 一直在等这个永远不会出现的设备。
  • 换过云服务商或重建过磁盘,根分区 UUID 变了,而 /etc/fstab 和 grub.cfg 里还是旧值。
  • 把 nofail 漏掉了——对于非关键的数据盘,fstab 里必须带 nofail 选项,否则那块盘一有问题整台机器就起不来。

救援模式下修复很简单,但修复完必须验证:

blkid                      # 拿到真实的 UUID
vim /mnt/etc/fstab         # 对照修改
grep -v '^#' /mnt/etc/fstab | awk '{print $1, $2, $3}'

只改 fstab 还不够,如果根分区 UUID 也变了,grub.cfg 和 initramfs 里都还写着旧值:

chroot /mnt /bin/bash
update-grub
update-initramfs -u -k all

很多人只跑 update-grub 忘了 update-initramfs,结果重启后仍然卡在 initramfs。原因是根分区的解析发生在 initramfs 里,update-grub 只更新 GRUB 的配置文件,碰不到 initramfs 内部那份 /etc/fstab` 副本和 conf/conf.d/resume。两台命令都跑,才是完整的修复。

UEFI 特有的三个坑:ESP 分区、安全启动与 NVRAM

上面讲的流程在 BIOS 机器上基本不会出岔子,但 UEFI 机器有三个额外变量:

坑一:ESP 分区被格掉但机器还能启动

因为已经加载到内存里的内核不受影响,机器照样能跑,只是下次重启才暴雷。所以进救援模式之后,第一件事就应该 ls /boot/efi/EFI/ 确认目录还在。如果 ESP 被误格式化,需要重装 grub-efi 并重建 grubx64.efi。

坑二:Secure Boot 拒绝加载未签名的内核

如果你自己编译过内核或换过 DKMS 模块(比如第三方网卡驱动),重新安装 GRUB 之后 Secure Boot 可能拒绝引导,表现是黑屏或直接回到固件界面。排查方法是进固件设置看 Secure Boot 状态,或者用 mokutil --sb-state 查。临时排障可以在固件里关掉 Secure Boot,长期方案是用 mokutil --import 注册自签名密钥。注意这跟「升级内核后网卡驱动消失」是两件事——后者是 DKMS 重建失败,和签名无关,别混在一起查。

坑三:NVRAM 启动项顺序被改乱

装过多个系统或多次重装之后,efibootmgr -v 里可能堆积一大堆失效条目,甚至 BootOrder 里第一个指向已经不存在的设备。修复方式是先删无效条目,再用 efibootmgr -o 重排顺序:

efibootmgr -b 0003 -B          # 删除指定条目
efibootmgr -o 0001,0002        # 设定启动顺序

救援完成后的三件事:别在同一个坑里摔第二次

机器重新起来之后,故事还没结束。如果没有做下面三件事,下次故障大概率重演:

第一,确认引导配置已经落盘。重启前先 sync 并真正重启验证一次,不要只看着 grub-install 输出 Success 就以为万事大吉。很多 grub-install 的失败是静默的——它把文件写到了 chroot 里某个临时挂载点,重启后原样如初。验证方式是重启后再进一次救援模式看看 /boot/grub/grub.cfg 的修改时间是否更新了。

第二,把关键配置纳入版本管理或备份。/etc/fstab、/etc/default/grub、Nginx 站点配置、crontab 这几样加起来不到几十 KB,却是最容易让人开不了机的部分。用 etckeeper 把 /etc 纳入 git 是成本最低的做法,出问题时 git diff 一眼就能看出改坏了哪一行。

第三,准备一张能落地的救援清单。把本文这段挂载 + chroot 的命令序列存成一份文档,连同磁盘 UUID 表一起放在本机以外的位置(比如手机备忘录或另一台机器)。理由很实际:救援模式下的浏览器只能用另一台设备,而这时候你最需要的恰恰是这些命令。

顺带提醒一个容易忽略的细节:救援模式下挂载原系统的磁盘之前,先确认没有别的实例正在运行。云平台上的机器如果只是「关机」而不是「销毁」,磁盘是独占的;但如果开了快照挂载到另一台临时实例上做修复,务必保证同一时刻只有一台机器在写这块盘,否则会直接把文件系统写坏,那就不是引导问题而是数据恢复问题了。

小结

服务器无法引导这件事,看起来吓人,但排查路径其实高度结构化:先看屏幕最后一行定位断点(固件 / GRUB / initramfs / 内核 / init),再选救援方式(能进 GRUB 菜单优先改参数;否则进救援系统手工挂载),最后按故障类型修复(GRUB 重装走 grub-install + update-grub;fstab/UUID 问题走 update-grub + update-initramfs)。

真正容易翻车的从来不是命令本身,而是那两个容易被跳过的步骤:chroot 前的 mount --rbind,以及修复后的重启验证。把这两步当成本能反应,90% 的「救不回来」就不会发生。

Last modification:September 28th, 2026 at 12:24 pm

Leave a Comment