리눅스 서버의 runlevel과 systemd target 완벽 비교 정리

Views: 0

리눅스 부팅과 서비스 구동 방식은 SysV init의 runlevel에서 systemd의 target으로 진화했다. runlevel은 숫자(0~6)로 시스템 상태를 구분하고, systemd는 유닛(Unit)과 의존성 그래프를 활용해 더 유연한 부팅 시나리오를 제공한다. 이 글에서는 두 체계를 개념부터 명령어, 매핑, 운영 시 주의점까지 깊이 있게 비교 정리한다.

왜 runlevel에서 systemd target으로 바뀌었는가

  • 확장성: runlevel은 고정된 7개 수준만 제공한다. 반면 target은 원하는 만큼 정의할 수 있어 컨테이너, 클라우드, 데스크톱 등 다양한 시나리오에 맞출 수 있다.
  • 병렬성: systemd는 의존성 그래프를 기반으로 유닛을 병렬로 시작해 부팅 시간을 단축한다.
  • 관측·제어성: journal(로그 집계), 유닛 상태 조회, 의존성 시각화 등 운영 가시성이 뛰어나다.
  • 호환성: 레거시 스크립트와의 호환 레이어(runlevel 타깃)를 제공해 이행이 수월하다.

runlevel 개념 정리

  • 정의: 부팅 시 시작·중지할 서비스 집합을 숫자로 표현한 시스템 상태.
  • 관례적 의미
    • 0: 시스템 종료(shutdown)
    • 1: 단일 사용자 모드(복구용)
    • 2~4: 멀티유저(배포판에 따라 의미가 다르며, 데비안 계열은 2~5가 동일하게 설정된 경우가 많다)
    • 5: 멀티유저 + 그래픽(X/디스플레이 매니저)
    • 6: 재부팅(reboot)
  • 대표 명령어
    • 현재 runlevel 확인: runlevel 또는 who -r
    • 상태 전환: telinit 3(예: 3으로 전환), init 6(재부팅)
    • 기본 runlevel 설정(레거시): /etc/inittab 편집

systemd target 개념 정리

  • 정의: 특정 상태를 나타내는 “타깃 유닛(.target)”과 서비스 유닛(.service)들의 의존성 묶음.
  • 장점
    • 원하는 상태를 타깃으로 정의하고, Requires=/Wants=/Before=/After=로 관계를 명시한다.
    • 부팅·전환 시 의존성에 따라 병렬 실행이 가능하고 실패 지점 파악이 쉽다.
  • 대표 타깃
    • poweroff.target: 시스템 종료
    • rescue.target: 단일 사용자 모드(리커버리 쉘)
    • multi-user.target: 멀티유저(텍스트 콘솔)
    • graphical.target: 멀티유저 + 그래픽
    • reboot.target: 재부팅
    • emergency.target: 최소 복구 환경(루트 쉘, 의존성 거의 없음)

runlevel ↔ systemd target 매핑표

  • 0 → poweroff.target
  • 1 → rescue.target
  • 2~4 → 일반적으로 multi-user.target에 매핑(배포판별 차이 주의)
  • 5 → graphical.target
  • 6 → reboot.target

배포판마다 2~4의 의미가 다를 수 있으므로, 이식성 있는 스크립트에서는 숫자 대신 명시적 타깃(multi-user.target, graphical.target)을 권장한다.

현재 상태 확인과 전환 방법

SysV(runlevel) 계열

  • 현재 runlevel: runlevel who -r
  • 즉시 전환(예: 3으로): telinit 3
  • 기본 runlevel(레거시 방식): /etc/inittab에서 id:3:initdefault: 형태로 설정

systemd(target) 계열

  • 현재 디폴트 타깃 확인: systemctl get-default
  • 현재 활성 타깃과 관련 타깃 보기: systemctl list-units --type=target
  • 즉시 전환(예: 텍스트 멀티유저로): sudo systemctl isolate multi-user.target
  • 그래픽 세션으로 전환: sudo systemctl isolate graphical.target
  • 디폴트 타깃 변경(부팅 시 적용): sudo systemctl set-default multi-user.target sudo systemctl set-default graphical.target
  • 응급/복구 모드: sudo systemctl rescue # rescue.target sudo systemctl emergency # emergency.target

실전 운영 시나리오

1) 헤드리스 서버에서 불필요한 GUI 비활성화

GUI가 필요 없다면 디폴트를 텍스트 모드로 바꿔 메모리·부팅 시간을 아낄 수 있다.

sudo systemctl set-default multi-user.target
sudo systemctl isolate multi-user.target

2) 원격 장애 복구

네트워크는 살리고 최소 서비스만 올린 상태에서 문제를 점검하려면 rescue.target이 유용하다. 서비스 의존성까지 극단적으로 줄여야 할 때는 emergency.target을 선택한다. 원격 세션에서 전환할 때는 접근 끊김 위험을 고려해 콘솔 접근(예: iDRAC, IPMI, VNC over BMC)을 확보한 뒤 실행하는 것이 안전하다.

