介绍
在本实验中,你将学习排查和修复红帽企业级 Linux (RHEL) 引导过程的基本技术。你将探索如何在引导序列的不同阶段与系统交互,以诊断并解决导致系统无法正常启动的常见问题。这包括使用 systemd 引导目标,以及利用专为系统恢复设计的特殊引导模式。
通过这些练习,你将获得使用 systemctl 管理 systemd 目标的实践经验,学习如何从 GRUB 菜单进入救援模式进行系统维护,并使用 rd.break 内核参数重置 root 密码。此外,你还将学习如何使用紧急模式来修复关键配置文件错误(例如损坏的 /etc/fstab),确保能够将无法引导的系统恢复到正常运行状态。
使用 systemctl 管理 Systemd 引导目标
在此步骤中,你将学习如何管理 systemd 引导目标。在 systemd 中,「目标」(target)是一个同步点,它将系统进入特定状态所需的各种服务和其他单元组合在一起。这是旧版 SysV init 系统中「运行级别」(runlevels)的现代替代方案。我们将探索如何查看当前的默认目标、更改未来引导的默认目标,以及临时切换到不同的目标。
首先,进入本实验的练习目录。
cd /home/labex/project
首先,让我们检查系统默认引导的目标。graphical.target 用于带有桌面环境的系统,提供图形用户界面 (GUI)。multi-user.target 则用于仅命令行界面。
要查看当前的默认目标并将结果保存以供后续查看,请运行以下命令:
systemctl get-default | tee step1-initial-target.txt
你应该会看到默认目标是图形目标。
graphical.target
现在,让我们将默认引导目标更改为 multi-user.target。这对于服务器环境或在不需要图形界面或图形界面导致问题时的排查场景非常有用。systemctl set-default 命令通过更改 /etc/systemd/system/default.target 符号链接来实现这一点。
使用 sudo 以管理员权限执行此命令。
sudo systemctl set-default multi-user.target
输出确认符号链接已更新。
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target.
你可以通过再次运行 get-default 命令并保存结果来验证默认值是否已更改。
systemctl get-default | tee step1-multi-user-target.txt
输出现在显示了新的默认目标。
multi-user.target
使用此设置,系统重启后将进入基于文本的控制台。在本实验中,我们希望保持一致的图形环境。让我们将默认目标改回 graphical.target。
sudo systemctl set-default graphical.target
你将看到与之前类似的输出,表明符号链接已改回。
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target.
运行最后一次检查以确认默认目标已恢复为 graphical.target,并保存结果。
systemctl get-default | tee step1-final-target.txt
graphical.target
除了更改重启后的默认目标外,你还可以使用 systemctl isolate 在当前会话中切换目标。此命令会停止与新目标无关的服务,并启动新目标所需的服务。例如,运行 sudo systemctl isolate multi-user.target 将终止你的图形会话并切换到纯文本控制台。这是一个功能强大但可能具有破坏性的命令,因此我们不在此处执行。
你现在已经成功使用 systemctl 管理了 systemd 目标。
从 GRUB 菜单进入救援模式
在此步骤中,你将了解 rescue.target,这是一个专为系统恢复设计的特殊 systemd 目标。在标准的 RHEL 系统上,你可以通过重启、中断引导加载程序 (GRUB) 并向内核引导选项添加参数来访问此模式。这提供了一个单用户 shell,其中根文件系统已挂载且大多数服务已禁用,非常适合进行故障排查。
虽然我们无法在这个容器化实验环境中执行真正的重启或访问 GRUB 菜单,但我们仍然可以探索救援模式的配置以了解其工作原理。
首先,让我们找到 rescue.target 的 systemd 单元文件。这些文件通常存储在 /usr/lib/systemd/system/ 目录中。
ls -l /usr/lib/systemd/system/rescue.target
你将看到该文件及其权限和所有权信息。
-rw-r--r--. 1 root root 500 Nov 1 2022 /usr/lib/systemd/system/rescue.target
现在,让我们检查该文件的内容以了解其配置。cat 命令将在终端中显示文件内容,tee 将在你的练习目录中保存一个副本。
cat /usr/lib/systemd/system/rescue.target | tee /home/labex/project/rescue-target.txt
输出显示了该目标的定义。
## SPDX-License-Identifier: LGPL-2.1-or-later
#
## This file is part of systemd.
#
## systemd is free software; you can redistribute it and/or modify it
## under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation; either version 2.1 of the License, or
## (at your option) any later version.
[Unit]
Description=Rescue Mode
Documentation=man:systemd.special(7)
Requires=sysinit.target rescue.service
After=sysinit.target rescue.service
AllowIsolate=yes
该文件中的关键指令包括:
Description=Rescue Mode:该目标的人类可读名称。Requires=sysinit.target rescue.service:这确保了当此目标被激活时,sysinit.target(基本系统初始化)和rescue.service都会启动。救援服务提供了根维护 shell。After=sysinit.target rescue.service:这指定了激活顺序,确保救援模式在系统初始化和救援服务之后启动。AllowIsolate=yes:这允许你在运行中的系统中使用systemctl isolate rescue.target命令从另一个目标切换到此目标。
为了更好地了解救援模式提供的最小化环境,你可以查看其依赖项。systemctl list-dependencies 命令显示了作为目标一部分启动的所有单元。也保存该输出。
systemctl list-dependencies rescue.target | tee /home/labex/project/rescue-dependencies.txt
输出列出了救援模式所需的单元。你将看到一组最小化的服务,这证实了它是一个专为修复任务设计的精简环境。
rescue.target
○ ├─rescue.service
○ ├─systemd-update-utmp-runlevel.service
● └─sysinit.target
● ├─dev-hugepages.mount
● ├─dev-mqueue.mount
● ├─dracut-shutdown.service
○ ├─iscsi-onboot.service
○ ├─iscsi-starter.service
● ├─kmod-static-nodes.service
● ├─ldconfig.service
● ├─lvm2-lvmpolld.socket
... (输出可能有所不同) ...
关键点在于 rescue.target 提供了一个已挂载读写权限文件系统的 root shell,使你能够修复系统问题。在接下来的步骤中,我们将模拟依赖于类似原则的恢复场景。
使用 rd.break 和 chroot 重置 Root 密码
在此步骤中,你将学习重置 RHEL 系统丢失的 root 密码的流程。这是一项关键的恢复技能。标准方法涉及使用 rd.break 内核参数中断引导过程,这使你在系统完全启动之前就能访问 shell。
在物理机或虚拟机上,你需要重启、中断 GRUB 引导加载程序,并将 rd.break 添加到 linux 内核行的末尾。此操作会在 systemd 接管控制权之前停止引导过程,将你置于 initramfs shell 中。从那里开始,一般步骤是:
- 使用命令
mount -o remount,rw /sysroot以读写模式重新挂载系统的根文件系统(默认以只读方式挂载在/sysroot)。 - 使用
chroot /sysroot进入/sysroot的chroot监牢。这使得系统的实际根文件系统成为你当前的环境,允许你运行影响系统的命令。 - 使用
passwd命令更改密码。 - 处理潜在的 SELinux 上下文问题。
- 退出
chroot和initramfsshell 以继续引导。
虽然我们无法在此实验环境中执行真正的重启并使用 rd.break,但我们将模拟进入 chroot 环境后执行的最重要命令。
首先,让我们模拟更改 root 密码。想象你已经成功进入了 chroot 监牢。你现在拥有更改任何用户密码的 root 权限。我们将使用 sudo passwd root 命令来更改 root 用户的密码。当提示时,将新密码设置为 redhat。
sudo passwd root
系统将提示你输入并重新输入新密码。将其设置为 redhat。
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
在此恢复环境中更改密码后,密码文件 (/etc/shadow) 上的 SELinux 安全上下文可能会变得不正确。要修复此问题,你必须在下次引导时强制进行完整的系统 SELinux 重新标记。这是通过在根 (/) 目录中创建一个名为 .autorelabel 的空文件来完成的。
sudo touch /.autorelabel
让我们验证该文件是否已创建。
ls -l /.autorelabel
输出应显示新创建的文件。
-rw-r--r--. 1 root root 0 <日期> <时间> /.autorelabel
在真实系统上,你现在需要输入两次 exit 并让系统重启。它将执行漫长的重新标记过程,然后使用新密码正常引导。在本实验中,请保留 /.autorelabel 文件以供验证;验证步骤将在检查后自动将其删除。
至此,重置 root 密码的模拟结束。你已经练习了恢复过程中核心的关键命令 (passwd 和 touch /.autorelabel)。
使用紧急模式修复 /etc/fstab 错误
在此步骤中,你将学习如何诊断和修复 /etc/fstab 文件中的错误。该文件对于引导过程至关重要,因为它告诉系统挂载哪些文件系统以及挂载到哪里。/etc/fstab 中的错误条目可能会阻止系统引导,从而强制其进入「紧急模式」(emergency mode)。
紧急模式为系统修复提供了尽可能最小化的环境。与救援模式不同,它不会尝试挂载大多数文件系统或启动许多服务。关键的是,根文件系统 (/) 以只读 (ro) 模式挂载,以防止进一步损坏。
虽然我们无法在此实验中触发真正的引导失败,但我们可以模拟查找和修复 /etc/fstab 错误的过程。
首先,让我们有意向 /etc/fstab 添加一个错误的条目。我们将使用带有 sudo 的 echo 命令追加一行引用不存在设备的内容。
echo '/dev/nonexistent /data xfs defaults 0 0' | sudo tee -a /etc/fstab
现在,让我们查看 /etc/fstab 的内容以确认我们的错误行已添加,并在修复之前保存一个副本。
cat /etc/fstab | tee /home/labex/project/step4-fstab-before.txt
你应该会在文件末尾看到错误的行。
#
## /etc/fstab
## Created by anaconda on <日期>
#
## Accessible filesystems, by reference, are maintained under '/dev/disk/'.
## See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
## After editing this file, run 'systemctl daemon-reload' to update systemd
## units generated from this file.
#
/dev/vda4 / xfs defaults 0 0
/dev/vda2 /boot xfs defaults 0 0
/dev/vda1 /boot/efi vfat umask=0077,shortname=winnt 0 0
/dev/vda3 swap swap defaults 0 0
/dev/nonexistent /data xfs defaults 0 0
接下来,我们将模拟诊断步骤。mount -a 命令尝试挂载 /etc/fstab 中列出的所有尚未挂载的文件系统。由于我们的条目无效,此命令将失败。保存错误输出,以便稍后与修复后的状态进行比较。
sudo mount -a 2>&1 | tee /home/labex/project/step4-mount-error.txt
该命令将产生一个错误,清楚地表明错误的 /dev/nonexistent 条目无法挂载。这类似于你在引导失败期间看到的错误类型。
mount: /data: fsconfig system call failed: /dev/nonexistent: Can't lookup blockdev.
dmesg(1) may have more information after failed mount system call.
现在,让我们模拟修复过程。在真正的紧急 shell 中,第一步是以读写模式重新挂载根文件系统以允许更改。
sudo mount -o remount,rw /
文件系统现在可写,你可以编辑 /etc/fstab 来修复错误。使用 nano、vi 或你熟悉的任何其他终端编辑器打开该文件。
sudo vi /etc/fstab
在编辑器中,导航到错误的行 (/dev/nonexistent /data xfs defaults 0 0) 并将其删除,然后保存文件。
要确认修复,请再次运行 sudo mount -a。
sudo mount -a
这一次,命令应该静默执行且没有任何输出,这表明 /etc/fstab 中的所有有效条目都已正确挂载。你已成功修复该文件。
总结
在本实验中,你学习了排查红帽企业级 Linux 引导过程的基本技术。你练习了管理 systemd 引导目标,例如使用 systemctl 查看当前默认目标并在 graphical.target 和 multi-user.target 之间进行切换。你还学习了如何中断引导序列以访问专门的恢复环境,包括从 GRUB 菜单进入救援模式,以便在单用户 shell 中执行系统维护任务。
此外,你还执行了针对常见系统故障的关键恢复程序。你通过使用 rd.break 内核参数、以写权限重新挂载根文件系统,并使用 chroot 环境设置新密码,成功重置了遗忘的 root 密码,同时还通过创建 .autorelabel 文件解决了 SELinux 上下文问题。最后,你学习了通过进入紧急模式、识别问题条目并将其注释掉,来解决由 /etc/fstab 错误导致的引导失败,从而使系统能够成功引导。



