Systemd Reference
Systemd 서비스 관리 레퍼런스
Systemd Reference 소개
Systemd 레퍼런스는 Ubuntu, Fedora, Debian, RHEL, Arch, SUSE 등 사실상 모든 현대 리눅스 배포판에서 사용되는 init 시스템이자 서비스 관리자인 systemd를 검색할 수 있는 빠른 참조 가이드입니다. 유닛파일 디렉티브, 서비스 설정, 타이머 스케줄링, 소켓 활성화, journalctl 로그 쿼리, systemctl 명령어, 타겟 관리, 부팅 분석의 8개 카테고리를 다룹니다. 각 항목에는 디렉티브 또는 명령어 구문, 간결한 설명, 바로 사용 가능한 설정 또는 셸 예제가 포함되어 있습니다.
Systemd는 선언적 유닛 파일을 통해 서비스, 마운트 포인트, 디바이스, 소켓, 타이머를 관리하는 통합 프레임워크를 제공하여 SysVinit와 Upstart를 대체했습니다. systemd를 이해하는 것은 리눅스 서버에 애플리케이션을 배포하는 모든 리눅스 시스템 관리자, DevOps 엔지니어, 백엔드 개발자에게 필수적입니다. 이 레퍼런스는 엔지니어가 매일 접하는 디렉티브와 명령어에 집중합니다: 적절한 의존성 순서가 있는 서비스 유닛 파일 작성, 재시작 정책 설정, 타이머 기반 cron 대체 구성, journalctl 로그 조회 등입니다.
Node.js 애플리케이션을 장애 시 자동 재시작하는 .service 유닛 파일을 작성하거나, OnCalendar 구문으로 야간 데이터베이스 백업을 스케줄링하는 .timer 유닛을 생성하거나, 온디맨드 서비스 시작을 위한 소켓 활성화를 설정하거나, 서비스, 우선순위, 시간 범위로 journalctl 출력을 필터링하거나, systemd-analyze blame으로 부팅 성능을 분석할 때, 이 치트 시트는 정확한 구문과 파라미터를 제공합니다. 모든 콘텐츠는 서버 의존 없이 브라우저에서 실행됩니다.
주요 기능
- Description, After/Before 순서 지정, Requires(필수 의존성), Wants(선택적 의존성), 부팅 타겟 연결을 위한 [Install] WantedBy를 포함한 유닛파일 [Unit] 섹션 디렉티브
- Type=simple, Type=forking, Type=oneshot, 재시작 정책(always, on-failure, no), RestartSec 지연, ExecStartPre 명령, Environment/EnvironmentFile, User/Group 실행 컨텍스트를 다루는 서비스 섹션
- 부팅 후 지연을 위한 OnBootSec, cron 스타일 스케줄링을 위한 OnCalendar(daily, weekly, *-*-* HH:MM:SS), 반복 주기를 위한 OnUnitActiveSec, 놓친 실행 보상을 위한 Persistent=true, systemctl list-timers를 포함한 타이머 유닛 설정
- TCP용 ListenStream, UDP용 ListenDatagram, 연결별 서비스 인스턴스를 위한 Accept=yes, 소켓-서비스 온디맨드 시작 패턴을 포함한 소켓 활성화
- 서비스별 로그를 위한 -u, 실시간 스트리밍을 위한 -f, 시간 범위 필터링을 위한 --since/--until, 우선순위 필터링을 위한 -p(emerg~debug), 저널 유지보수를 위한 --disk-usage/--vacuum-size를 포함한 journalctl 쿼리
- start/stop/restart, 부팅 영속성을 위한 enable/disable, 상태 및 최근 로그 확인을 위한 status, 유닛 파일 편집 후 daemon-reload, list-units 필터링, 완전 비활성화를 위한 mask/unmask, 유닛 파일 내용 보기를 위한 cat을 포함한 systemctl 작업
- multi-user.target, graphical.target, rescue.target과 기본 부팅 타겟 설정을 위한 systemctl get-default/set-default를 포함한 타겟 관리
- 총 부팅 시간을 위한 systemd-analyze, 서비스별 타이밍을 위한 blame, 의존성 체인 시각화를 위한 critical-chain, SVG 타임라인 생성을 위한 plot을 포함한 부팅 분석 도구
자주 묻는 질문
유닛 파일에서 Requires=와 Wants=의 차이점은 무엇인가요?
Requires=는 필수 의존성을 만듭니다: 요구된 유닛이 시작에 실패하면 의존하는 유닛도 실패합니다. Wants=는 선택적 의존성을 만듭니다: 원하는 유닛이 병렬로 시작되지만 실패해도 의존하는 유닛은 정상적으로 시작됩니다. 실제로 대부분의 의존성에는 시스템을 더 탄력적으로 만드는 Wants=가 선호됩니다. Requires=는 서비스가 다른 서비스 없이는 진정으로 기능할 수 없을 때 사용됩니다(예: postgresql.service에 의존하는 데이터베이스 앱).
Type=simple, Type=forking, Type=oneshot 중 어떤 것을 선택해야 하나요?
ExecStart 프로세스가 메인 서비스 프로세스이고 계속 실행될 때 Type=simple(기본값)을 사용하세요. 프로세스가 fork하여 데몬화하고 부모가 종료될 때 Type=forking을 사용합니다(전통적 데몬에서 일반적이며 보통 PIDFile=이 필요). 명령이 실행 완료 후 종료되는 스크립트에는 Type=oneshot을 사용하며, systemd는 ExecStart가 끝날 때까지 서비스를 활성으로 간주합니다. sd_notify()로 준비 상태를 알리는 서비스에는 Type=notify도 유용합니다.
cron 작업을 systemd 타이머로 어떻게 대체하나요?
두 개의 파일을 만드세요: 실행할 명령이 있는 .service 유닛(Type=oneshot)과 일치하는 .timer 유닛. 캘린더 기반 스케줄링에는 OnCalendar=를 사용합니다: OnCalendar=daily, OnCalendar=Mon *-*-* 03:00:00, 또는 15분마다 실행하려면 OnCalendar=*-*-* *:00/15:00. 놓친 실행을 보상하려면 Persistent=true를 추가합니다. systemctl enable --now myservice.timer로 활성화하고, systemctl list-timers로 예정된 타이머를 확인합니다.
systemctl daemon-reload는 무엇을 하며 언제 필요한가요?
systemctl daemon-reload는 systemd에게 디스크에서 모든 유닛 파일을 다시 읽으라고 지시합니다. /etc/systemd/system/ 또는 /usr/lib/systemd/system/의 유닛 파일을 생성, 수정, 삭제한 후에 필요합니다. 이것 없이는 systemd가 캐시된 버전의 유닛 파일을 계속 사용합니다. 유닛 파일 편집 후 서비스를 재시작하기 전에 항상 daemon-reload를 실행하세요. 서비스를 재시작하지 않으며 설정만 다시 읽습니다.
journalctl로 로그를 조회하고 필터링하는 방법은?
journalctl -u service-name으로 특정 서비스의 로그를 봅니다. -f를 추가하면 실시간 스트리밍(tail -f와 유사)입니다. --since "2024-01-01 00:00" --until "2024-01-02"로 시간 범위를 필터링합니다. -p err로 우선순위를 필터링합니다(err 이상: emerg, alert, crit, err 표시). 필터를 결합할 수 있습니다: journalctl -u nginx -p warning --since today. -b로 현재 부팅으로 제한하거나 -b -1로 이전 부팅을 봅니다. -o json-pretty로 JSON 출력도 가능합니다.
소켓 활성화란 무엇이며 언제 사용해야 하나요?
소켓 활성화는 systemd가 소켓(TCP 포트, Unix 도메인 소켓 등)에서 수신 대기하다가 연결이 도착할 때만 관련 서비스를 시작하게 합니다. 자주 접근하지 않는 서비스의 리소스 사용을 줄이고 무중단 재시작을 가능하게 합니다. ListenStream=이 있는 .socket 유닛과 일치하는 .service 유닛을 만드세요. Systemd는 열린 파일 디스크립터를 서비스에 전달합니다. 각 연결마다 별도의 서비스 인스턴스를 생성하려면 Accept=yes를 사용합니다.
시작에 실패하는 서비스를 어떻게 트러블슈팅하나요?
systemctl status service-name으로 활성 상태, 종료 코드, 최근 로그 몇 줄을 확인하세요. 그런 다음 journalctl -u service-name -n 50 --no-pager로 더 상세한 로그를 봅니다. systemctl cat service-name으로 유닛 파일을 확인합니다. 일반적인 문제로는 잘못된 ExecStart 경로, 누락된 Environment 변수, 권한 문제(User/Group 확인), 의존성 순서 문제(After=/Requires= 디렉티브)가 있습니다. systemd-analyze verify service-name으로 유닛 파일 구문을 검사할 수 있습니다.
systemd 타겟은 무엇이며 런레벨과 어떤 관계가 있나요?
타겟은 이전 SysVinit 런레벨을 대체하는 그룹핑 유닛입니다. multi-user.target은 런레벨 3(콘솔, 다중 사용자, GUI 없음)에 해당하며 서버의 기본값입니다. graphical.target은 런레벨 5(GUI가 있는 데스크톱)에 해당합니다. rescue.target은 단일 사용자 모드(런레벨 1)입니다. emergency.target은 최소한의 셸을 제공합니다. systemctl set-default로 부팅 타겟을 변경합니다. 서비스는 [Install] 섹션에서 WantedBy=를 선언하여 어떤 타겟이 시작해야 하는지 지정합니다.