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

journalctl, 실패한 유닛 확인, 복구 타겟, fstab 수정, 의존성 검토, initramfs 디버깅을 통해 systemd 부팅 문제를 진단합니다.

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

리눅스 부팅 문제는 익숙한 도구를 먼저 잃기 때문에 긴급하게 느껴집니다. SSH가 다운될 수 있고, 그래픽 로그인이 나타나지 않을 수 있으며, 콘솔이 실제보다 더 심각해 보이는 메시지와 함께 비상 모드로 빠질 수 있습니다. systemd 부팅 문제의 경우, 가장 좋은 첫 번째 조치는 추측이 아닙니다. 부팅이 중단된 지점을 찾은 다음, 유닛 로그, 마운트 실패, 의존성 오류 또는 초기 커널 메시지를 역추적하세요.

이 가이드는 커널이 systemd를 PID 1로 시작한 후 발생하는 실패와 콘솔에서 systemd 실패처럼 보이는 몇 가지 관련 문제(잘못된 /etc/fstab 항목, initramfs 문제, 부트로더 오류)에 중점을 둡니다.

Systemd 부팅 프로세스 이해

Systemd는 "유닛" 시스템을 통해 리눅스 부팅 프로세스를 관리합니다. 이러한 유닛은 서비스(.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가 필요한 것은 아닙니다. 설치된 시스템을 마운트하고 journalctl을 해당 위치로 지정하세요:

mount /dev/mapper/vg0-root /mnt
journalctl --directory=/mnt/var/log/journal -b -1

영구 저널이 없는 시스템에서는 이전 부팅 로그가 /var/log/journal 아래에 존재하지 않을 수 있습니다. 이 경우 /var/log 아래의 배포판별 로그를 확인하거나, 시스템이 충분히 정상일 때 영구 저널링을 활성화한 후 부팅을 재현하세요.

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 오류에 대한 오류 메시지 또는 "Give root password for maintenance (or type Control-D to continue)"와 같은 메시지와 함께 시스템이 emergency mode로 전환됩니다.

일반적인 원인:

  • 더티 파일 시스템: 잘못된 종료, 정전.
  • 잘못된 /etc/fstab: UUID/장치 경로 오타, 잘못된 파일 시스템 유형, 중요하지 않은 마운트에 noauto 누락.
  • 하드웨어 오류: 디스크 손상.

해결 방법:

  1. 비상 모드 접근: 메시지가 표시되면 루트 암호를 입력합니다.
  2. /etc/fstab 확인: /etc/fstab을 주의 깊게 검토하여 오류가 있는지 확인합니다. 의심스러운 줄을 임시로 #으로 주석 처리합니다.
  3. fsck를 주의해서 실행: 파일 시스템이 마운트 해제된 경우에만 수동으로 확인 및 복구하거나, 배포판에서 안전하다고 문서화된 유지 관리 컨텍스트에서 읽기 전용으로 마운트된 경우에만 수행합니다. 루트가 아닌 파티션의 경우:
    umount /dev/sdb1
    fsck -f /dev/sdb1
    
    루트 파일 시스템을 복구해야 하는 경우 라이브 미디어 또는 복구 환경에서 부팅하고 거기서 fsck를 실행합니다. 중요한 디스크의 경우 첫 번째 조치로 fsck -y를 피하십시오. 이미 백업이 있거나 손상을 이해하지 않는 한 프롬프트를 검토하십시오.
  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 이미지를 생성하며, 복잡한 문제에 매우 유용합니다.
  2. 유닛 종속성 검사: systemctl list-dependencies <unit_name>을 사용하여 유닛이 필요로 하는 것과 유닛에 의존하는 것을 확인합니다.

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

    • After=, Before=: 유닛의 순서를 제어합니다. A.serviceAfter=B.service가 있으면 AB 후에 시작됩니다(B가 전혀 시작되는 경우). 대부분의 순서 지정 요구에는 After=를 사용하십시오.
    • Wants=: 약한 종속성을 나타냅니다. A.serviceB.serviceWants하면 A가 시작될 때 B가 시작되지만 B가 실패하더라도 A는 계속됩니다.
    • Requires=: 강한 종속성을 나타냅니다. A.serviceB.serviceRequires하면 A가 시작될 때 B가 함께 시작되며 B를 시작할 수 없으면 A가 실패합니다. 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를 재구축합니다.
    # 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
    
  2. GRUB 구성 확인: /boot/grub/grub.cfg(또는 재생성하는 경우 /etc/default/grub)에서 올바른 root= 매개변수와 initrd 경로를 확인합니다.
  3. 커널 매개변수: 특정 모듈이 누락되었거나 문제를 일으키는 것으로 의심되는 경우 GRUB에 커널 매개변수(예: 디버깅을 위해 initramfs 셸로 드롭하는 rd.break)를 추가해 볼 수 있습니다.

5. GRUB/부트로더 문제

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

증상: "No boot device found", GRUB 복구 프롬프트, 또는 GRUB이 커널을 로드하지 못합니다.

일반적인 원인:

  • 손상된 부트로더.
  • 존재하지 않는 커널/initramfs를 가리키는 잘못된 GRUB 구성.
  • BIOS/UEFI 설정이 올바른 부팅 순서를 방해합니다.

해결 방법:

  1. GRUB 재설치: 라이브 USB로 부팅하고, 시스템에 chroot한 다음 MBR/EFI 파티션에 GRUB을 다시 설치합니다.
    # 예시
    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
    
  2. 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: 전체 부팅 시간에 영향을 미치는 종속성의 중요 경로를 이해합니다.

안전한 복구 순서

콘솔에 있고 시스템이 반쯤 부팅된 상태라면 복구 순서를 단순하게 유지하십시오:

  1. 가능하면 화면의 정확한 오류를 캡처합니다.
  2. systemctl --failed를 실행합니다.
  3. journalctl -b -p err..alert --no-pager를 읽습니다.
  4. 유닛이 실패한 경우 journalctl -u unit-name -b를 읽습니다.
  5. 마운트가 실패한 경우 /etc/fstab을 검사하고 blkid로 UUID를 확인한 다음 의심스러운 중요하지 않은 마운트만 주석 처리합니다.
  6. 루트 파일 시스템 또는 initramfs가 관련된 경우, 침습적인 복구를 수행하기 전에 라이브 미디어 또는 복구 모드로 전환합니다.
  7. 유닛 파일 편집 후 systemctl daemon-reload를 실행하고 가능하면 영향을 받는 유닛만 다시 시작합니다.

대부분의 systemd 부팅 문제는 한 번에 많은 것을 변경하여 해결되지 않습니다. 잘못된 마운트 라인, 누락된 디스크, ExecStart=가 손상된 서비스 또는 순서 지정 실수는 상당히 직접적인 흔적을 남깁니다. 그 흔적을 따라가고, 하나의 작은 수리를 한 다음, 현재 셸에서 수정 사항을 테스트할 수 없는 경우에만 재부팅하십시오.

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

예방 및 모범 사례

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

결론

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