Systemd 부팅 문제 해결: 일반적인 문제와 해결책

Linux 부팅 문제를 접하는 것은 어려울 수 있습니다. 이 포괄적인 가이드는 최신 Linux 시스템에서 흔히 발생하는 원인인 systemd 관련 부팅 실패에 대한 실용적인 해결책을 제공합니다. `journalctl` 및 `dmesg`를 사용하여 부팅 로그에 액세스하고 해석함으로써 문제를 효과적으로 진단하는 방법을 알아보십시오. 서비스 실패, 파일 시스템 손상 및 단위 종속성 충돌과 같은 일반적인 시나리오를 해결하며, 단계별 지침과 명령 예제를 제공합니다. 더 깊은 디버깅을 위해 복구 모드 및 `rd.break`와 같은 고급 기술을 발견하여 부팅 문제를 체계적으로 해결하고 시스템 기능을 복원할 수 있도록 보장합니다.

41 조회수

Systemd 부팅 문제 해결: 일반적인 문제 및 해결책

Linux 부팅 문제는 모든 시스템 관리자나 고급 사용자에게 가장 답답한 문제 중 하나일 수 있습니다. 시스템이 제대로 시작되지 않을 때, 첫 번째 단계는 부팅 프로세스가 성공적으로 완료되는 것을 방해하는 원인을 식별하는 것입니다. 현대 Linux 배포판의 주요 시스템 및 서비스 관리자로서, systemd는 초기 커널 핸드오버부터 필요한 모든 서비스의 시작에 이르기까지 부팅 시퀀스를 조정하는 데 핵심적인 역할을 합니다.

이 글은 일반적인 systemd 관련 부팅 오류를 이해하고 해결하기 위한 포괄적인 가이드입니다. 부팅 로그 분석, 문제 서비스 식별, 복잡한 유닛 순서 충돌 문제 해결을 위한 실용적인 방법에 대해 심층적으로 다룰 것입니다. 이 가이드를 마치면, 부팅 문제를 진단하고 해결하여 Linux 시스템을 안정적인 상태로 자신 있게 되돌릴 수 있는 체계적인 접근 방식을 갖게 될 것입니다.

Systemd 부팅 프로세스 이해

systemd는 "유닛(units)" 시스템을 통해 Linux 부팅 프로세스를 관리합니다. 이 유닛들은 서비스(.service), 마운트 지점(.mount), 장치(.device), 타겟(.target)과 같은 다양한 시스템 리소스와 서비스를 설명합니다. 타겟은 다른 유닛들을 그룹화하고 부팅 프로세스 중 특정 동기화 지점 또는 상태를 나타내는 특별한 유닛입니다. 예를 들어, multi-user.target(전통적인 런레벨 3) 또는 graphical.target(런레벨 5)과 같습니다.

부팅 프로세스는 일반적으로 다음을 포함합니다:
1. 커널 초기화: 커널이 하드웨어를 로드하고 초기화합니다.
2. Initramfs 단계: 초기 RAM 파일 시스템이 로드되며, 여기에는 루트 파일 시스템을 마운트하는 데 필요한 필수 드라이버와 도구가 포함됩니다.
3. Systemd 시작: systemd는 PID 1로 제어권을 넘겨받아 default.target (종종 multi-user.target 또는 graphical.target에 심볼릭 링크됨)을 시작합니다.
4. 유닛 활성화: systemd는 유닛 파일을 읽고, 의존성을 해결하며, 서비스를 시작하고 마운트 포인트를 고도로 병렬적으로 활성화합니다.

부팅 문제는 이러한 단계 중 어느 곳에서든 발생할 수 있지만, 이 가이드는 systemd가 시작된 후 나타나는 문제에 주로 초점을 맞춥니다.

초기 분류: 부팅 로그 접근

시스템이 제대로 부팅되지 않을 때, 가장 중요하고 첫 번째 단계는 부팅 로그에 접근하는 것입니다. 이 로그는 무엇이 잘못되었는지에 대한 단서를 제공합니다. 시스템이 그래픽 환경이나 표준 TTY로 부팅되지 않는 경우, 대체 방법을 사용해야 합니다.

