티스토리 뷰

Technology/Linux

systemd로 서비스 관리하기

캡틴테크 2023. 3. 7. 11:34
반응형

linux에서 서비스의 실행 관리 그리고 에러 등을 모니터링할 수 있는 방법이 있습니다. 바로 systemd 인데요 이전에는 시작프로그램의 역할만을 하는 initd 라던지 하는 조촐한 것에서 지금은 거의 systemd를 사용해서 이러한 서비스들을 관리하고 있습니다. 좀더 자세한 내용을 보기 위해 위키피디아를 확인해 보도록 하겠습니다.

systemd 란?

systemd는 일부 리눅스 배포판에서 유닉스 시스템 V나 BSD init 시스템 대신 사용자 공간을 부트스트래핑하고 최종적으로 모든 프로세스들을 관리하는 init 시스템입니다. systemd 라는 이름 뒤에 추가된 d는 유닉스에서 데몬(daemon)을 나타내며 systemd의 기본 목표들 가운데 하나는 모든 배포판들에 대하여 기본 리눅스 구성과 서비스 동작을 통일하는 것입니다. 2015년을 기준으로 수많은 리눅스 배포판들은 systemd를 자신들의 기본 init 시스템으로 채택하고 있고, 이런 채택이 증가되어 기능이 복잡해졌을뿐 아니라 배포판들이 채택을 강요받게 되면서 소프트웨어가 유닉스 철학을 위반했다는 비평을 받기도 했습니다.

시스템디 아키텍쳐

근데 내 서비스를 반드시 systemd애 추가해야할 까요? 그건 자신이 만든 프로그램이 어떻게 라이프사이클을 관리할 것인가에 대해 질문해 보아야합니다. 시스템을 전체 브링업 했을때, 과연 내 프로그램은 누가 실행시켜 줄 수 있을까요? 그리고 만약 어떤 이유로 종료됬다면 어떻게 다시 실행시켜 줄 수 있을까요? 물론 휴먼이 매번 직접 실행해줄 수 있지만 그건 굉장히 큰 리소스가 드는 일이겠지요. 따라서 자신의 서비스를 언제 어떻게 실행되게 하고, 에러일때 어떻게 할꺼냐, 우선순위는 어떤 서비스 앞이나 뒤에 해달라 등 이러한 설정을 통해 전체 시스템이 안정적으로 구동될 수 있게 만드는게 근본적인 systemd의 역할이라고 볼 수 있습니다. 자 이제, 자신의 서비스를 한번 등록하러 가볼까요?

systemd에 내 서비스 등록하기

파일 위치 : /etc/systemd/system/나의서비스명.service

파일 구성

  • 예 1
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=myuser
Group=mygroup
EnvironmentFile=/home/myuser/env/systemd_env

# 또는
# Environment=MYVAL="myvalresult"

WorkingDirectory=/home/myuser/myapp
ExecStart=/home/myuser/bin/gunicorn_start
Restart=always

[Install]
WantedBy=multi-user.target
  • 예 2
[Unit]
Description=Unit for starting a basic Django app 

[Service]
Restart=on-failure
WorkingDirectory=/var/www/hello
ExecStart=/srv/env/bin/gunicorn hello.wsgi -b 0.0.0.0:8000

[Install]
WantedBy=multi-user.target
  • 예 3
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=foo
Group=www-data
WorkingDirectory=/home/foo/django_test/repo
ExecStart=/home/foo/django_test/venv/bin/gunicorn \
        --workers 3 \
        --bind unix:/home/foo/django_test/run/gunicorn.sock \
        conf.wsgi:application

[Install]
WantedBy=multi-user.target

 

이제 내용에 대해서 알아보도록 할텐데요, 아마도 쓰는 옵션 위주로 사용할 테지만 이런게도 설정할 수 있구나하는 관점에서 알아두시면 좋겠습니다.

Service unit

  • 기본적으로 [Unit], [Install] 섹션이 존재하며 [Service] 섹션에 서비스 유닛에 대한 옵션 값들을 정의
  • systemctl을 이용하여 서비스를 시작하면 systemd는 해당 유닛 파일이 존재하는지 확인하고, 없다면 같은 이름으로 된 init 스크립트 파일을 찾아 실행하지만 systemd가 모든 init 스크립트를 실행할 수 있는 것은 아님