3) 데스크톱 환경 전환

그래픽 로그인(디스플레이 매니저)을 기본으로 쓰려면:

sudo systemctl set-default graphical.target

Xorg/Wayland나 디스플레이 매니저(gdm, sddm, lightdm)가 올바로 설정되지 않았다면 graphical.target 전환 시 실패할 수 있으니, 관련 서비스 활성화 상태(systemctl status gdm.service 등)와 저널 로그를 확인한다.

트러블슈팅 체크리스트

  • 어떤 타깃이 실패했는가 systemctl --failed systemctl status <unit or target>
  • 부팅 로그로 실패 원인 추적 journalctl -b -p err journalctl -u <service>
  • 의존성 확인 systemctl list-dependencies multi-user.target systemctl list-dependencies --reverse <unit>
  • 디폴트 타깃 오설정 점검
    ls -l /etc/systemd/system/default.target로 심볼릭 링크가 올바른지 확인한다.

전환 시 안전 가이드

  • 원격 접속 중 전환 주의: isolate는 현재 타깃과 충돌하는 서비스(예: 네트워크, SSH)를 중지시킬 수 있다. 테스트 환경에서 먼저 검증하거나 콘솔 백업 경로를 마련한다.
  • 데이터 워크로드 고려: 종료·재부팅 타깃으로의 전환은 파일시스템 동기화와 서비스 종료 순서를 정확히 따른다. DB 등 상태 기반 서비스는 종료 훅이 정상 작동하는지 확인한다.
  • 배포판 차이: RHEL/CentOS/AlmaLinux와 Debian/Ubuntu 계열의 runlevel 해석이 다를 수 있다. 자동화 스크립트는 숫자 대신 target 명시가 바람직하다.

이행 전략: runlevel 스크립트에서 systemd로

  • 서비스 이식: /etc/init.d/ 스크립트를 systemd 유닛 파일로 옮긴다. ExecStart=, ExecReload=, Restart= 등을 명시해 재시작 정책과 헬스 체크를 정교하게 설계한다.
  • 타깃 기반 부팅 시나리오 구성: 예를 들어, 스토리지 → 네트워크 → 로깅 → 애플리케이션 순으로 의존성을 정의해 재현 가능한 부팅을 보장한다.
  • 호환 레이어 활용: systemctl isolate runlevel3.target처럼 호환 타깃을 사용할 수 있으나, 장기적으로는 multi-user.target 등 순정 타깃 명칭으로 정착한다.

자주 묻는 질문(FAQ)

runlevel 숫자 명령이 여전히 동작하는 이유는?

대부분의 현대 배포판은 systemd 위에서 호환 레이어를 제공한다. runlevel, telinit 같은 명령이 내부적으로 systemd 호출로 매핑될 수 있다. 다만 새 자동화에서는 systemctl 사용을 권장한다.

rescue와 emergency의 차이는?

rescue.target은 기본 파일시스템 마운트와 일부 필수 서비스가 실행되는 단일 사용자 모드다. emergency.target은 의존성이 거의 없는 최소 루트 쉘만 제공해, 마운트나 fsck 같은 기초 복구 작업에 적합하다.

부팅 시 특정 서비스만 지연시키고 싶다면?

해당 서비스 유닛에 After=/Requires=를 적절히 지정하거나, 별도의 커스텀 타깃을 만들어 해당 타깃이 만족될 때 서비스가 시작되도록 의존성을 설계한다.

핵심 정리

  • runlevel은 고정된 숫자 기반 상태, systemd target은 유닛 의존성을 활용한 유연한 상태 모델이다.
  • 실무에서는 systemctl get-default, set-default, isolate, list-units --type=target 명령을 기본기로 익히면 대부분의 전환·점검을 해결할 수 있다.
  • 자동화·이식성을 위해 runlevel 숫자보다 명시적 타깃 이름을 사용하고, 전환 시 네트워크·SSH 끊김 가능성을 항상 고려한다.

빠른 실습 명령 모음

# 현재 디폴트 타깃
systemctl get-default

# 텍스트 모드(멀티유저)로 즉시 전환
sudo systemctl isolate multi-user.target

# 그래픽 모드로 즉시 전환
sudo systemctl isolate graphical.target

# 부팅 시 기본 타깃 설정
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target

# 실패 유닛 확인과 로그
systemctl --failed
journalctl -b -p err

이 글의 내용을 토대로, 기존 runlevel 기반 운영에서 systemd target 중심 운영으로 자연스럽게 전환하면, 부팅 시간 단축과 장애 원인 파악, 재현 가능한 서비스 시작 순서 설계까지 한 단계 높은 운영 품질을 구현할 수 있다.