☰
Linux救援模式实战:从GRUB参数到chroot修复系统启动故障
2026/10/2 17:36:27 网站建设 项目流程

凌晨两点半,手机突然响了,机房那边的同事声音都在发抖:“兄弟,服务器进不去了,重启了好几次,开机菜单走一半就卡死,停在黑屏上,连登录界面都见不着。”这种场景,只要做过Linux运维的人,基本都碰过。启动流程走到一半黑屏、卡在开机logo、掉进一个莫名其妙的小shell,第一反应千万不要是“重装系统”,而是应该想起Linux救援模式。救援模式说白了就是一套“专门用来修系统的最小系统”:它不加载你硬盘上那个完整的系统,只给一个精简的shell环境,让你能检查磁盘、修复引导、重置密码、改掉写错的配置,最后把机器重新恢复到能启动的状态。这篇文章,我打算用真实故障案例帮你弄清楚救援模式到底是什么、有哪些入口、进去之后先干什么,顺便把我踩过的坑都摊开来讲。

1. 先搞清楚边界:救援模式和单用户模式、LiveCD到底有啥区别

很多刚接触Linux的人会把“救援模式”当成某一个发行版的专属功能,其实它是一套横跨所有主流发行版的启动挽救机制。要理解它,得先明白Linux正常启动时发生了什么。开机后BIOS或UEFI把GRUB加载起来,GRUB选择内核并加载initramfs(初始内存文件系统),这个initramfs里有一堆启动必需的驱动和工具,负责把真正的根文件系统挂载起来,然后切换过去,接着systemd开始按target启动服务。救援模式就是在不同阶段“截胡”出来的临时shell,目的只有一个:在你的完整系统已经没法正常工作的情况下,给你一个还能敲命令的环境。

1.1 systemd时代的两套“半系统”:rescue.target和emergency.target

现在的发行版基本都使用systemd,它内置了两个专门给故障维护用的启动目标:rescue.target和emergency.target。你可以把rescue.target理解成“基础系统已经挂载好、设备也基本识别了,但是没有任何业务服务在跑”的状态,它有基本的文件系统、udev设备管理,适合做修改配置、重装引导等操作。emergency.target则更简陋,它相当于在systemd刚起来、能读取文件但很多服务都没启动的阶段强行停下来给你一个root shell,通常连网络都不会配置。两者之间最直观的区别是“你已经能访问多少设备树”。实际使用中,rescue模式更适合查出问题原因,emergency模式则更接近“这台机器我只能手搓修复”的原始状态。

从老一代SysVinit继承过来的还有一个词叫“单用户模式”,当年在GRUB启动参数里加一个s、S或者数字1就能进入。现在的大部分systemd发行版里,这个行为被rescue.target取代,但不少老运维还是习惯叫它“单用户模式”。这没啥问题,反正核心思想是一样的:绕开正常启动流程,只把最基础的运行时准备好,交给你一个root shell。

1.2 内核initramfs里的break shell和安装盘救援模式

除了systemd的target机制,还有一种很多人用但不太清楚原理的入口,叫rd.break。这个词出自dracut,RHEL系、CentOS、Fedora这些发行版默认用dracut生成initramfs,你在GRUB内核参数后面附加rd.break,启动流程会在initramfs吃掉触发root挂载之前停下来,得到一个shell。此时系统还在initramfs环境里,你的真实根分区通常被挂载在/sysroot目录下但处于只读状态。这个入口有个天然的好处:不需要你原系统的root密码,因为这时根本还没切换进原系统,连影子密码文件都还没参与认证。

另一类是安装盘救援模式。你拿同一版本的安装ISO或Live镜像启动,在引导菜单里选择“Rescue a system”或者直接进Live桌面,然后把硬盘分区手动挂载起来。这种路径优势在于:即使你的GRUB已经损坏、内核文件丢失、甚至initramfs都坏了,只要镜像能动,照样可以进一个完整的系统去修硬盘。缺点是不能乱挂载,Restore模式里面的文件系统和修复工具的版本可能与原系统有差异,操作时心里要有数。

1.3 一张表分清常见场景该用哪个入口

