排查 RHEL 启动过程问题

Red Hat Enterprise LinuxBeginner
立即练习

介绍

在这个实验中,你将学习用于排查和修复 Red Hat Enterprise Linux (RHEL) 启动过程的基本技术。你将探索如何在启动序列的不同阶段与系统交互,以诊断和解决可能阻止系统正确启动的常见问题。这包括使用 systemd 启动目标以及利用专为系统恢复设计的特殊启动模式。

在整个练习中,你将获得管理 systemd 目标(使用 systemctl)、从 GRUB 菜单启动到救援模式进行系统维护以及使用 rd.break 内核参数重置 root 密码的实践经验。此外,你将学习如何使用紧急模式来修复关键的配置文件错误,例如损坏的 /etc/fstab,确保你可以将无法启动的系统恢复到可操作状态。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 92%。获得了学习者 96% 的好评率。

使用 systemctl 管理 Systemd 启动目标

在这一步中,你将学习如何管理 systemd 启动目标。在 systemd 中,"目标"(target)是一个同步点,它将各种服务和其他单元组合在一起,以使系统达到特定状态。这相当于旧的 SysV init 系统中的 "运行级别"(runlevels)。我们将探讨如何查看当前的默认目标,更改未来启动的默认目标,以及临时切换到不同的目标。

首先,让我们检查你的系统默认启动到哪个目标。graphical.target 用于具有桌面环境的系统,提供图形用户界面(GUI)。multi-user.target 用于仅限命令行的界面。

要查看当前的默认目标,请运行以下命令:

systemctl get-default

你应该看到默认目标是图形目标。

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

输出现在显示了新的默认目标。

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
graphical.target

除了更改重启的默认目标之外,你还可以使用 systemctl isolate 在当前会话中切换目标。此命令会停止与新目标无关的服务,并启动与新目标相关的服务。例如,运行 sudo systemctl isolate multi-user.target 将终止你的图形会话并切换到仅文本控制台。这是一个强大但可能具有破坏性的命令,因此我们不会在此处执行它。

你现在已经成功地使用 systemctl 管理了 systemd 目标。

从 GRUB 菜单启动到救援模式

在这一步中,你将学习 rescue.target,这是一个专为系统恢复设计的特殊 systemd 目标。在标准的 RHEL 系统上,你将通过重启、中断引导加载程序(GRUB)以及向内核的启动选项添加参数来访问此模式。这提供了一个单用户 shell,其中根文件系统已挂载,并且大多数服务已禁用,这非常适合故障排除。

虽然我们无法在此容器化的实验环境中执行真正的重启或访问 GRUB 菜单,但我们仍然可以探索救援模式的配置以了解其工作原理。

首先,让我们找到 rescue.targetsystemd 单元文件。这些文件通常存储在 /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 命令将在终端中显示文件的内容。

cat /usr/lib/systemd/system/rescue.target

输出显示了目标的定义。

##  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

输出列出了救援模式所需的单元。你将看到一组最少量的服务,确认它是一个为修复任务设计的精简环境。

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
... (output may vary) ...

关键要点是 rescue.target 提供了一个根 shell,文件系统以读写方式挂载,使你能够修复系统问题。在后续步骤中,我们将模拟依赖于类似原则的恢复场景。

使用 rd.break 和 chroot 重置 Root 密码

在这一步中,你将学习在 RHEL 系统上重置丢失的根密码的程序。这是一项关键的恢复技能。标准方法涉及使用 rd.break 内核参数中断启动过程,这使你可以在系统完全启动之前访问 shell。

在物理机或虚拟机上,你将重新启动,中断 GRUB 引导加载程序,并将 rd.break 添加到 linux 内核行的末尾。此操作会在 systemd 接管控制之前停止启动过程,将你置于 initramfs shell 中。从那里开始,一般步骤是:

  1. 使用命令 mount -o remount,rw /sysroot 以读写模式重新挂载系统的根文件系统(它以只读模式挂载在 /sysroot)。
  2. 使用 chroot /sysroot/sysroot 处进入 chroot jail。这将使系统的实际根文件系统成为你当前的环境,允许你运行影响系统的命令。
  3. 使用 passwd 命令更改密码。
  4. 解决潜在的 SELinux 上下文问题。
  5. 退出 chrootinitramfs shell 以继续启动。

