RHEL 부팅 프로세스 문제 해결

Red Hat Enterprise LinuxBeginner
지금 연습하기

소개

이 실습에서는 Red Hat Enterprise Linux (RHEL) 부팅 프로세스를 문제 해결하고 복구하는 필수 기술을 배웁니다. 시스템이 올바르게 시작되지 않도록 방해하는 일반적인 문제를 진단하고 해결하기 위해 부팅 시퀀스의 여러 단계에서 시스템과 상호 작용하는 방법을 살펴봅니다. 여기에는 systemd 부팅 타겟 작업과 시스템 복구를 위해 설계된 특수 부팅 모드 활용이 포함됩니다.

실습을 진행하면서 systemctl을 사용하여 systemd 타겟을 관리하고, 시스템 유지 관리를 위해 GRUB 메뉴에서 rescue 모드로 부팅하며, rd.break 커널 매개변수를 사용하여 root 비밀번호를 재설정하는 실무 경험을 쌓게 됩니다. 또한, emergency 모드를 사용하여 손상된 /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 타겟임을 확인할 수 있습니다.

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 모드로 부팅

이 단계에서는 시스템 복구를 위해 설계된 특수 systemd 타겟인 rescue.target에 대해 배웁니다. 표준 RHEL 시스템에서는 재부팅하여 부트로더(GRUB)를 중단시키고 커널 부팅 옵션에 매개변수를 추가하여 이 모드에 액세스합니다. 이는 root 파일 시스템이 마운트되고 대부분의 서비스가 비활성화된 단일 사용자 셸을 제공하므로 문제 해결에 이상적입니다.

이 컨테이너화된 실습 환경에서는 실제 재부팅을 수행하거나 GRUB 메뉴에 액세스할 수 없지만, rescue 모드의 구성을 살펴보고 작동 방식을 이해할 수 있습니다.

먼저 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가 모두 시작되도록 보장합니다. rescue 서비스는 root 유지 관리 셸을 제공합니다.
  • After=sysinit.target rescue.service: 활성화 순서를 지정하여 시스템 초기화 및 rescue 서비스 이후에 rescue 모드가 시작되도록 합니다.
  • AllowIsolate=yes: 실행 중인 시스템에서 systemctl isolate rescue.target 명령을 사용하여 이 타겟으로 전환할 수 있도록 합니다.

rescue 모드가 제공하는 최소한의 환경을 더 잘 이해하기 위해 종속성을 볼 수 있습니다. systemctl list-dependencies 명령은 타겟의 일부로 시작되는 모든 유닛을 보여줍니다. 해당 출력도 저장합니다.

systemctl list-dependencies rescue.target | tee /home/labex/project/rescue-dependencies.txt

출력에는 rescue 모드에 필요한 유닛이 나열됩니다. 복구 작업을 위해 설계된 간소화된 환경임을 확인하는 최소한의 서비스 세트를 볼 수 있습니다.

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 셸을 제공하여 시스템 문제를 해결할 수 있게 해준다는 것입니다. 다음 단계에서는 유사한 원리에 의존하는 복구 시나리오를 시뮬레이션합니다.

rd.break와 chroot를 사용한 Root 비밀번호 재설정

이 단계에서는 RHEL 시스템에서 분실한 root 비밀번호를 재설정하는 절차를 배웁니다. 이는 중요한 복구 기술입니다. 표준 방법은 시스템이 완전히 시작되기 전에 셸에 액세스할 수 있게 해주는 rd.break 커널 매개변수로 부팅 프로세스를 중단하는 것입니다.

물리적 또는 가상 머신에서는 재부팅하고 GRUB 부트로더를 중단시킨 다음 linux 커널 라인 끝에 rd.break를 추가합니다. 이 작업은 systemd가 제어권을 갖기 직전에 부팅 프로세스를 중지하고 initramfs 셸로 진입하게 합니다. 거기서 일반적인 단계는 다음과 같습니다.

  1. mount -o remount,rw /sysroot 명령을 사용하여 시스템의 root 파일 시스템(읽기 전용으로 마운트됨)을 읽기-쓰기 모드로 다시 마운트합니다.
  2. chroot /sysroot를 사용하여 /sysroot에서 chroot 감옥(jail)으로 들어갑니다. 이렇게 하면 시스템의 실제 root 파일 시스템이 현재 환경이 되어 시스템에 영향을 주는 명령을 실행할 수 있습니다.
  3. passwd 명령을 사용하여 비밀번호를 변경합니다.
  4. 잠재적인 SELinux 컨텍스트 문제를 해결합니다.
  5. chrootinitramfs 셸을 종료하여 부팅을 계속합니다.