1. journalctl 사용 (복구/비상 모드 또는 라이브 미디어에서)

journalctl은 systemd 저널을 질의하는 유틸리티입니다. 시스템이 복구 모드비상 모드로 부팅되거나, 라이브 USB/CD를 사용하여 디스크에 접근할 수 있다면, journalctl이 주요 도구입니다.

이전 부팅의 로그를 보려면:

journalctl -b -1

시스템이 부팅된 이후의 모든 메시지를 보려면:

journalctl -b

실패한 유닛과 관련된 로그를 보려면:

journalctl -b -p err..emerg # 오류, 심각, 경고, 비상 메시지 표시
journalctl -b --since "-5min" # 현재 부팅의 마지막 5분 로그 표시

라이브 환경을 사용하는 경우, 시스템의 저널 파일에 접근하려면 먼저 시스템의 루트 파티션으로 chroot해야 합니다.

2. dmesg 사용

dmesg는 부팅 중 커널로부터의 메시지를 포함하는 커널 링 버퍼를 표시합니다. 이는 systemd가 완전히 제어권을 넘겨받기 전, 부팅 프로세스의 아주 초기 단계에서 발생하는 문제에 특히 유용합니다.

dmesg

3. 유닛 상태 검사

사용 가능한 셸(복구 모드, 비상 모드 또는 chroot가 적용된 라이브 환경)에 진입하면 모든 systemd 유닛의 상태를 확인할 수 있습니다.

systemctl --failed

이 명령은 시작에 실패한 모든 유닛을 나열합니다. 특정 실패한 유닛에 대한 자세한 정보를 보려면 다음을 사용하십시오:

systemctl status <unit_name>.service

그리고 해당 유닛의 특정 저널 항목을 보려면:

journalctl -u <unit_name>.service -b

일반적인 Systemd 부팅 문제 및 해결책

1. 서비스 및 유닛 실패

문제: 중요한 서비스가 시작되지 않아 시스템이 원하는 타겟(예: multi-user.target)에 도달하지 못합니다. 이는 종종 시스템이 비상 모드로 진입하는 것으로 나타납니다.

증상: systemctl --failed가 하나 이상의 유닛이 "failed" 상태임을 보여줍니다. journalctl -u <unit_name>.service는 서비스가 시작되지 못한 이유를 나타내는 오류 메시지를 드러냅니다.

일반적인 원인:
* 잘못된 구성: 구성 파일의 오타, 잘못된 경로, 누락된 의존성.
* 파일/의존성 누락: 서비스가 존재하지 않거나 접근할 수 없는 파일 또는 디렉토리에 접근하려고 시도합니다.
* 자원 고갈: 서비스가 너무 많은 메모리 또는 기타 자원을 할당하려고 시도합니다.
* 권한 문제: 서비스에 파일 읽기/쓰기 또는 명령 실행에 필요한 권한이 없습니다.

해결책:
1. 실패한 유닛 식별: systemctl --failed를 사용하십시오.
2. 로그 검사: 자세한 오류 메시지를 위해 journalctl -u <unit_name>.service -b를 실행하십시오.
3. 구성 수정: 서비스의 구성 파일(예: /etc/systemd/system/<unit_name>.service 또는 /etc/ 내의 파일)을 편집하십시오. ExecStart, WorkingDirectory, User, Group, Environment 지시문에 주의하십시오.
4. 의존성 확인: 모든 Wants=, Requires=, After=, Before= 지시문이 올바르게 지정되었는지, 그리고 필요한 서비스가 활성화되었는지 확인하십시오.
5. 다시 시작 및 재활성화: 변경 사항을 적용한 후 systemctl daemon-reload를 실행한 다음 systemctl start <unit_name>.servicesystemctl enable <unit_name>.service를 시도하십시오.

예시: 사용자 정의 웹 서비스 mywebapp.service가 데이터베이스를 사용할 수 없어 실패합니다.