写清楚各种入口的差异之后,最容易踩的坑其实是“不知道该用哪个”。我按实际故障场景给你整理了一下,之后遇到情况可以直接对照:

故障场景建议入口原因
忘记root密码rd.break或GRUB加rescue参数不需要原系统认证,直接可改密码
修改/etc/fstab导致启动卡死systemd.unit=emergency.target最简环境,先卸载挂载逻辑,再修复配置
GRUB菜单丢失、引导损坏安装ISO进Rescue模式原系统的一部分可能都起不来了,需要外部环境
根文件系统损坏、需要fsck任意救援入口只要能umount掉冲突分区,就能跑文件系统修复工具
硬件驱动异常、想换内核参数正常GRUB加参数,不一定要进救援模式很多启动问题是单次参数就能解决的

救援模式并不是一个“万能工具”,它的能力边界是:如果问题出在CPU、内存、硬盘颗粒这些硬件物理损坏上,救援模式也没辙。能修的是启动逻辑、配置、引导、文件系统元数据这些软件层面的事。

2. 进入救援模式的三种实操路径

知道了概念,接下来就是动手。我按通用性从高到低来写,先讲GRUB编辑启动参数,因为这一招能覆盖几乎所有发行版,而且不需要额外准备设备。

2.1 GRUB编辑启动参数:跨发行版最通用的一招

开机见到GRUB菜单时,先选中要启动的内核,然后按e进入编辑模式。别紧张,你不需要理解这一屏内容里每一项的意思,只需要找到那一行以linux开头的内核启动参数行。不同发行版这行长得不太一样,RHEL系一般是linux16 /vmlinuz-...或者linux /vmlinuz-...,Debian/Ubuntu则是linux /boot/vmlinuz-... ro quiet splash。在这行的末尾追加参数,注意和前面的参数之间留一个空格。

RHEL系和CentOS系,最常用的救援参数是rd.break。改完后按Ctrl+x或者F10启动,几秒后就会落进一个写着switch_root:/#的shell。Debian系、Ubuntu系更常用的追加参数是systemd.unit=rescue.target,或者更狠一点的systemd.unit=emergency.target,启动后会要求输入root密码,输对了就进入维护shell。这也是为什么你忘了密码的时候,Debian系你反而要想想别的办法,通常我会选择挂载ISO用Live环境去改,或者直接用recovery菜单(下面会讲)。

如果你把参数加错了也不用怕,重启再回到GRUB重新编辑就行。这整个动作没有写入任何磁盘,只是本次启动的一个临时选项。

2.2 开机菜单里直接选择rescue或recovery入口

不少发行版在GRUB菜单里其实已经放了救援入口,只是藏得深一点。Ubuntu桌面版安装完成后,GRUB菜单里有“Advanced options for Ubuntu”这一项,展开后能看到每个内核版本对应的“(recovery mode)”条目。选中进入会有一个Recovery Menu,里面提供“root Shell”选项,选它就直接拿到根目录下的root shell,菜单上还有“修复文件系统”和“网络”等入口。这里需要注意的是,这个Recovery模式下根文件系统最初是只读挂载的,你要先执行一次mount -o remount,rw /才能写操作。

RHEL系在早期版本里也有类似单用户入口,但新版大多只保留GRUB参数方案,所以我个人觉得“靠按e加参数”这种基础技能更保值。

2.3 安装ISO和虚拟机/云环境的特殊入口

物理机最稳的备胎是安装盘。用同一版本或更高版本的安装ISO启动,在引导菜单选“Rescue a system”或者类似名称(不同发行版叫法不太一样,CentOS的安装盘里是“Rescue a CentOS system”,Ubuntu Server则是进入Live环境后自己挂)。进入后会询问一些语言和键盘配置,然后让你选择要继续系统还是挂载原系统,选“继续”通常会自动发现你硬盘上的Linux分区,挂载到/mnt/sysimage,然后给你root shell。在这个shell里,你觉得哪里别扭都可以正常访问,因为chroot /mnt/sysimage之后你就会进入原系统的环境。

