전원 ON부터 로그인까지 30초 — 그 사이에 무슨 일이 일어나는가
서버 전원을 켰다. 30초~1분 뒤 SSH 로그인 프롬프트가 뜬다. 그 사이 30초 동안 무슨 일이 벌어지는가? 대부분 "부팅되겠지" 하고 넘긴다. 하지만 서비스가 부팅 후 자동으로 안 올라오거나, 부팅이 응급 모드(emergency)에 빠져 멈추거나, 부팅이 너무 느릴 때 — 이 연쇄를 모르면 어디서 막혔는지조차 진단할 수 없다.
이 글은 전원 ON부터 로그인 프롬프트까지의 연쇄를 따라간다. 핵심 인물은 systemd, PID 1 — 모든 서비스의 출발점이다.
부팅은 여섯 단계 연쇄다
flowchart LR
P1["1. 펌웨어<br/>BIOS/UEFI + POST"] --> P2["2. 부트로더<br/>GRUB2 2.12"]
P2 --> P3["3. 커널 로드<br/>vmlinuz + initramfs"]
P3 --> P4["4. systemd<br/>PID 1"]
P4 --> P5["5. target 도달<br/>default.target"]
P5 --> P6["6. 로그인 프롬프트<br/>getty / 디스플레이 매니저"]
비유하자면 아침에 건물을 여는 절차와 비슷하다 — 경비원 출근(펌웨어) → 안내데스크가 관리실 열쇠 전달(GRUB2) → 임시 관리실 개방(initramfs) → 건물 관리자 출근(systemd) → 층별 전원 병렬 점등(target) → 로비 개방(로그인). 단, 건물은 순차적이지만 systemd는 병렬로 서비스를 올린다(의존성만 충족하면 동시).
각 단계를 좇아보자.
1. 펌웨어(BIOS/UEFI)
POST(Power-On Self-Test) 로 하드웨어를 점검한다(CPU·RAM·저장소가 살아있나). 그리고 부트 디바이스를 찾아 부트로더를 메모리에 올린다. UEFI 시스템이면 ESP(EFI System Partition)의 grubx64.efi를 실행한다.
2. GRUB2(부트로더)
Rocky 10은 GRUB2 2.12. 디스크에서 커널 이미지(vmlinuz-<버전>)와 initramfs를 메모리에 적재하고, 커널 명령줄 매개변수(root=, crashkernel=, rd.lvm.lv= 등)를 전달한다.
부트 엔트리는 과거의 거대한 grub.cfg 스크립트가 아니라 BLS(Boot Loader Specification) 방식 — 커널마다 독립된 .conf 스니펫으로 모듈화되어 있다:
title Rocky Linux (6.12.0-xxx.el10.x86_64)
version 6.12.0-xxx.el10.x86_64
linux /vmlinuz-6.12.0-xxx.el10.x86_64
initrd /initramfs-6.12.0-xxx.el10.x86_64.img
options root=/dev/mapper/rl-root ro crashkernel=2G-64G:256M rd.lvm.lv=rl/root
BLS가 왜 생겼나: 구 GRUB은
/boot/grub2/grub.cfg하나에 모든 엔트리가 스크립트로 들어가 커널 업데이트마다 재생성이 필요했고 오류가 잦았다. BLS는 커널별 독립 스니펫으로 모듈화해 이 문제를 풀었다.grubby가 관리한다.
3. 커널 + initramfs
커널이 메모리에서 initramfs(압축 CPIO 아카이브)를 tmpfs로 풀어 임시 루트를 만들고, 제어를 systemd로 넘긴다. 왜 굳이 임시 루트를 거치는지는 바로 다음 절에서.
4-6. systemd(PID 1) → target → 로그인
커널이 시작하는 첫 사용자 공간 프로세스가 systemd다. systemd가 target(동기화 체크포인트)을 차례로 도달하며 서비스를 올리고, 마침내 로그인 서비스(getty/sshd/GDM)가 뜬다.
flowchart TD
SYS["systemd 시작"] --> SYSINIT["sysinit.target<br/>(체크포인트)"]
SYSINIT --> BASIC["basic.target<br/>(체크포인트)"]
BASIC --> DEFAULT["default.target<br/>(multi-user 또는 graphical)"]
DEFAULT --> LOGIN["로그인 서비스<br/>getty/sshd/GDM"]
sysinit.target, basic.target은 체크포인트다. 여기서 실패하면 emergency.target(응급 모드)로 빠진다.
커널은 왜 곧바로 루트를 마운트하지 못할까 — initramfs의 이유
여기서 의문이 든다: 커널이 임시 루트(initramfs)를 거치지 않고 곧바로 진짜 루트(/)를 마운트하면 안 되나? 귀찮게 왜 임시 루트를 거치는가?
핵심 사실: 커널은 만능이 아니다. 루트 파티션이 LVM이면, RAID면, 디스크 암호화면, NVMe/iSCSI 특수 드라이버가 필요하면 — 커널이 혼자서 마운트할 수 없다. 필요한 드라이버와 도구가 있어야 한다. 그 도구를 담은 임시 환경이 initramfs다.
흐름:
- 커널이 initramfs를 tmpfs로 풀어 임시 루트 구성.
- initramfs가 LVM/RAID/암호화/특수 드라이버 초기화.
- 진짜 루트 장치가 준비되면
/sysroot에 마운트 →switch_root로 전환. - 제어를 systemd로 넘김.
구 용어
initrd와initramfs가 혼용되지만 기술적 구분이 있다: initrd = 블록 장치 기반 ramdisk(구식), initramfs = tmpfs 기반 CPIO(현대). 현대 리눅스는 모두 initramfs. LVM/RAID/암호화 루트면 initramfs 없이는 부팅 자체가 불가능하다.
systemd가 모든 것을 총괄한다 — PID 1
systemd는 RHEL/Rocky 7부터 기본 init 시스템이며, PID 1으로 모든 서비스를 관리한다. 핵심 설계 네 가지:
- 병렬 서비스 시작 — 의존성만 충족하면 동시에 올린다 → 부팅 속도 향상.
- cgroup 기반 자원 관리 — 서비스별 CPU/메모리를 통제. Rocky 10은 cgroup v2 강제.
- socket/D-bus activation — 요청이 올 때까지 서비스를 안 띄운다 → 메모리 절약. 첫 연결이 오면 그제야 서비스를 시작하고, 서비스가 죽어도 소켓이 요청을 큐에 담아둬 재시작 시 이어받는다.
- 통합 로그(journald) — 커널·서비스·syslog 로그를 구조화해 한곳에 수집.
Rocky 10(systemd 257)의 변화: cgroup v1을 폐기하고 항상 v2를 쓴다. System V(
init.d) 서비스 스크립트는 deprecated(향후 제거 → 네이티브 unit 파일 권장). 기본 설정 파일 위치가/etc/systemd/에서/usr/lib/systemd/로 이동했다(/etc/나 드롭인으로 오버라이드).cgroup v2 강제의 함정: 구 모니터링 도구·컨테이너 런타임이 cgroup v1 경로(
/sys/fs/cgroup/memory/...)를 쓰면 동작하지 않는다. v2 통일 경로(/sys/fs/cgroup/)를 써야 한다.
unit과 target — systemd가 세상을 보는 단위
systemd가 관리하는 모든 것은 unit이다. 접미사로 종류가 갈린다.
| unit 종류 | 접미사 | 용도 |
|---|---|---|
| service | .service |
데몬/서비스 (예: sshd.service) |
| target | .target |
동기화 지점/상태 (예: multi-user.target) |
| socket | .socket |
소켓 activation |
| timer | .timer |
cron 대체 스케줄러 |
| mount | .mount |
파일시스템 마운트 |
| device | .device |
커널 장치 |
| slice | .slice |
cgroup 계층 그룹 |
unit 파일 우선순위(높은 순): /etc/systemd/system/(관리자 수정, 최우선) > /run/systemd/system/(런타임) > /usr/lib/systemd/system/(패키지 기본, Rocky 10부터 여기가 기본).
target — runlevel의 현대적 대체
과거 runlevel은 숫자였다(0~6). systemd는 이름 있는 target으로 대체했다.
| target | 구 runlevel | 의미 |
|---|---|---|
poweroff.target |
0 | 종료 |
rescue.target |
1, s, single | 단일 사용자(구조) |
multi-user.target |
3 | 텍스트 다중 사용자(서버 표준) |
graphical.target |
5 | GUI 다중 사용자 |
reboot.target |
6 | 재부팅 |
emergency.target |
— | 최소 응급(루트만, 거의 아무것도 마운트 안 함) |
service unit 파일 구조
# /usr/lib/systemd/system/sshd.service (예시 형태)
[Unit]
Description=OpenSSH server daemon
After=network.target auditd.service # 의존 순서
[Service]
Type=notify # 시작 완료 신호 방식
ExecStart=/usr/sbin/sshd -D $OPTIONS # 시작 명령
ExecReload=/bin/kill -HUP $MAINPID # 재로드 명령
Restart=on-failure
[Install]
WantedBy=multi-user.target # enable 시 어느 target에 걸지
Type이 서비스 시작을 어떻게 판정하느냐를 결정한다: simple(기본, 즉시 시작으로 간주), forking(fork 후 부모가 종료되면 시작 완료), notify(sd_notify로 준비 신호 받아야 시작 완료), oneshot(일회성).
부팅 시간은 어디서 걸리나 — systemd-analyze
systemd-analyze는 부팅 시간을 세 단계로 쪼개 보여준다.
| 단계 | 대략 시간 | 의미 |
|---|---|---|
| kernel | 1-5초 | 커널 자체 초기화 |
| initrd | 2-10초 | initramfs에서 루트 마운트(LVM/암호화면 더 김) |
| userspace | 5-30초 | systemd가 서비스 올리는 시간 |
Startup finished in 3.1s (kernel) + 5.5s (initrd) + 12.8s (userspace) = 21.4s
graphical.target reached after 12.5s in userspace
userspace가 길면 systemd-analyze blame으로 어떤 서비스가 느린지 찾아라. 보통 NetworkManager(네트워크 대기)나 초기화가 무거운 DB가 병목이다. 부팅 최적화의 첫 단추는 "어디서 걸리나"를 아는 것이다.
Rocky 10에서 직접 확인하기
미검증(출처 인용). Rocky 10 VM에서 직접 실행 권장.
# Rocky 10 — UEFI인가 BIOS인가
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS/Legacy"
# Rocky 10 — 어느 커널로 부팅하나 (BLS 엔트리)
ls /boot/loader/entries/
cat /boot/loader/entries/$(ls /boot/loader/entries/ | head -1)
systemctl --version
확인할 것: Rocky 10은 systemd 257.
systemd 257 (257.x)
+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP ...
# Rocky 10 — 서비스 운영
systemctl status sshd # 현재 상태
sudo systemctl start sshd # 즉시 시작
sudo systemctl enable sshd # 부팅 시 자동 시작 등록
systemctl is-enabled sshd # 자동 시작 여부
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: active (running) since ...
Main PID: 1234 (sshd)
# Rocky 10 — target 관리
systemctl get-default # 현재 기본 target (보통 multi-user.target)
sudo systemctl set-default graphical.target # 기본 변경
sudo systemctl isolate rescue.target # 즉시 전환(로그아웃 발생)
# Rocky 10 — 부팅 로그 분석 (어디서 느리거나 막혔나)
journalctl -b # 현재 부팅 전체 로그
systemd-analyze # 부팅 시간 요약
systemd-analyze blame | head # 서비스별 시작 시간(느린 순)
systemd-analyze critical-chain # 병목 서비스
journalctl -u sshd # 특정 서비스 로그
journalctl -p err -b # 이번 부팅 에러만
흔히 묻는 것, 흔히 틀리는 것
| 오해 | 정정 |
|---|---|
"enable하면 지금 시작된다" |
아니다. enable은 부팅 시 자동 시작 등록만. 즉시 시작은 start |
"start하면 부팅 후에도 자동이다" |
아니다. start는 즉시 시작만. 재부팅 후엔 자동 아님 |
| "unit 파일을 고치면 바로 적용된다" | 아니다. systemctl daemon-reload로 systemd가 다시 읽게 해야 |
"구 /etc/sysconfig/network-scripts/를 써야 한다" |
Rocky 10은 NetworkManager(nmcli) 중심 |
"service sshd restart는 안 된다" |
된다(호환 래퍼). 단 System V 스크립트 자체는 deprecated |
| "모든 서비스가 순차 시작한다" | 아니다. systemd는 병렬 시작(의존성만 충족하면 동시) |
| "initramfs는 안 쓰는 게 빠르다" | LVM/RAID/암호화 루트면 initramfs 없이 부팅 불가 |
| "Rocky 10도 cgroup v1을 쓴다" | 아니다. systemd 257이 cgroup v2 강제. v1 경로는 동작 안 함 |
요약 — 이 글의 결론
- 부팅 6단계: 펌웨어(POST) → GRUB2 → 커널+initramfs → systemd(PID 1) → target → 로그인.
- initramfs = 임시 루트. 커널이 혼자 마운트 못 하는 루트(LVM/RAID/암호화) 환경을 제공. 없으면 부팅 불가.
- systemd = PID 1. 병렬 시작 + cgroup 자원 관리 + socket activation + journald 통합 로그.
- unit/target: systemd의 관리 단위(unit)와 동기화 지점(target=runlevel 대체, multi-user=3, graphical=5).
- enable vs start: enable=부팅 자동 등록, start=즉시 시작. 보통 둘 다 필요. unit 수정 후엔 반드시
daemon-reload. - Rocky 10 특이: systemd 257, cgroup v2 강제(v1 폐기), System V deprecated, BLS 부트 엔트리, 설정 기본 위치
/usr/lib/systemd/. - 부팅 병목은
systemd-analyze blame으로 잡는다 — userspace가 길면 서비스 탓.
생각해 볼 문제
- 전원 ON부터 systemd가 시작되기까지의 단계를 순서대로 말하라.
- 왜 커널이 곧바로 루트 파티션을 마운트하지 않고 initramfs를 거치는가?
- systemd의 PID는 왜 1인가? (03장의 fork 연쇄와 연결해 생각해 보라)
enable과start의 차이. 두 단계 모두 필요한 이유는?- unit 파일을 수정한 뒤 반드시 해야 하는 명령은? 안 하면 어떻게 되는가?
- 부팅이 느릴 때 어느 명령으로 병목 서비스를 찾는가?
참고
- Rocky Linux 10 Admin Guide - System Startup - 접근 2026-07-09 (부팅 흐름 1차)
- RHEL 10 Release Notes - systemd 257 - 접근 2026-07-09
- RHEL 10 - Configuring kernel command-line parameters - 접근 2026-07-09 (grubby/BLS)
- man page:
man systemctl,man systemd.unit,man systemd.target,man journalctl,man bootup(7)
'Tech Artifacts > Linux' 카테고리의 다른 글
| Linux - 06. io device (0) | 2026.07.09 |
|---|---|
| Linux - 05. filesystem (0) | 2026.07.09 |
| Linux - 04. memory (0) | 2026.07.09 |
| Linux - 03. process (0) | 2026.07.09 |
| Linux - 01. overview (0) | 2026.07.08 |