# 상태 확인
systemctl status mywebapp.service

# 단서를 위한 로그 확인
journalctl -u mywebapp.service -b

# 유닛 파일 편집 (예: /etc/systemd/system/mywebapp.service)
# 데이터베이스가 먼저 시작되도록 After= 지시문 추가/수정
# 예: After=postgresql.service mysql.service

# systemd 다시 로드 후 재시도
systemctl daemon-reload
systemctl start mywebapp.service
systemctl enable mywebapp.service # 다음 부팅 시 시작되도록 보장

2. 파일 시스템 문제

문제: 손상된 파일 시스템 또는 /etc/fstab의 잘못된 항목은 시스템이 중요한 파티션을 마운트하는 것을 방해하여 비상 모드로 이어질 수 있습니다.

증상: fsck 실패, mount 오류에 대한 오류 메시지, 또는 "유지 관리를 위해 root 암호를 입력하십시오 (또는 계속하려면 Control-D를 입력하십시오)"와 같은 메시지와 함께 시스템이 emergency mode로 진입합니다.

일반적인 원인:
* 손상된 파일 시스템: 부적절한 종료, 전원 손실.
* 잘못된 /etc/fstab: UUID/장치 경로의 오타, 잘못된 파일 시스템 유형, 중요하지 않은 마운트에 대한 noauto 누락.
* 하드웨어 고장: 디스크 손상.

해결책:
1. 비상 모드 접근: 메시지가 나타나면 root 암호를 입력하십시오.
2. /etc/fstab 확인: /etc/fstab에서 오류가 없는지 신중하게 검토하십시오. 의심스러운 줄은 임시로 #로 주석 처리하십시오.
3. fsck 실행: 수동으로 파일 시스템을 확인하고 복구하십시오. 예를 들어, /dev/sda1이 루트 파티션인 경우:
bash # 가능하면 언마운트 (루트 파티션이 아닌 경우), 또는 fsck 매개변수로 재부팅 umount /dev/sda1 fsck -y /dev/sda1
: 루트 파티션을 언마운트할 수 없다면, 라이브 USB로 부팅하여 거기서 fsck를 실행해야 할 수 있습니다.
4. 재부팅: 변경 사항을 적용하거나 fsck를 실행한 후 재부팅을 시도하십시오.

3. 의존성 충돌 및 유닛 순서 지정

문제: 서비스가 잘못된 순서로 시작되거나, 유닛에 충돌하는 의존성이 있어 교착 상태 또는 실패로 이어집니다.

증상: 서비스 시간 초과, 의존성이 준비되지 않아 서비스 실패, systemd-analyze plot이 긴 체인 또는 순환을 보여줌.

일반적인 원인:
* 유닛 파일의 Wants=, Requires=, After=, Before= 지시문 잘못 구성.
* 아직 사용할 수 없는 리소스를 기대하는 유닛.

해결책:
1. 부팅 시퀀스 분석: systemd-analyze를 사용하여 부팅 프로세스를 시각화하십시오.
* systemd-analyze blame: 시작 시간에 따라 정렬된 서비스를 보여주며, 느린 유닛을 강조합니다.
* systemd-analyze critical-chain: 전체 부팅 시간에 직접적인 영향을 미치는 유닛의 중요한 경로를 보여줍니다.
* systemd-analyze plot > boot.svg: 전체 부팅 의존성 그래프의 SVG 이미지를 생성하며, 복잡한 문제 해결에 매우 유용합니다.

  1. 유닛 의존성 검사: systemctl list-dependencies <unit_name>을 사용하여 유닛이 무엇을 필요로 하는지, 그리고 무엇이 이 유닛에 의존하는지 확인하십시오.

  2. 유닛 파일 지시문 조정:

    • After=, Before=: 유닛의 순서를 제어합니다. A.serviceAfter=B.service가 있으면, AB 이후에 시작됩니다 (B가 시작될 경우). 대부분의 순서 지정 요구 사항에 After=를 사용하십시오.
    • Wants=: 약한 의존성을 표현합니다. A.serviceWants=B.service를 가지면, BA가 시작될 때 시작되지만, B가 실패하더라도 A는 계속됩니다.
    • Requires=: 강한 의존성을 표현합니다. A.serviceRequires=B.service를 가지면, BA가 시작될 때 시작되며, B가 실패하거나 중지되면 A도 중지됩니다.
    • Conflicts=: 현재 유닛이 시작되면 특정 유닛이 중지되고, 그 반대도 마찬가지로 보장합니다.
    • PartOf=: 한 유닛의 수명 주기를 다른 유닛과 연결합니다(예: slice가 중지되면, 해당 PartOf인 모든 유닛도 중지됩니다).

    : 교착 상태나 연쇄적인 실패로 이어질 수 있는 강한 결합을 피하기 위해 대부분의 의존성에는 항상 After=Wants=를 선호하십시오.