虽然我们无法在此实验环境中执行真正的重启并使用 rd.break,但我们将模拟在进入 chroot 环境后将要执行的最重要的命令。

首先,让我们模拟更改根密码。假设你已成功进入 chroot jail。你现在将拥有 root 权限来更改任何用户的密码。我们将使用 sudo passwd root 命令来更改 root 用户的密码。当提示时,将新密码设置为 redhat

sudo passwd root

系统将提示你输入并重新输入新密码(例如 labex.io)。

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 <date> <time> /.autorelabel

在真实系统中,你现在将键入两次 exit 并让系统重新启动。它将执行冗长的重新标记过程,然后使用新密码正常启动。由于我们不想在我们的实验中触发此操作,我们将通过删除我们刚刚创建的文件来进行清理。

sudo rm /.autorelabel

这结束了重置根密码的模拟。你已经练习了作为恢复过程核心的关键命令(passwdtouch /.autorelabel)。

使用 Emergency Mode 修复 /etc/fstab 错误

在这一步中,你将学习如何诊断和修复 /etc/fstab 文件中的错误。此文件对于启动过程至关重要,因为它告诉系统要挂载哪些文件系统以及挂载到哪里。/etc/fstab 中的条目不正确可能会阻止系统启动,迫使其进入“紧急模式”。

紧急模式为系统修复提供了尽可能最少的环境。与救援模式不同,它不会尝试挂载大多数文件系统或启动许多服务。至关重要的是,根文件系统(/)以只读(ro)模式挂载,以防止进一步损坏。

虽然我们无法在此实验中触发真正的启动失败,但我们可以模拟查找和修复 /etc/fstab 错误的过程。

首先,让我们有意向 /etc/fstab 添加一个错误的条目。我们将使用带有 sudoecho 命令来追加引用不存在设备的行。

echo '/dev/nonexistent /data xfs defaults 0 0' | sudo tee -a /etc/fstab

现在,让我们查看 /etc/fstab 的内容以确认我们的错误行已添加。

cat /etc/fstab

你应该在文件的末尾看到不正确的行。

#
## /etc/fstab
## Created by anaconda on <date>
#
## 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

该命令将产生一个错误,清楚地表明挂载点 /data 不存在。这类似于你在启动失败期间看到的错误。

mount: /data: mount point does not exist.

现在,让我们模拟修复过程。在真正的紧急 shell 中,第一步是以读写模式重新挂载根文件系统以允许更改。

sudo mount -o remount,rw /

现在文件系统可写,你可以编辑 /etc/fstab 以修复错误。使用 nano 编辑器打开该文件。

sudo nano /etc/fstab

nano 编辑器中,使用箭头键导航到错误的行(/dev/nonexistent /data xfs defaults 0 0)并将其删除。你可以通过按 Ctrl+k 删除整行。删除该行后,通过按 Ctrl+x,然后按 y,最后按 Enter 来保存文件。

要确认修复,再次运行 sudo mount -a

sudo mount -a

这次,该命令应该静默执行,没有输出,这表明 /etc/fstab 中的所有有效条目都已正确挂载。你已成功修复了该文件。

总结

在这个实验中,你学习了用于排查 Red Hat Enterprise Linux 启动过程的必要技术。你练习了管理 systemd 启动目标,例如查看当前默认目标,以及使用 systemctlgraphical.targetmulti-user.target 之间进行切换。你还学习了如何中断启动序列以访问专门的恢复环境,包括从 GRUB 菜单启动到救援模式,以便在单用户 shell 中执行系统维护任务。

此外,你还执行了针对常见系统故障的关键恢复程序。你通过使用 rd.break 内核参数、以写权限重新挂载根文件系统以及使用 chroot 环境设置新密码,成功重置了遗忘的根密码,同时还通过创建 .autorelabel 文件解决了 SELinux 上下文问题。最后,你学习了如何通过进入紧急模式、识别有问题的条目并将其注释掉以允许系统成功启动,从而解决由 /etc/fstab 错误引起的启动失败。