systemd service
systemd에 대해서 몇 번 곁다리로 다루었는데, systemd(System daemon)은 시스템 부팅 시 가장 먼저 생성된 후 다른 프로세스를 실행하는 init 역할을 대체한다. 대부분의 리눅스 시스템에 공식적으로 채택되었다.
service는 특정 상항에 따라 시작하거나 중지되는 background process를 말한다.
systemd service file은 systemd가 구문 분석하고 이해할 수 있는 형식으로 작성된 파일로, 사용자가 지시한 작업을 수행한다.
대부분의 리눅스 배포판에서 systemd를 사용하고 있어, 이 글에서는 systemd가 관리할 서비스를 생성하고 등록하는 방법을 정리한다.
.service 파일 구조
systemd가 관리하는 서비스 파일의 확장자는 .service이며, .service 파일은 크게 Unit, Service, Install 섹션으로 구성되어 있다. 아래는 실제로 동작하지는 않지만 .service 파일의 기본 구조를 보기 위해 작성한 예시이다.
[Unit]
Description=Apache web server
After=network.target
Before=nextcloud-web.service
[Service]
ExecStart=/usr/local/apache2/bin/httpd -D FOREGROUND -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
Type=notify
Restart=always
[Install]
WantedBy=default.target
RequiredBy=network.target
Unit
unit 자체에 대한 세부 정보와 설명을 포함한다. 여기서 세부 정보란 설명은 무엇인지, 의존성은 무엇인지 등이 해당된다.
Unit 섹션의 속성은 아래와 같다.
- Description : 사람이 읽을 수 있는 서비스 제목
- After : 서비스에 대한 종속성. target 또는 다른 서비스가 올 수 있다.
- Before : 현재 서비스를 지정한 서비스 전에 실행시킨다. 위의 예시에서는 nextcloud-web 서비스 전에 apaceh web server를 실행해야 한다. target 또는 다른 서비스가 올 수 있다.
Service
서비스 실행과 종료에 대한 세부 정보를 포함한다. service 섹션의 속성은 아래와 같다.
- ExecStart : 서비스 시작 실행해야 하는 명령어
- ExecReload : 시스템을 다시 시작하는 방법을 지정하며, 선택 옵션이다.
- Type : 서비스에 대한 프로세스 시작 유형을 나타낸다. simple, exec, forking, oneshot, dbus, notify, idle 등을 지정할 수 있다.
- Restart : 상황에 따라 서비스 재시작 여부를 지정한다. no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always을 지정할 수 있다.
Install
.service 파일의 설치를 처리한다. 서비스를 활성화/비활성화하기 위한 systemctl enable, systemctl disable 실행 시 사용한다. Install 섹션의 속성은 아래와 같다.
- WantedBy : After, Before 속성과 비슷하지만, WantedBy는 systemd와 동등한 런레벨을 지정하는 데 사용된다는 점에서 차이가 있다. default.target은 시스템 초기화 완료 시점 즉, 사용자 로그인 요청 시점을 의미하며 대부분의 user-facing 서비스가 사용한다.
- RequiredBy : WantedBy와 유사하지만 RequiredBy는 hard dependencies을 지정한다는 점에서 차이가 있다.
참고로 .service 파일의 주석은 # 기호를 사용한다.
.service 생성
사용자 지정 .service 파일을 작성하고 등록해 본다. 이 글에서는 시스템 부팅 시 루트 사용자로 실행할 스크립트를 작성해 본다.
실행 스크립트
root 사용자로 시스템 부팅 시 실행할 스크립트로, 사용자가 root이면 apt update를 수행한다. 명령어 수행 시 출력되는 오류는 /root/logs/apt-update.log에 기록된다.
#!/bin/bash
if [ ${EUID} -ne 0 ]
then
exit 1 # this is meant to be run as root
fi
apt update 1>/dev/null 2>>/root/logs/apt-update.log
작성한 스크립트는 실행이 가능하도록 권한을 부여한다.
.service 파일
루트 사용자로 실행하는 .service 파일은 /etc/systemd/system/ 경로에 위치해야 한다.
해당 경로에 아래와 같이 apt-update-on-boot.service 파일을 작성한다.
[Unit]
Description=Keeping my sources fresher than Arch Linux
After=multi-user.target
[Service]
ExecStart=/usr/bin/bash /root/.scripts/apt-update.sh
Type=simple
[Install]
WantedBy=multi-user.target
.service 활성화
사용자 지정 .service 파일을 작성했다면 이제 활성화한다
1. systemd reload
systemd가 생성한 서비스 파일을 읽도록 한다.
systemctl daemon-reload
2. service 활성화
생성한 서비스를 활성화시킨다.
systemctl enable SERVICE-NAME.service
# 예시
systemctl enable apt-update-on-boot.service
서비스가 정상적으로 enable 상태에 있는지 확인한다.
systemctl status SERVICE-NAME.service
systemctl is-enabled SERVICE-NAME.service
# 예시
systemctl status apt-update-on-boot.service
systemctl is-enabled apt-update-on-boot.service
.service 동작 확인
서비스가 활성화되었으므로 정상적으로 동작하는지 확인한다. 이 글의 경우 부팅 시 실행하는 서비스이므로 서버를 재부팅한다.
먼저 결과 파일이 생성되는 경로에 아무 파일이 없는 것을 확인한다.
서버 재부팅
shutdown -r now
결과 파일 경로 확인
결과 파일이 잘 생성되고, service가 정상적으로 실행된 상태임을 확인한다.
shutdown .service 예시
아래 예시는 서버 shutdown 시 실행하는 .service 파일 예시다.
[Unit]
Description=Log uptime in scoreboard
DefaultDependencies=no
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/pratham/.scripts/big-uptime.sh
TimeoutStartSec=0
[Install]
WantedBy=shutdown.target
참고 문서
https://linuxhandbook.com/create-systemd-services/
https://www.freedesktop.org/wiki/Software/systemd/?ref=linuxhandbook.com