4. 커널 패닉 / Initramfs 문제

문제: 시스템이 아주 초기 단계에서 부팅에 실패하며, 종종 systemd가 완전히 제어권을 넘겨받기 전, "Kernel panic - not syncing" 또는 dracut이나 initramfs와 관련된 메시지를 표시합니다.

증상: 초기 부팅 실패, 종종 스택 트레이스나 루트 장치 없음, /dev/root를 찾을 수 없음 등의 메시지가 텍스트 벽처럼 표시됩니다.

일반적인 원인:
* 누락된 커널 모듈: Initramfs가 루트 파일 시스템에 필요한 드라이버(예: LVM, RAID, 특정 디스크 컨트롤러)를 포함하지 않습니다.
* 손상된 커널/Initramfs: 파일이 손상되었습니다.
* 잘못된 커널 매개변수: GRUB의 root= 매개변수가 잘못된 장치를 가리킵니다.

해결책:
1. Initramfs 재구성: 이는 일반적인 해결책입니다. 라이브 환경 또는 다른 커널로 부팅하고, 시스템으로 chroot한 다음, initramfs를 재구성하십시오.
```bash
# Dracut 예시 (Fedora/RHEL/CentOS)
dracut -f -v /boot/initramfs-$(uname -r).img $(uname -r)

# mkinitcpio 예시 (Arch Linux)

mkinitcpio -P

# update-initramfs 예시 (Debian/Ubuntu)
update-initramfs -u -k all
```
  1. GRUB 구성 확인: /boot/grub/grub.cfg (또는 재생성하는 경우 /etc/default/grub)에서 올바른 root= 매개변수와 initrd 경로를 확인하십시오.
  2. 커널 매개변수: 특정 모듈이 누락되었거나 문제를 일으킨다고 의심되는 경우, GRUB에 커널 매개변수를 추가(예: 디버깅을 위해 initramfs 셸로 진입하는 rd.break)해 볼 수 있습니다.

5. GRUB/부트로더 문제

문제: 시스템이 커널 로드 지점에도 도달하지 못하거나, GRUB 메뉴에서 멈춥니다.

증상: "부팅 장치를 찾을 수 없습니다", GRUB 복구 프롬프트, 또는 GRUB이 커널 로드에 실패합니다.

일반적인 원인:
* 손상된 부트로더.
* 존재하지 않는 커널/initramfs를 가리키는 잘못된 GRUB 구성.
* 적절한 부팅 순서를 방해하는 BIOS/UEFI 설정.

해결책:
1. GRUB 재설치: 라이브 USB로 부팅하고, 시스템으로 chroot한 다음, MBR/EFI 파티션에 GRUB을 재설치하십시오.
```bash
mount /dev/sdaX /mnt # 루트 파티션 마운트

mount /dev/sdaY /mnt/boot/efi # 별도의 EFI 파티션인 경우

for i in /dev /dev/pts /proc /sys /run; do mount --bind $i /mnt$i; done
chroot /mnt

grub-install /dev/sda # 메인 디스크에 설치

grub-mkconfig -o /boot/grub/grub.cfg # GRUB 구성 재설성

exit
umount -R /mnt
reboot
```
  1. BIOS/UEFI 설정 확인: 올바른 부팅 드라이브가 우선순위에 있는지 확인하십시오.