[Service] 섹션의 옵션

  1. Type : Service 유닛의 유형
    - simple
    - forking
    - oneshot
    - dbus
    - notify
  2. ExecStart — 유닛이 시작할 때 실행할 명령이나 스크립트의 경로
    - ExecStartPre : ExecStart 이전에 실행될 사용자 정의 명령어 지정
    - ExecStartPost : ExecStart 이후에 실행될 사용자 정의 명령어 지정
  3. ExecStop — 유닛이 Stop 되었을 때, 실행할 명령이나 스크립트
  4. ExecReload — 유닛이 Reload 되었을 때, 실행할 명령이나 스크립트
  5. Restart — 활성화되면, 이미 중지되어 있는 유닛을 제외한 유닛이 종료되면 서비스를 재시작
  6. RemainAfterExit (default : False이며 보통 Type=oneshot과 함께 사용) — True로 세팅되었을 경우, 서비스는모든 프로세스가 종료되어도 실행상태인 것으로 간주입니다.

Device unit

  • sys/udev 장치 트리에에 등록된 정보를 담고 있다.
  • 하드웨어가 추가되거나 디스크를 파티셔닝 한 경우, 생성됨
  • 장치유닛의 경우, unit 파일에 [Device] 섹션이 따로 존재하지 않고, systemd가 ‘systemd’라는 udev tag 가 표시된 모든 장치의 장치유닛파일을 동적으로 생성

Mount unit

  • 마운트 포인트를 관리하는 유닛
  • 사용자가 파일시스템이 생성된 파티션 장치를 마운트 포인트에 연결하면 마운트 유닛이 생성되고 마운트를 해제하면 마운트 유닛이 제거됨
  • 즉 /etc/fstab 파일에 마운트 정보를 등록한 뒤 시스템을 재부팅하면 마운트 유닛 파일이 생성됩니다. 마운트 유닛은 유닛 파일에서 [Mount]섹션에 정보가 저장됨

Automount unit

  • 자동마운트 유닛은 유닛 파일에서 [Auto-mount]섹션에 정보가 저장됨

Swap unit

  • 스왑 영역을 관리하는 유닛
  • 스왑 영역을 활성화하면 스왑 영역으로 사용되는 (파티션 장치나 파일)이름뒤에 .swap 확장자가 추가된 유닛이 생성

Target unit

  • init 프로세스에서 런 레벨과 매핑되는 유닛

Path unit

  • 특정 파일시스템이나 디렉토리를 모니터링하기 위한 정보를 저장
  • [Path]섹션에 저장되며, 같은 이름의 서비스 유닛이 존재(path, timer, socket)

Timer unit

  • crontab 같이 일정주기마다 유닛을 실행 할 때 사용하는 유닛
  • 같은 이름의 서비스 유닛이 존재(path, timer, socket)

Snapshot unit

  • 특정시점의 모든 유닛상태를 저장하는 저장하는 유닛
  • 파일형태로 저장되지 않음
  • systemctl snapshot(스냅샷 생성), systemctl isolate(스냅샷 사용), systemctl delete(스냅샷 제거)

Socket unit

  • systemd에 의해 제어되는 IPC(Inter Process Communication), 네트워크 소켓, 파일 시스템의 파일입출력(FIFO)에 대한 정보를 가지고 있는 unit
  • [Socket] 섹션에 저장되며 socket unit은 같은 이름을 가진 service unit이 존재(path, timer, socket)

scope unit

  • 유닛 파일에 의해 구성되지 않고, 오직 systemd의 bus interface를 이용하여 계획적으로 생성
  • 프로세스의 집합을 관리하며 서비스 유닛과 다르게 외부적으로 생성된 프로세스를 관리하고 자식프로세스를 생성하지 않음
  • 자원을 조직화하고 관리하기 위해 시스템 서비스 작업 프로세스들을 그룹화시키는 것이 목적이며, 특정 scope unit의 상태를 확인하면 CGroup으로 여러 개의 프로세스가 그룹화 된 것 을 확인 가능

slice unit

  • 해당 유닛에는 별도의 [Slice] 섹션이 존재하지 않음
  • 슬라이스 유닛은 프로세스 그룹의 자원을 계층적으로 관리하기 위한 개념으로 슬라이스 유닛은 CGroup 트리에 하나의 노드를 생성하므로써 자원을 관리
  • 프로세스를 관리하는 유닛인 Scope unit/ Service unit은 특정 Slice unit에 할당될수도 있다.
  • slice unit은 프로세스에 자원을 제한하거나 할당하는 역할을 함
 
 

서비스 확인 

  • 서비스 활성화 및 시작
sudo systemctl enable 내서비스이름
sudo systemctl start 내서비스이름
  • 서비스 종료 및 비 활성화
sudo systemctl stop 내서비스이름
sudo systemctl disable 내서비스이름
  • 서비스 에러로그 확인
sudo journalctl | grep 내서비스이름

 

반응형
댓글