一线运维摸爬滚打好几年,我总结出 4 招——从单用户模式到挂载镜像修复,覆盖绝大部分"起不来"的场景。每一招都是生产环境真用过,关键时候能顶上的操作。
由于系统故障场景太多,且按操作的破坏性从低到高排序:单用户模式 → 救援模式 → LiveCD 改密码 → 挂载镜像修复,原则简单来说就是能轻不重,能修不装。
信创推进后行里大量换上了麒麟系统,SP1 到 SP3都有在用,虽然基于 openEuler 社区 + Linux 4.19 LTS 内核,不是 RHEL 克隆,但用户态工具链跟 RHEL/CentOS 高度兼容,方法论可以直接迁移,为方便也在做信创的同行参考,下面涉及麒麟的地方会逐处标出来。
一、单用户模式:改密码、修配置的万能钥匙
最常见的场景:root 密码丢了,或者 fstab 写错导致系统卡在启动。
重启过程中按 e 编辑,找到内核引导行——CentOS 7 是 linux16 开头,RHEL 8+ 和麒麟 V10(SP1-SP3 统一)都是 linux 开头,把 ro 改成 rw,行尾加 rd.break,Ctrl+X 启动。系统会停在一个 dracut shell,根分区挂载在 /sysroot,只读。
mount -o remount,rw /sysroot # /sysroot 默认只读,必须先改成可写chroot /sysroot# 切根到真实系统环境passwd root # 改 root 密码# SELinux 是 enforcing 的话必须打标签# 触发下次启动时对全盘文件重新标记 SELinux 上下文touch /.autorelabelexit# 退出 chroot,回到 dracut shellexit# 退出 dracut,系统自动重启并执行 autorelabel第一次改密码如果忘了 autorelabel,SELinux 会把文件上下文搞乱,系统比改之前还惨。我现在敲这个命令是肌肉记忆。
如果 fstab 写错导致卡在启动,同样进 dracut shell:
# 先把 /sysroot 改成可写mount -o remount,rw /sysrootchroot /sysroot # 切根到真实系统# chroot 后 / 就是原来的 /sysroot,前面已经 remount rw 了 这步是防御性操作,双保险,不会出错mount -o remount,rw /vi /etc/fstab # 编辑 fstab,把写错那行注释掉# 这步很重要,写错了下次启动还是卡mount -a # 验证 fstab 语法,没报错再退出exit# 退出 chrootexit# 退出 dracut,系统自动重启Ubuntu / Debian 简单点,GRUB 编辑那行加 init=/bin/bash,Ctrl+X 启动后直接是 root shell,不需要 chroot。改完 exec /sbin/init 继续正常启动。
二、救援模式:单用户都进不去时的底牌
如果是根分区损坏、GRUB 被覆盖、内核 panic——单用户救不了的时候上救援模式。从 ISO 启动一个最小环境,把硬盘挂上来修。
银行机房物理机不方便直接插 U 盘,一般都走 VNC 虚拟控制台挂载 ISO 镜像。用对应 ISO 启动——CentOS 选 Troubleshooting → Rescue a CentOS system;麒麟选 Troubleshooting → Rescue a Kylin Linux Advanced Server system。提示挂载原系统时选 Continue,系统会挂到 /mnt/sysimage。
修 GRUB 引导:
# 切根到被救援的系统chroot /mnt/sysimage# ---- BIOS 模式 ----# 重装 GRUB 引导扇区到第一块硬盘的 MBRgrub2-install /dev/sda# 重新生成 GRUB 配置文件(BIOS 路径)grub2-mkconfig -o /boot/grub2/grub.cfg# ---- UEFI 模式 ----# 安装 UEFI 引导程序到 EFI 分区# CentOS 用 --bootloader-id=centos# 麒麟用 --bootloader-id=KylinOS(注意大小写,官方安装默认值)grub2-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=KylinOS# 重新生成 GRUB 配置文件# 先确认实际目录名(bootloader-id 决定目录名,注意大小写)# ls /boot/efi/EFI/ → 看到 kylin 还是 KylinOS# CentOS 路径:/boot/efi/EFI/centos/grub.cfg# 麒麟路径(原厂安装):/boot/efi/EFI/kylin/grub.cfggrub2-mkconfig -o /boot/efi/EFI/kylin/grub.cfgexit# 退出 chrootreboot # 在 VNC 界面卸载 ISO 镜像,正常启动修文件系统:
CentOS 7 和麒麟 V10 默认都用 xfs,不是 ext4,别用 fsck,直接上 xfs_repair:
# 别 chroot,在救援环境直接修# chroot 会锁住文件系统,xfs_repair 没法跑# 救援模式启动时,根分区已被挂到 /mnt/sysimage# xfs_repair 要求文件系统处于未挂载状态,必须先卸载umount /mnt/sysimage# 确认根分区设备名# CentOS 卷组一般叫 centos,设备名 /dev/mapper/centos-root# 麒麟卷组一般叫 klas,设备名 /dev/mapper/klas-rootlsblk# 修复 xfs 文件系统(以麒麟为例)xfs_repair /dev/mapper/klas-root# 如果报 "dirty log" 错误,说明日志没清干净# 先挂载触发日志回放,再卸载,再修mount /dev/mapper/klas-root /mnt # 挂载,触发 xfs 日志回放umount /mnt # 卸载,释放锁xfs_repair /dev/mapper/klas-root # 再次修复,这次应该能过有次做麒麟内核升级,同事把 /boot 下的 initramfs 删了,重启直接 kernel panic。挂 ISO 进救援模式,chroot 重装内核包,5 分钟搞定。要是重装系统,上面十几个业务得重新部署,少说得半天。(当然,最好是提前做系统备份或者快照,不粘锅)
三、Linux 改密码的 3 种姿势
单用户和救援模式下改密码上面都讲了,再补一种最暴力的——LiveCD 直接改。前两种都进不去时用:
# Ubuntu LiveCD 启动后# 如果根分区用的是 LVM,先激活所有卷组# 不激活的话 /dev/mapper/rootvg 不存在sudo vgchange -ay# 挂载目标系统的根分区sudo mount /dev/mapper/rootvg /mntsudo chroot /mnt # 切根到目标系统passwd root # 改密码touch /.autorelabel # SELinux 环境必须打标签,跟单用户模式一样exit# 退出 chrootsudo umount /mnt # 卸载根分区,必须先退出 chroot 再卸# 记得先卸载 ISO 镜像,重启sudo reboot一个坑:改完密码能登录了,但 su 报 Authentication token manipulation error。先查文件系统是不是还挂着 ro:
# 文件系统只读时写不了 /etc/shadow,改密码会报错mount -o remount,rw / # 重新挂载为可写如果不是这个问题,查 /etc/shadow 权限。CentOS 7 和麒麟 V10 标准权限都是 0000,不是 0400:
# /etc/shadow 正确权限是 0000(----------)# 只有 root 能通过文件系统权限直接读# 权限被改过会导致 PAM 认证异常chmod 0000 /etc/shadow四、挂载镜像修复:最硬核的急救
系统大面积损坏——glibc 被覆盖、rpm 数据库崩了、依赖链断了——得从安装镜像里把文件搬回来。
场景:glibc 被覆盖,连 ls 都报错
# 进救援模式后,系统挂载在 /mnt/sysimage# 关键:先挂 ISO,再 chroot!# 顺序反了的话,chroot 后 /dev/cdrom 设备节点可能不存在,把 ISO 挂载到目标系统的 /mnt/iso 目录mount /dev/sr0 /mnt/sysimage/mnt/isochroot /mnt/sysimage # 切根到目标系统cd /mnt/iso/Packages # 进入 ISO 包目录# 强制重装 glibc 主包(--force 覆盖已损坏的文件)# 包名因版本不同:CentOS 是 glibc-2.17-xxx.el7.x86_64.rpm# 麒麟 V10(SP1-SP3 统一):glibc-2.28-xxx.ky10.x86_64.rpm# 通配符 glibc-*.x86_64.rpm 会匹配所有 glibc 子包(含 -common/-utils 等),全装没问题rpm -ivh --force glibc-*.x86_64.rpm# 最后验证下:能列出目录就说明基本库恢复了ls /修 rpm 数据库:
# 先备份 rpm 数据库,防止修坏了没法回退cp -r /var/lib/rpm /var/lib/rpm.bak# 删除 Berkeley DB 的锁文件和缓存(__db.* 是 BDB 的运行时文件)# 这些文件损坏会导致 rpm/yum/dnf 全部报错rm -f /var/lib/rpm/__db*rpm --rebuilddb # 重建 rpm 数据库索引rpm -qa | head -5 # 验证:能列出已安装包说明数据库恢复了****批量修复依赖链:
# 创建本地 yum/dnf 源,指向刚才挂载的 ISO# 用 heredoc 写入 repo 文件,'EOF' 单引号防止变量被 shell 展开cat > /etc/yum.repos.d/local.repo << 'EOF'[local]name=Local ISObaseurl=file:///mnt/isoenabled=1gpgcheck=0EOF# 麒麟/CentOS ISO 的 repodata 通常在 ISO 根目录,baseurl=file:///mnt/iso 适用大多数版本# 如果 yum/dnf 报 "Metadata not found",试改为 file:///mnt/iso/BaseOS# 麒麟 V10 基于 openEuler,包管理器是 dnf,yum 是 dnf 的软链接,两个命令都能用# 清除缓存,强制重新读取本地源yum clean all# 也可以用:dnf clean all# 批量重装核心基础包yum reinstall glibc glibc-common bash coreutils -y# 也可以用:dnf reinstall glibc glibc-common bash coreutils -y每次做补丁升级前,我都会先 rpm -qa > /root/rpm-list-$(date +%F).txt 备份已安装包列表。出问题时至少知道原来装了什么版本,这个习惯救过我不止一次。
4 招优先级
一个原则:能轻不重,能修不装。 每次上更重的手段前,先想清楚——问题到底是密码?引导?文件系统?还是库文件?有没有更轻的方式?盲目上重手段,可能把小问题搞成大事故。
有人可能说现在都容器化了,谁还修物理机。容器跑在宿主机上,宿主机起不来,上面所有容器都是空中楼阁。会修系统是运维的基本功,你能在高压环境下把一台起不来的服务器救回来,这种能力比什么证书都硬。
建议收藏这篇,在测试环境实际操练一遍。等真出事的时候,肌肉记忆比搜索引擎快。
能力一般,水平有限,若文章有谬误,还请各位大佬不吝赐教~
你有没有遇到过 Linux 进不去系统的紧急情况?最后怎么救回来的? 评论区聊聊,也许你的经验能帮到别人。
说句题外话。
文章里每一条命令——rd.break、xfs_repair、grub2-mkconfig、rpm --rebuilddb——真出事的时候,未必能手不抖心不慌的敲出来。
之前我自己也存了一堆文档,但关键时刻还是现翻现查。所以把常用命令按场景整理进了小程序里,算是一种沉淀了。
OpsKit运维宝典,微信搜一搜就能找到。
不收费,没广告,运维人给运维人攒的工具箱。
相关命令我已排期更新到命令速查板块了,下次出事直接打开参考下,比翻聊天记录快。