고급 문제 해결 기술

복구/비상 모드로 부팅

이 모드들은 문제를 해결하기 위한 최소한의 환경을 제공합니다. 진입 방법:

  1. GRUB 중: e를 눌러 커널 명령줄을 편집하십시오.
  2. linux 줄 찾기: linux (또는 linuxefi)로 시작하는 줄을 찾으십시오.
  3. 복구 모드(대부분의 서비스는 꺼져 있고, 단일 사용자 셸)를 위해 systemd.unit=rescue.target을 추가하십시오.
  4. 비상 모드(최소 서비스, 종종 읽기 전용 루트)를 위해 systemd.unit=emergency.target을 추가하십시오.
  5. Ctrl+X 또는 F10을 눌러 부팅하십시오.

Initramfs 디버깅을 위한 rd.break 사용

GRUB의 커널 명령줄에 rd.break를 추가하면 실제 루트 파일 시스템이 마운트되기 전에 initramfs 내의 셸로 진입하게 됩니다. 이는 누락된 드라이버나 LVM/RAID 설정 문제와 같은 initramfs 문제를 디버깅하는 데 매우 유용합니다.

initramfs 셸에 진입하면 다음을 수행할 수 있습니다:
* lsblk, mount 검사.
* /sysroot에서 누락된 파일 확인.
* 수동으로 루트 파일 시스템 마운트 시도.

부팅 성능 분석

엄밀히 "실패"는 아니지만, 느린 부팅 시간은 근본적인 문제나 비효율적인 서비스 구성을 나타낼 수 있습니다.

  • systemd-analyze blame: 시작하는 데 가장 오래 걸리는 서비스를 식별합니다.
  • systemd-analyze critical-chain: 전체 부팅 시간에 영향을 미치는 의존성의 중요한 경로를 이해합니다.

이러한 도구를 사용하여 병목 현상을 식별하고 After=, Requires=, TimeoutStartSec=, Type= 지시문을 조정하여 유닛 시작을 최적화하십시오.

예방 및 모범 사례

  • 변경 사항 테스트: 유닛 파일 수정 사항을 프로덕션 환경에 배포하기 전에 스테이징 환경에서 테스트하십시오.
  • 구성 백업: /etc/ 또는 최소한 중요한 /etc/systemd/system/ 파일을 정기적으로 백업하십시오.
  • 유닛 지시문 이해: systemd.service(5)systemd.unit(5) man 페이지에 대한 확실한 이해는 매우 중요합니다.
  • 드롭인 파일 사용: /lib/systemd/system/ 유닛 파일(업데이트로 덮어쓰여질 수 있음)을 직접 수정하는 대신, 사용자 정의 구성을 위해 드롭인 파일(/etc/systemd/system/<unit_name>.service.d/*.conf)을 사용하십시오.
  • 커널 보관: 새로운 커널이 문제를 일으킬 경우를 대비하여 항상 최소한 하나의 잘 알려진 이전 커널을 시스템에 보관하십시오.

결론

systemd 부팅 문제를 해결하려면 효과적인 로그 분석부터 시작하는 체계적인 접근 방식이 필요합니다. systemd의 유닛 기반 아키텍처를 이해하고 journalctl, systemctl, systemd-analyze와 같은 도구를 활용하면, 잘못 구성된 서비스, 파일 시스템 문제, 또는 복잡한 의존성 충돌 등 부팅 실패의 근본 원인을 효율적으로 찾아낼 수 있습니다. 복구 또는 비상 모드로 부팅하는 능력과 고급 디버깅 기술을 결합하면, 시스템이 완전히 응답하지 않는 것처럼 보일 때도 제어권을 되찾을 수 있습니다. 이러한 전략과 모범 사례를 통해 대부분의 systemd 부팅 문제를 해결하고 안정적이며 신뢰할 수 있는 Linux 작업을 유지할 수 있는 충분한 준비를 갖추게 될 것입니다.