虚拟机场景更简单,直接把安装ISO作为光驱挂载,改启动顺序优先从光驱启动就行。云主机则要看厂商的控制台,一般叫“救援模式”或“Recovery”,本质是让你从一台临时维护镜像启动,然后你把原本的根卷挂载到/mnt去修。文章前面讲的那些挂载逻辑在云环境同样适用,差别只是你不用按GRUB的e,而是在网页控制台里操作,原理一模一样。

2.4 进入救援模式后如何判断自己在哪

有些朋友进了救援shell还迷迷糊糊,不知道自己是停在了initramfs还是rescue.target。教你两个快速判断的方法。第一看提示符:switch_root:/#或带dracut字样的通常是rd.break的initramfs环境;bash-x.x.x#或者系统主机名提示符一般是rescue/emergency模式。第二看根文件系统的挂载情况,执行mount | head,如果看到/sysroot挂载了你的根分区,说明你还在initramfs阶段;如果根目录直接就是你原来系统的目录结构,说明已经切根或chroot成功。这两个状态的操作方式差别很大,最典型的就是rd.break下必须先把/sysroot重新挂载成可写,否则你改什么都存不进去。

3. 救援模式里最高频的修复操作:重置密码、修fstab、重建GRUB

搞清楚环境之后,重点来看实战中修得最多的三件事。这三类故障基本上覆盖了“服务器半夜起不来”的七八成原因,也是救援模式存在的核心意义。

3.1 root密码忘了,用rd.break硬闯

RHEL系忘了root密码,最快的方法就是rd.break。完整流程如下,每一步都有讲究。进入switch_root:/#后,先执行:

mount -o remount,rw /sysroot chroot /sysroot

第一步是把原本只读挂载的真实根分区重新挂载为可写,否则后续写密码文件会失败。第二步是进入原系统的完整目录环境,让passwd命令能正确读取本机的账号配置。接下来就是改密码:

passwd root touch /.autorelabel

输两次新密码。然后关键一步:执行touch /.autorelabel。这个文件是给SELinux用的,稍后我会专门展开讲这一步为什么省了会后悔。最后连续输入两次exit退出,系统会继续启动流程,等它自动relabel完就能正常登录了。

Debian系没有rd.break,但流程类似:在GRUB菜单按e,在linux行末尾追加init=/bin/bash启动,系统会直接给你root shell。不过因为这里是直接用init替换systemd起一个bash,所以挂载关系更原始,你得手动把根分区以读写方式重新挂载一次,例如:

mount -o remount,rw /

然后直接passwd root,改完exec /sbin/init继续启动,或者直接reboot -f。同样要记住SELinux在Debian系默认关闭,这个坑主要在RHEL系。

3.2 fstab写错导致系统起不来,emergency是个好去处

刚学会自己挂NAS、加数据盘、稀里糊涂改了fstab的人太多了。这类故障的典型表现是:启动进度条走到某个地方卡住,然后屏幕跳出一堆含Timed out waiting for device的日志,最后落到emergency mode让你输入root密码。这个场景我用emergency.target很顺,因为fstab错误本来就是挂载系统时发生的,在更早的阶段介入能避开加载那些不存在的分区。

进入维护shell后,第一件事是执行:

mount -o remount,rw / vi /etc/fstab

把明显写错的行注释掉,或者修正UUID。然后一定不要着急重启,先验证:

mount -a

这条命令会按fstab重新挂一遍所有条目,只要它不报错,说明配置已经不会有问题了。接着reboot,系统就能正常起来。

这里多说一句我的意见:fstab里写设备名(比如/dev/sdb1)是个坏习惯,设备名可能因为拔插变化。用blkid查出来的UUID更稳。还有一个救急思路,就是在新挂载条目后面加nofail参数,即使挂载失败也不阻塞启动,但这是治标不是治本,生产环境我还是建议修好源头。

3.3 chroot进原系统之后重建GRUB引导

遇到GRUB损坏,通常得靠安装盘或Live环境。把原系统分区挂载好之后,关键的步骤是chroot进去,然后再操作GRUB。拿一个典型的物理机场景举例,假设根分区是/dev/sda2,boot是独立分区/dev/sda1,在Live shell里先:

mount /dev/sda2 /mnt mount /dev/sda1 /mnt/boot

