多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Linux救援模式实战:从原理到修复fstab、GRUB与密码丢失

Linux救援模式实战:从原理到修复fstab、GRUB与密码丢失 直接说结论Linux救援模式是系统坏了以后你还能进得去的那个最小可用环境。不管你是因为fstab写错、GRUB损坏、root密码丢失还是内核panic只要手里有这份知识大多数场景都能在不重装系统的前提下把机器救回来。这篇文章会从原理讲到实操把三种进入救援模式的姿势、标准修复流程和几个坑全都拆开揉碎适合刚接触Linux的运维新人也适合已经踩过几次坑但一直没系统梳理过的老手。1. 救援模式究竟是个什么东西先说清楚概念别看这个名字有点吓人它本质就是一个极简Linux环境专门用来“修复另一个坏掉的Linux”。日常办公环境你可能永远用不到它但服务器一旦开不了机、进不了登录界面它就是最后那根救命稻草。1.1 救援模式与普通模式、单用户模式的区别很多人分不清救援模式rescue mode、单用户模式single user mode和紧急模式emergency mode的区别这里直接用一个表讲明白。模式启动依赖根文件系统来源典型用途正常运行模式本机GRUB引导完整启动本机磁盘上的真实根分区日常使用单用户模式本机GRUB菜单加参数single本机真实根分区重置密码、修复配置文件救援模式安装介质外部U盘/光盘启动介质自带的内存文件系统GRUB损坏、内核崩溃等大故障紧急模式systemd无法挂载所有分区时自动掉入真实根分区尽量只读排查fstab、systemd启动失败这里最关键的一点是单用户模式虽然跳过了登录验证、不启动图形界面和网络服务但它仍然依赖你本机的根文件系统。如果你的根分区本身挂不上、内核起不来单用户模式照样进不去。救援模式尤其通过安装介质进去的那种用的是独立的内存文件系统不依赖目标系统的磁盘所以连引导损坏都能修。配合initramfs这个概念更好理解。Linux正常启动流程大致是这样BIOS/UEFI加载GRUBGRUB把内核和initramfs加载到内存内核把initramfs解包成一个临时根环境然后这个临时环境根据/etc/fstab把真实的根分区挂载上来最后切换到真实根。救援模式做的事情本质就是让你停在这个“临时根环境”阶段或者让安装介质启动一套完整系统然后把目标磁盘挂载进来操作。1.2 什么场景下你会哭着找它我修机器这么多年遇到最多的几类故障基本都离不开救援模式fstab配置错误。最常见的手贱操作。写错一个UUID、挂载一个不存在的分区开机直接卡在等待界面最后掉进emergency。GRUB引导损坏。比如重装Windows把Linux引导覆盖了、/boot分区被清空、grub.cfg丢失或损坏。root密码遗忘。这属于纯管理事故但几乎每个运维都遇到过。SSH密钥也丢了的时候只有救援模式能救。内核升级后panic。刚装完新内核重启后屏幕一屏报错起不来。关键配置文件被改坏。比如/etc/profile写了个死循环、/etc/selinux/config被乱改、systemd的unit文件被误删。这些场景有一个共同点系统已经没法用常规方式启动但你其实不想重装。这时候救援模式就是标准解。2. 进入救援模式的三种姿势进入救援模式的路不止一条选哪条取决于你的机器坏到什么程度。我按“系统还能不能看到GRUB菜单”这个标准来区分。2.1 从GRUB引导菜单直接进救援如果你开机还能看到GRUB菜单那是最幸运的情况说明引导阶段还没坏透。RHEL/CentOS系列的GRUB菜单里通常会自带一个“Rescue a CentOS Linux system”之类的条目选它就能进入一个文字界面系统会自动扫描磁盘上已有的Linux系统然后挂载到/mnt/sysimage并给你一个shell。Debian/Ubuntu系的桌面版安装盘里有“Rescue mode”但已经装好的系统在GRUB菜单里没有直接的rescue条目不过提供了Advanced options for Ubuntu这种子菜单里面有多个内核版本的recovery mode。recovery mode本质上就是单用户模式加一个简易菜单能修fstab、能开root shell。这种方式的优点不需要外部介质机器上有什么用什么。缺点如果GRUB本身坏了或内核崩溃了这个入口也跟着没了。2.2 用安装U盘/光盘进入救援模式GRUB菜单都看不到或者内核彻底起不来的时候就得靠外部介质了。把官方ISO写进U盘用它启动在安装器界面选择救援模式。RHEL/CentOS安装盘选“Troubleshooting”再选“Rescue a CentOS system”。它会问你语言然后自动扫描磁盘让你选择要挂载的系统目录接着问你要Read-Only还是Read-Write。这一步很重要如果你要改文件务必选Read-Write否则chroot进去后只能看不能动。Ubuntu安装盘选“Try Ubuntu”进Live桌面然后打开终端手动挂载目标系统。这其实是更自由的做法后面我会详细说。安装介质救援模式的优势是彻底它自己不依赖目标系统的任何部分所以连GRUB分区表损坏都能处理。这也是我推荐所有运维至少准备一个带Linux安装镜像U盘的原因。2.3 用内核参数强闯单用户或rd.break还有一种被提到很多但很多人用不明白的方法在GRUB菜单里按e找到linux16或linux开头的那一行在行尾追加参数。最常用的两个追加single也就是让systemd直接启动到rescue.target相当于单用户模式。它会切到真实根尽量少地启动服务给你一个root shell。追加rd.break这个是RHEL/CentOS系列dracut框架里的断点参数。它的意思是initramfs阶段执行到一半就暂停此时真实根还没挂载你停在一个临时shell里提示符类似switch_root:/#。rd.break和single的区别很微妙但很关键。单用户模式的前提是真实根能挂上、systemd能起来一部分。而rd.break发生在更早阶段它绕过了根挂载和systemd初始化所以当你的fstab写错了、根分区有文件系统问题时rd.break比single更能进去。这也是我实际处理启动故障时优先用的入口。3. 进入救援模式后的标准修复流程不管从哪个口子进去进来之后的通用套路都差不多把真实系统挂载到某个目录、切进去、修、重启。下面这套流程是通用的我用rd.break和安装介质两种情形来示范。3.1 先把根文件系统挂成可写并chroot这是整个救援模式里最重要的一步也是很多人进来后卡住的第一关。如果你用的是rd.break进入shell后执行mount -o remount,rw /sysroot chroot /sysroot注意顺序不能反。/sysroot就是你的真实根分区但它默认是只读挂载的。如果先chroot再remount你会发现自己处于一个“只能看不能写”的根环境里任何修改都会报Read-only file system。我见过不少人在这一步反复折腾以为是权限问题实际就是没先重新挂载。如果你用的是安装介质救援模式RHEL/CentOS系会自动帮你挂到/mnt/sysimage直接chroot /mnt/sysimageUbuntu Live环境要手动来通常这样sudo mkdir -p /mnt/sys sudo mount /dev/sda2 /mnt/sys sudo mount --bind /dev /mnt/sys/dev sudo mount --bind /proc /mnt/sys/proc sudo mount --bind /sys /mnt/sys/sys sudo chroot /mnt/sysmount --bind这三步是为了让chroot环境里能设备访问、进程信息和内核文件系统可见不然很多命令会报奇怪的错。这个细节在救援手册里很少被强调但实际操作中非常重要。chroot之后你看到的目录结构就是真实系统了。但还有一个容易被忽略的坑如果/boot是独立分区此时它可能没被挂载。你进chroot后执行ls /boot会发现里面是空的或者只有一个空目录。这时候要手动挂载否则后面grub2-mkconfig根本找不到内核镜像。mount /dev/sda1 /boot判断/boot是否独立分区很简单cat /etc/fstab看一下有没有单独挂载/boot的行。3.2 典型修复一重置root密码密码遗忘是最不复杂但最紧急的故障。chroot进真实根之后一条命令的事passwd root如果是因为密码过期导致登录被拒还要顺便清一下有效期chage -E -1 root chage -M 99999 root这里不得不提SELinux那个著名的坑。如果你改了密码、重启后依然提示认证失败或者干脆告诉你“密码正确但无法登录”大概率是SELinux的文件安全上下文出问题了。解决办法是退出chroot后在目标系统根目录建立一个自动重标记文件touch /.autorelabel在rd.break环境里你要touch的是/sysroot/.autorelabel因为此刻真实根挂在/sysroot下面。重启时SELinux会自动给所有文件重新打标签这个过程可能需要几分钟但能避免修复后依然进不去的尴尬。3.3 典型修复二修复GRUB引导GRUB损坏分好几种程度对应不同处理方式。只是grub.cfg缺失或内容坏了在chroot环境里重新生成一次配置就行# RHEL/CentOS grub2-mkconfig -o /boot/grub2/grub.cfg # Debian/Ubuntu update-grubMBR或EFI启动器本身损坏单靠mkconfig不够要把GRUB重新写回磁盘# 传统BIOS引导 grub2-install /dev/sda # UEFI引导 grub2-install --targetx86_64-efi --efi-directory/boot/efi /dev/sda注意/dev/sda要换成你自己的磁盘设备名而且要确认ESP分区通常是/dev/sda1挂载到了/boot/efi。UEFI和BIOS两条路线的安装目标不一样写错了还是会引导不起来。再补一个很多人不知道的细节如果你之前升级过内核、但新内核镜像本身损坏了单纯重新生成grub.cfg也没用因为mkconfig扫描到的是坏文件。这种情况要先重装内核RHEL系执行yum reinstall kernelUbuntu系执行apt install --reinstall linux-image-xxx然后重新mkconfig。这一步做完才算把引导真正修好。3.4 典型修复三fstab写错与启动卡死的处理fstab出问题是救援模式最常见的用途而且它表现出来的现象五花八门。有的直接提示找不到UUID有的卡在“A start job is running for dev-disk-by...”还有的挂在“Timed out waiting for device”上不动。进救援环境后先把fstab备份再逐个排查cp /etc/fstab /etc/fstab.bak blkid cat /etc/fstabblkid能列出所有磁盘分区的UUID和fstab里的UUID对着看哪行不一致就是哪行的问题。最简单粗暴的修复是把出错那一行注释掉重启后再重新配置。但要小心如果你把根分区也注释了那就真起不来了。还有一种我在生产环境踩过的坑挂载网络存储NAS。fstab里写了一个NAS地址结果重启时网络服务还没准备好systemd就在那里傻等挂载超时整个系统卡死在启动阶段。这种问题用救援模式进去后把那行挂载规则加上_netdev和nofail选项重启就能跳过网络未就绪的情况//192.168.1.100/share /mnt/nas cifs credentials/etc/nas.cred,_netdev,nofail 0 0如果是文件系统本身有错误比如ext4超级块损坏可以去救援模式里先卸载分区再跑fsckumount /dev/sda2 fsck -y /dev/sda2注意XFS文件系统没有fsck.xfs它是用xfs_repair /dev/sda2做的而且必须在卸载状态下执行。这个区别在RHEL 7以后的机器上是常见的翻车点。4. 实战案例与排查方法救援模式用多了你会发现很多故障的表象完全一样但病因各不相同。下面这几个案例是我实际遇到过的每个都值得单独记录。4.1 案例一克隆虚拟机后UUID对不上导致进不去这个场景特别典型。虚拟机模板或者克隆出来的机器磁盘分区UUID应该已经变了但grub.cfg和fstab里还写着旧的值开机直接提示找不到根分区。救援进去之后先用blkid拿到正确的UUID然后修改两个地方一是/etc/fstab里的根分区UUID二是/boot/grub2/grub.cfg里对应menuentry的rootUUIDxxx参数。改完重启如果引导能进系统了再执行grub2-mkconfig -o /boot/grub2/grub.cfg把配置固话一下。我个人的习惯是直接修改grub.cfg而不只依赖mkconfig因为mkconfig在某些配置复杂的机器上会生成一些多余菜单项而直接改能确保你正在使用的内核参数是准确的。4.2 案例二LVM卷组没有激活导致挂载失败LVM布局的机器比较特殊。你进救援模式后ls /dev/mapper/可能什么都没有然后你按fstab里的名字mount /dev/mapper/centos-root就报错说设备不存在。原因是救援环境的initramfs没有自动激活所有卷组。解法是手动激活vgscan vgchange -ay如果里面有LUKS加密卷还得先cryptsetup luksOpen解密设备名才会出现在/dev/mapper下。处理LVM机器时这个步骤一定要形成肌肉记忆否则你会怀疑是不是磁盘坏了。4.3 案例三SELinux导致救援修完还是进不去我说的不是开机报SELinux错误那种明显情况而是修改文件后、重启一切正常但登录时总是被拒。这种最折磨人。上面提到过处理方式是touch /.autorelabel。但有一个补充经验如果在修改密码时系统提示了Authentication token manipulation error这种奇怪错误多半也是SELinux标签问题。此时可以临时关闭SELinux验证一下setenforce 0 passwd root但别忘了重启后还是要让系统重新打标签否则下次还会遇到同样问题。4.4 故障入口速查表把常见故障和推荐入口整理成一张表平时可以直接对照用。故障症状推荐入口核心命令GRUB菜单都看不到安装介质救援grub2-install /dev/sda内核panic / 卡在内核启动安装介质救援重装内核 grub2-mkconfigfstab挂载失败rd.break 或 single注释fstab错误行vgchange -ayroot密码丢失rd.breakpasswd roottouch /.autorelabel开机黑屏显卡驱动问题GRUB里按e追加nomodeset修改内核启动参数网络挂载NAS卡死启动singlefstab加_netdev,nofailSELinux认证异常rd.breaktouch /.autorelabel5. 写在最后的几句经验这些年用下来我最深的体会是救援模式不是用来“临时凑合”的它是一个标准安全通道平时就值得练熟。我建议每个运维都在虚拟机里故意制造几次故障比如改错fstab、把grub.cfg删掉、用错误的UUID替换根分区然后完整走一遍救援流程。练过三次以后真出故障时你至少不会手忙脚乱。还有两个小细节很容易被忽略但关键时刻要命。第一救援环境里改完东西退出chroot后用sync刷一下缓存再执行reboot避免缓存没落盘导致修复白做。第二永远在修改前备份哪怕只是cp /etc/fstab /etc/fstab.bak这种一行命令都可能帮你省掉一次重装的代价。如果你手边的机器不止一种发行版建议把RHEL系和Debian系这两套救援流程都走一遍命令差异虽然不大但入口位置和工具名称确实不一样。这些经验攒下来就是你自己的一份“系统救活手册”了。
返回列表