-
systemd 완벽 정복 : 유닛(Unit)부터 systemctl 명령어까지임베디드 개발 환경 이야기 2025. 9. 15. 14:27
지난 포스팅에서는 모든 프로세스의 시작점인 init 시스템에 대해 배우며, 낡은
SysVinit을 대체한 현대적인systemd가 왜 등장했는지 알아보았습니다.systemd가 '스마트 팩토리'처럼 병렬 처리와 효율적인 의존성 관리로 부팅 속도를 획기적으로 개선했다는 점을 기억하실 겁니다.오늘은 이 강력한 '스마트 팩토리'의 내부로 들어가, 그 설계 철학은 무엇인지, 그리고 우리는 이 공장을 어떻게 제어하고 원하는 기계를 들여놓을 수 있는지, 즉
systemd를 실제로 어떻게 사용하고 활용하는지에 대해 집중적으로 알아보겠습니다.
Part 1. systemd의 핵심 철학, 유닛(Unit)
systemd를 이해하기 위한 가장 첫 번째 관문은 바로 유닛(Unit)이라는 개념입니다.systemd는 자신이 관리하는 모든 대상을 '유닛'이라는 표준화된 단위로 취급합니다.
서비스, 마운트 포인트, 소켓, 심지어는 특정 시스템 상태까지도 모두 유닛으로 정의됩니다.비유: 시스템을 조립하는 '레고(LEGO) 블록'
systemd의 유닛은 레고 블록과 같습니다. 각 블록(유닛)은 모양과 역할이 다릅니다.service유닛: 엔진이나 모터 같은 '동작' 블록socket유닛: 센서나 버튼 같은 '입력' 블록target유닛: 여러 블록을 모아 만든 '자동차의 차체' 같은 중간 조립품
우리는 이 표준화된 레고 블록들을 조립 설명서(설정 파일)에 따라 연결하여,
'자동차'라는 하나의 완성된 시스템을 만들어냅니다.가장 자주 만나게 될 유닛의 종류는 다음과 같습니다.
*.service: 가장 기본적이고 중요한 유닛. 데몬이나 애플리케이션 같은 백그라운드 서비스를 정의합니다. (예:network.service,my-avn-app.service)*.socket: 네트워크 소켓이나 파일시스템 소켓을 정의합니다. 특정 소켓에 요청이 들어올 때만 연결된.service유닛을 활성화시키는 '온디맨드' 실행의 핵심입니다.*.target: 여러 유닛을 논리적으로 그룹화하는 유닛입니다.SysVinit의 '런레벨'과 비슷한 역할을 하며, 특정 상태에 도달하기 위해 필요한 다른 유닛들의 의존성을 정의합니다. (예:multi-user.target,graphical.target)*.mount: 파일 시스템의 마운트 포인트를 정의합니다.*.timer: 특정 시간에 또는 주기적으로 잡(job)을 실행시키는cron과 유사한 역할을 합니다.
이처럼 모든 것을 '유닛'으로 표준화했기 때문에, 우리는
systemctl이라는 단 하나의 명령어로 시스템의 모든 구성요소를 일관되게 관리할 수 있습니다.
Part 2. 내 손으로 서비스 만들기: 유닛 파일 작성법
백문이 불여일견!
systemd가 관리할 수 있도록, 우리의 AVN 메인 애플리케이션(my-avn-app)을 위한.service유닛 파일을 직접 만들어 보겠습니다.유닛 파일은 보통
/etc/systemd/system/디렉터리에유닛이름.유닛타입형식으로 만듭니다. (예:my-avn-app.service)파일 내용은
[섹션]과키=값형식으로 이루어진 간단한 텍스트 파일입니다.my-avn-app.service# 이 유닛에 대한 설명 (사람이 보기 위함) [Unit] Description=My Awesome AVN Main Application # 이 서비스는 네트워크와 사운드 시스템이 준비된 '이후에' 시작되어야 함 After=network-online.target sound.target # 서비스의 실제 동작 방식 정의 [Service] # 'simple'은 ExecStart 명령이 주 프로세스임을 의미 (가장 일반적) Type=simple # 서비스를 시작하기 위해 실행할 명령어 ExecStart=/usr/bin/my-avn-app # 서비스가 비정상적으로 종료되면 자동으로 재시작 Restart=on-failure # 이 유닛을 어떻게 시스템에 '설치'할 것인지 정의 [Install] # 'systemctl enable' 명령을 사용했을 때, multi-user.target에 포함되도록 함 # 즉, 일반적인 다중 사용자 모드로 부팅될 때 이 서비스를 시작하라는 의미 WantedBy=multi-user.target각 섹션의 역할을 다시 정리해볼까요?
- [Unit] 섹션 (이력서): 이 유닛이 누구이며, 다른 유닛과 어떤 관계(실행 순서)를 갖는지 정의합니다.
- Description: 사람이 알아보기 쉬운 설명.
- After=, Before=: 유닛 간의 실행 순서를 정의합니다. (가장 중요!)
- Wants=, Requires=: 의존성을 정의합니다. (Requires는 더 강력한 의존성)
- [Service] 섹션 (행동 지침): .service 유닛의 실제 동작 방식을 상세하게 정의합니다.
- Type=: 서비스의 프로세스 타입. (simple, forking, oneshot 등)
- ExecStart=: 서비스를 시작할 때 실행할 명령어. (필수!)
- ExecStop=: 서비스를 중지할 때 실행할 명령어.
- Restart=: 어떤 상황에서 서비스를 재시작할지 정의합니다. (on-failure, always 등) (안정성 확보의 핵심!)
- [Install] 섹션 (소속 부서): systemctl enable/disable 명령을 통해 이 유닛이 어떤 target에 소속될지를 정의합니다.
이제 이 파일만 /etc/systemd/system에 넣어주면, systemd는 우리의 my-avn-app을 하나의 정식 서비스로 인식하고 관리할 수 있게 됩니다!
Part 3. 시스템을 지휘하는 마법 지팡이, systemctl
유닛 파일을 만들었다면, 이제 systemctl 명령어로 시스템을 지휘할 차례입니다. systemctl은 systemd를 제어하는 가장 중요한 도구입니다.
유닛의 라이프사이클 관리
- systemctl start my-avn-app.service: 서비스를 즉시 시작합니다.
- systemctl stop my-avn-app.service: 서비스를 즉시 중지합니다.
- systemctl restart my-avn-app.service: 서비스를 재시작합니다.
부팅 시 자동 실행 관리
- systemctl enable my-avn-app.service: 부팅 시 자동으로 시작되도록 등록합니다. ([Install] 섹션의 WantedBy 설정을 사용)
- systemctl disable my-avn-app.service: 자동 시작을 해제합니다.
상태 확인 및 분석
- systemctl status my-avn-app.service: 서비스의 현재 상태를 아주 상세하게 보여줍니다.
(실행 중인지, 언제 시작했는지, PID는 무엇인지, 최근 로그는 어떤지 등 디버깅의 시작점!) - systemctl is-active my-avn-app.service: 서비스가 실행 중인지 여부만 간단히 확인합니다.
- systemctl is-enabled my-avn-app.service: 부팅 시 자동 실행되도록 등록되어 있는지 확인합니다.
⚠️ 아주 중요한 팁!
.service 파일을 수정했다면, 반드시 systemctl daemon-reload 명령어를 실행해야 systemd가 변경된 내용을 인식합니다. 이걸 잊어서 왜 적용이 안 되지? 하고 헤매는 경우가 정말 많습니다.Part 4. 모든 흔적을 기록하는 수사관, journalctl
systemd는 journald라는 자체 로깅 시스템을 가지고 있습니다.
과거처럼 여러 서비스가 /var/log 아래에 제각각 로그 파일을 남기는 대신, 모든 시스템 이벤트를 하나의 중앙화된 저널에 기록합니다.journalctl은 이 저널을 조회하는 강력한 도구입니다.
- journalctl: 모든 로그를 시간순으로 보여줍니다.
- journalctl -f: 새로운 로그가 기록될 때마다 실시간으로 보여줍니다. (마치 tail -f 처럼)
- journalctl -b: 이번 부팅 이후의 로그만 보여줍니다. (부팅 문제 분석 시 필수)
- journalctl -u my-avn-app.service: 특정 유닛(서비스)에 대한 로그만 필터링해서 보여줍니다. (가장 많이 사용하게 될 명령어!)
- journalctl -p err: 에러(err) 등급 이상의 심각한 로그만 보여줍니다.
journalctl 덕분에 우리는 더 이상 로그 파일을 찾아 헤맬 필요 없이, 원하는 조건으로 로그를 빠르고 정확하게 분석하여 버그의 원인을 찾아낼 수 있습니다.
오늘은 systemd의 핵심 개념인 유닛(Unit)부터, .service 파일을 직접 작성하고 systemctl과 journalctl로 서비스를 제어하고 분석하는 방법까지 알아보았습니다.
- systemd는 모든 것을 '유닛' 단위로 관리한다.
- 우리는 .service 파일을 작성하여 우리의 앱을 시스템 서비스로 등록할 수 있다.
- systemctl은 서비스의 시작, 중지, 자동 실행을 관리하는 제어 도구다.
- journalctl은 시스템의 모든 로그를 분석하는 강력한 디버깅 도구다.
이제 systemd는 더 이상 복잡하고 낯선 존재가 아니라, 우리 AVN 시스템의 부팅 시간을 최적화하고, 안정성을 높이기 위해 마음껏 활용할 수 있는 강력한 아군이 되었습니다.
'임베디드 개발 환경 이야기' 카테고리의 다른 글
부트로더(Bootloader)란? 시스템의 첫 숨결, 부트로더와 U-Boot 깊이 보기 (0) 2025.09.15 ADB란? ADB(Android Debug Bridge) 사용법 완벽 가이드 (0) 2025.09.15 모든 프로세스의 시작점, init system 과 systemd란? (0) 2025.09.15 커널(kernel)이란? 시스템의 지배자, 리눅스 커널(Kernel)의 모든 것 (0) 2025.09.15 BSP란? 임베디드 시스템의 통역사 BSP 파헤치기 (0) 2025.09.15