이 실습 환경에서는 실제 재부팅을 수행하고 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 재레이블(relabel)을 강제해야 합니다. 이는 root(/) 디렉토리에 .autorelabel이라는 빈 파일을 생성하여 수행합니다.

sudo touch /.autorelabel

파일이 생성되었는지 확인합니다.

ls -l /.autorelabel

출력에 새로 생성된 파일이 표시되어야 합니다.

-rw-r--r--. 1 root root 0 <날짜> <시간> /.autorelabel

실제 시스템이라면 이제 exit를 두 번 입력하고 시스템을 재부팅합니다. 시스템은 긴 재레이블 프로세스를 수행한 다음 새 비밀번호로 정상적으로 부팅됩니다. 이 실습에서는 확인을 위해 /.autorelabel 파일을 그대로 둡니다. 확인 단계에서 검사 후 자동으로 제거됩니다.

이것으로 root 비밀번호 재설정 시뮬레이션을 마칩니다. 복구 프로세스의 핵심인 주요 명령(passwdtouch /.autorelabel)을 연습했습니다.

Emergency 모드를 사용하여 /etc/fstab 오류 복구

이 단계에서는 /etc/fstab 파일의 오류를 진단하고 복구하는 방법을 배웁니다. 이 파일은 시스템에 어떤 파일 시스템을 어디에 마운트할지 알려주기 때문에 부팅 프로세스에 매우 중요합니다. /etc/fstab의 잘못된 항목은 시스템 부팅을 방해하여 emergency mode로 강제 진입하게 할 수 있습니다.

Emergency 모드는 시스템 복구를 위해 가능한 가장 최소한의 환경을 제공합니다. Rescue 모드와 달리 대부분의 파일 시스템을 마운트하거나 많은 서비스를 시작하려고 시도하지 않습니다. 결정적으로, 추가 손상을 방지하기 위해 root 파일 시스템(/)이 읽기 전용(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.

이제 복구 프로세스를 시뮬레이션해 보겠습니다. 실제 emergency 셸에서는 첫 번째 단계로 변경을 허용하기 위해 root 파일 시스템을 읽기-쓰기 모드로 다시 마운트합니다.

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의 모든 유효한 항목이 올바르게 마운트되었음을 나타냅니다. 파일을 성공적으로 복구했습니다.

요약

이 실습에서는 Red Hat Enterprise Linux 부팅 프로세스를 문제 해결하기 위한 필수 기술을 배웠습니다. systemctl을 사용하여 현재 기본값을 확인하고 graphical.targetmulti-user.target 간에 변경하는 등 systemd 부팅 타겟을 관리하는 연습을 했습니다. 또한 부팅 시퀀스를 중단하여 특수 복구 환경에 액세스하는 방법(예: 단일 사용자 셸에서 시스템 유지 관리 작업을 수행하기 위해 GRUB 메뉴에서 rescue 모드로 부팅)을 배웠습니다.

또한 일반적인 시스템 장애에 대한 중요한 복구 절차를 실행했습니다. rd.break 커널 매개변수를 사용하고, root 파일 시스템을 쓰기 권한으로 다시 마운트하고, chroot 환경을 사용하여 새 비밀번호를 설정하며, .autorelabel 파일을 생성하여 SELinux 컨텍스트 문제를 해결함으로써 잊어버린 root 비밀번호를 성공적으로 재설정했습니다. 마지막으로, emergency 모드에 진입하여 문제가 있는 항목을 식별하고 주석 처리하여 시스템이 성공적으로 부팅되도록 함으로써 /etc/fstab 오류로 인한 부팅 실패를 해결하는 방법을 배웠습니다.