接着伪文件系统(下面第四部分会专门讲)挂好以后,chroot进去:

chroot /mnt

对BIOS引导的老机器(也就是传统Legacy模式),重建引导要两步:

grub2-install /dev/sda grub2-mkconfig -o /boot/grub2/grub.cfg

先执行grub2-install把引导代码写进磁盘的MBR区域,再执行mkconfig重新生成菜单配置。这两步有本质区别,很多人都只做第二步,结果界面和配置恢复了但一到开机还是引导不了。UEFI引导的机器略有不同,你要先确认EFI系统分区有没有挂到/boot/efi,然后重新生成对应发行版的grub.cfg:

grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

Debian系则直接一句update-grub,它会自动去扫描系统里的内核并重新生成配置。执行完后exit退出chroot,sync,重启。

3.4 为什么要touch /.autorelabel:一个99%的人会踩的SELinux坑

我在前面两次提到touch /.autorelabel,这里认真展开说一下。RHEL系默认启用SELinux,系统里几乎所有文件都有安全上下文标签。你在救援模式里通过chroot去改/etc/shadow时,新建或修改的文件上下文很可能跟SELinux策略里的要求对不上。最典型的后果是:你明明觉得密码已经重置成功了,重启后登录却被SELinux拒绝,甚至root都进不去,整个局面比没修之前更绝望。

/.autorelabel这个文件的作用就是告诉SELinux,下次启动时忽略当前标签不一致,主动对整个文件系统重新打一遍标签。代价是这个过程可能要等几分钟,但对一台已经躺在救援模式里的机器来说,这点时间完全值得。所以要养成习惯:只要是在救援环境里动过安全认证相关的文件、或者把原系统搬过位置,就touch一下这个文件。这算是我自己用一次的代价换来的教训,希望你能直接跳过。

4. 挂载顺序和chroot的规矩:救援模式里最容易翻车的细节

很多人的救援操作其实是在一个奇怪的“半连接”状态下进行的:明明人已经站在了原系统的目录面前,设备却还躺在外面。这就引出救援模式最核心的细节——挂载顺序。

4.1 chroot不是随便钻进去就行,伪文件系统必须先挂

chroot的意思是改变当前进程的根目录,让你以为自己进入了原系统。但Linux里有一批特殊的目录跟磁盘文件无关:/proc展示内核的进程视图,/sys展示设备和内核对象,/dev负责管理和动态生成设备节点。这些目录在真实根分区上是空壳,数据是由内核动态映射出来的。如果你不把它们挂进去,chroot之后的很多程序会直接报错。打个比方,你进了一栋楼,但楼里的水电气总闸没打开,插座是通电了但水管不出水,你拧开水龙头当然只有空气。

我在CentOS 7上曾经因为只挂载了/proc没挂/sys,导致chroot之后执行systemctl命令出现一堆异常行为,排查半天才发现是/sys缺失。现在我的固定挂载序列是这样的:

mount --bind /proc /mnt/proc mount --bind /dev /mnt/dev mount --bind /sys /mnt/sys

有些发行版还可以顺便绑定/run,避免某些进程管理工具的PID文件目录异常。先把这些挂好,再chroot,原系统里的工具才能像在正常运行环境里一样干活。

4.2 手把手手动挂载根分区、boot、EFI和特殊目录

很多时候你没法依赖“自动发现”,得理解一下为什么挂载顺序有讲究。救援模式里(比如LiveCD环境),你要先找到根分区,通常用:

lsblk blkid

看一下分区布局和文件系统类型。然后按“先根、后boot、再特殊目录”的顺序挂。根分区是基础,boot分区如果不先挂,后面chroot进去跑grub的时候根本找不到内核镜像;EFI系统分区同理,要在chroot之前挂到/mnt/boot/efi,不然生成UEFI引导菜单时工具会找不到挂载点。完整命令大概是这样:

mount /dev/mapper/vg-root /mnt mount /dev/sda1 /mnt/boot mount /dev/sda2 /mnt/boot/efi mount --bind /proc /mnt/proc mount --bind /dev /mnt/dev mount --bind /sys /mnt/sys

挂完之后用df -h看一眼,确认顺序没有错乱,再chroot /mnt。这样进去之后,你想跑什么修复命令基本都顺手。

