formulous

주니어 개발자의 개발 지식 공유 블로그입니다.

Linux

[linux] CentOS7 환경의 systemd에 대해 알아봅시다.

formulous 2023. 1. 16. 20:48

 

 

안녕하세요.

 

오늘은 CentOS7 환경에서 init.d를 대체하게 된 systemd에 대해 알아보겠습니다.

 

 

init.d, systemd에서 ddaemon의 약자입니다.

 

daemon은 시스템의 background에서 실행되는 프로세스인데요.

 

이러한 daemon의 실행과 관리를 담당하고 있는 daemon이 바로 systemd입니다.

 

그리고 이 systemd는 시스템을 부팅했을 때에 가장 먼저 실행되는 daemon이에요.

 

 

 

이전의 CentOS 버전에서는 init이라는 데몬으로 프로세스를 관리하고 있었는데요.

 

init.d의 약점을 보완함과 동시에 여러 가지 기능을 추가하여 나온 것이 바로 systemd입니다.

 

그리고 init.d가 그랬듯이 init.d를 대체하는 systemd 역시 PID 1을 부여받습니다.

 

 

 

systemd는 리소스를 unit이라는 단위로 분류하여 관리하게 됩니다.

 

.service,  .socket, .mount, .swap 등등 여러 가지 유닛이 존재하는데요.

 

오늘 저희가 알아볼 유닛은 가장 많이 쓰이기도 하고 가장 중요하기도 한 service 유닛입니다.

 

 

 

서비스는 서버에서 service와 application을 어떻게 관리할 것인지 명세합니다.

 

예를 들어 service의 시작과 중지 방법을 정의하기도 하고, 조건에 따라 자동적으로 실행하게끔 설정해 줄 수도 있습니다.

 

서비스 Unit을 추가하고 싶다면 /etc/systemd/system 경로에 [파일 이름].service 형식으로 파일을 등록해 주면 되는데요.

 

 

 

해당 service 파일로 쉘 스크립트를 실행하는 간단한 예시를 살펴보도록 할까요?

 

 

auto_start.service

 

 

제가 업무 중에 등록하여 사용한 auto_start.service 유닛을 가져와봤습니다.

 

Serivce 유닛에서는 [Unit] [Service] [Install] 세 가지 섹션이 존재하는데요.

 

각 섹션마다 서비스 유닛이 어떻게 동작할지 정의해 주는 다양한 옵션들이 있습니다.

 

제가 작성한 서비스 유닛을 기준으로 설명드리겠습니다.

 

나머지 옵션들이 궁금하시다면 여기를 참조해 주세요.

 

 

  •  Unit

 

먼저 Unit 섹션에 대해 알아봅시다.

 

Unit 섹션은 서비스가 실행될 때 가장 먼저 실행되는 섹션입니다.

 

 

[Unit]
Description = RMS Start Service
After = network.target

 

 

위에서 Unit 섹션에 대한 두 가지 옵션을 볼 수 있습니다.

 

Description은 해당 유닛에 대한 설명입니다.

 

해당 유닛이 어떠한 역할을 하는지 핵심적인 정보를 짧고 간결하게 설명하도록 작성하는 게 좋습니다.

 

After는 유닛들의 순서를 정의해 줍니다.

 

After = network.target의 의미는 말 그대로 network.target 이 실행된 이후에 auto_start.service 유닛을 실행하라는 의미죠.

 

After가 있으면 Before 옵션도 있겠죠?? 사용법은 마찬가지입니다.

 

 

  • Service
[Service]
Type = simple
ExecStart = /start.sh
Restart = always

 

 

다음으로 Service 섹션의 내용을 살펴볼까요?

 

Service 섹션의 Type은 말 그대로 유닛의 타입을 지정하게 됩니다.

 

타입은 유닛이 어떤 식으로 동작되는지 정의하게 되는데요.

 

타입에는 아래와 같이 여러 가지 종류가 있습니다.

 

  • simple : 타입을 명시하지 않을 경우 default값으로 simple로 동작하게 됩니다. simple은 메인 프로세스가 시작되면 systemd 유닛이 정상적으로 실행되었다고 판단하고 active 상태로 바꾸게 됩니다. 실행된 메인 프로세스가 끝날 때까지 기다려주지 않고 연결된 다음 유닛을 실행하기 때문에, 네트워크 작업이 끝날 때까지 기다렸다가 다음 유닛을 실행해야 하는 상황이라면 다른 옵션을 사용해주어야 합니다.
  • forking : 서비스가 자식 프로세스를 생성할 때 사용합니다. 이때 자식을 생성한 프로세스는 곧장 나갈 때 사용하게 됩니다.
  • oneshot : 프로세스가 오래 실행되지 않을 때 systemd가 이 프로세스의 종료를 기다려야 한다면 oneshot을 사용하면 됩니다.
  • dbus : 지정된 Bus가 D-Bus에 준비될 때까지 기다리고 D-Bus가 준비되면 서비스가 실행됩니다.
  • notify : 서비스가 startup이 끝날 때 시그널을 발생시킵니다. 그리고 systemd는 다음 유닛으로 넘어가게 됩니다.
  • idle : 모든 작업이 실행될 때까지 서비스가 실행되지 않고, 마지막에 행해져야 하는 작업이 필요할 때 사용하는 유닛 타입입니다.

 

 

다음으로 ExecStart 옵션은 해당 유닛이 실행할 커맨드의 경로를 지정하게 됩니다.

 

저의 경우 해당 유닛이 실행될 때 /start.sh 쉘 스크립트를 실행하도록 작성해 두었습니다.

 

start.sh 스크립트 내에는 제 프로젝트를 실행하기 위한 여러 가지 환경 설정값이 리눅스 커맨드 형태로 기록되어 있습니다.

 

 

Restart 옵션은 systemd가 자동으로 재시작을 시도하는 상황을 정의합니다.

 

always, on-success, on-failure, on-abnormal, on-abort, on-watchdog 옵션을 사용할 수 있습니다.

 

 

  • Install

 

마지막으로 Install 섹션입니다.

 

Install 섹션은 보통 서비스 파일의 마지막에 존재하게 됩니다.

 

해당 섹션은 optional 한 특징을 가지고 있습니다. 즉, 있어도 되고 없어도 된다는 뜻입니다.

 

보통 Install 섹션은 유닛이 enable 하거나 disable 될 때 유닛이 취할 행동을 정의하게 됩니다.

 

WantedBy 옵션은 유닛이 활성화될 시에 어떻게 행동할 지에 대해 명세하게 됩니다.

 

 

 

오늘은 CentOS7에서 init.d를 대체하게 된 만능 데몬인 systemd에 대해 알아보았습니다.

 

저는 Docker 컨테이너 환경에서 부팅 즉시 해당하는 프로젝트가 바로 실행될 수 있도록 구성하는 과정에서 systemd를 접하게 되었는데요.

 

 

 

말로만 들었을 때는 어떻게 구현해야 할지 막막한 싸움이었는데, systemd를 접하고 나니 생각보다 간단하게 구현이 되었어요.

 

그리고 앞으로의 개발에도 systemd 데몬을 활용하게 되면 다른 기능을 개발할 시에도 많은 참고가 될 것 같다는 생각이 들었습니다.

 

CentOS7의 환경구성이 필요하다면 필수적으로 systemd에 대해 학습해 보시길 바랍니다.

 

 

 

오늘 포스팅은 여기서 마치겠습니다.

 

감사합니다.