4.3 文件系统修复的时机和顺序:xfs_repair和e2fsck的正确姿势

文件系统修错的案例也很经典。ext4系列一般用e2fsck,xfs系列用xfs_repair,但它们的共同规矩是:不能在文件系统挂载可写的状态下跑修复工具。救援模式的优势就在于可以轻松掌握卸载时机。比如启动时一个ext4分区提示需要检查,你要先看看它有没有被挂载,如果有就umount掉再执行:

e2fsck -f /dev/sdb1

xfs_repair则更严格,它会拒绝在挂载状态下运行,如果日志损坏需要恢复写入,xfs_repair -L /dev/sdb1可以强制清日志,但这意味着最近没有落盘的数据可能丢,要权衡。我的习惯是:先备份重要分区的重要数据(能备份就备份),再考虑-L这种激进参数。修复文件系统最讲究的其实是耐心,别让进度条骗了你,有输出就等着,没事别Ctrl+C。

5. 我在实际救援中踩过的坑,和一份防呆清单

最后这部分,聊点写在书上的教程里永远碰不到的东西。有些坑看起来不大,却会把你一晚上的修机时间变成通宵。

5.1 LVM卷组的识别问题:vgscan / vgchange -ay 忘了吗

朋友曾经用LiveCD救援一个CentOS系统,明明看到了根目录的设备名,执行mount /dev/mapper/vg01-lv_root /mnt却报错No such file or directory。他以为是设备名不对,尝试了一堆重建映射的命令,最后还是我提醒他:LVM卷组没有被内核扫描到。救援系统启动时不会自动激活原来硬盘上的卷组,你需要先手动扫描并激活:

vgscan vgchange -ay lvscan

vgscan会重新扫描所有磁盘上的LVM元数据,vgchange -ay会把状态为inactive的卷组激活,激活后设备映射才会出现在/dev/mapper下,这时再挂载就通了。这条排查链路很简单,但排错顺序如果没有“激活卷组”这个思路,会绕很多弯路。遇到挂载失败先别慌,lsblk看不到不代表不存在,LVM的元数据是藏在分区内部某一段区域里的。

5.2 “反正进救援了所以随便改”:最容易把系统修坏的几种操作

救援模式给root shell,很多人会忍不住肆无忌惮。我见过有人随便删/var/log下日志文件,结果重启时系统起不来;有人直接对根分区跑了xfs_repair且加了-L,导致正在缓存的数据全部丢失;还有人试图在chroot里跨发行版执行某个需要图形库的二进制,结果因为glibc版本和库路径不一致报了段错误。救援模式下修系统,心态上应该像做外科手术,能少动的就少动。在你改动任何东西之前问自己三句话:这个文件是什么?我改它的目的是什么?有没有副作用?如果答案不清晰,就先去查文档,别在凌晨两点靠肾上腺素做决定。

5.3 救援完成后的检查清单和恢复顺序

修好系统之后的收尾也有一套顺序,很多人就是挂在最后一步。正确的做法是:先按挂载的逆序卸载所有分区和绑定挂载点,比如你挂过/mnt/proc、/mnt/sys、/mnt/boot/efi,就按相反顺序先umount这些,最后umount根挂载点,再sync让缓冲落盘,然后才重启。如果你是从云控制台的救援模式操作,特别注意不要忘记在重启前卸载干净,否则临时系统可能还占着向外导出的路径。重启后第一时间看日志:journalctl -xb查启动错误,df -h确认根分区挂载正常,uptime确认系统稳定运行。有条件的话观察十分钟再跑业务。

如果你也想平时少熬夜,我个人最强烈的一条建议:每台长期服役的Linux机器,在文档里记录一条“救援入口”,写明这个发行版的GRUB参数该追加什么,以及物理机还是虚拟机、BIOS还是UEFI、有没有LVM。这个信息不值钱,但凌晨三点每搜一次谷歌都像是在跟时间赛跑。我自己的机器上还常备一个和线上版本一致的安装U盘,不是为了显摆动手能力,而是很多引导、分区、root密码问题,一个U盘就能让我安心睡个好觉。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询