Linux: systemctl daemon-reload

LinuxBeginner
지금 연습하기

소개

이 튜토리얼은 Linux 시스템에서 systemctl daemon-reload 명령을 사용하여 시스템 데몬 및 서비스를 관리하는 과정을 안내합니다. Systemd 는 대부분의 최신 Linux 배포판에서 기본 서비스 관리자이며, 서비스 구성을 적절하게 업데이트하는 방법을 이해하는 것은 Linux 사용자 및 관리자에게 필수적인 기술입니다.

이 랩에서는 systemctl daemon-reload 명령을 언제, 왜 사용해야 하는지, 서비스 파일을 생성하고 수정하는 방법, 그리고 시스템 운영을 방해하지 않고 구성 변경 사항을 적용하는 방법을 배우게 됩니다. 이 튜토리얼을 마치면 systemd 서비스 작업을 능숙하게 수행하고 구성 변경 사항을 효과적으로 적용할 수 있게 될 것입니다.

이 랩은 학습을 위해 인터넷 연결이 필요하므로, Pro 사용자만 VM 을 시작할 수 있습니다. 계정을 Pro 로 업그레이드하세요.

systemd 및 systemctl 기본 사항 이해

Systemd 는 이 랩에서 사용하고 있는 Ubuntu 22.04 를 포함하여 대부분의 최신 Linux 배포판의 서비스 및 시스템 관리자입니다. 시스템 서비스 시작 및 관리를 담당하며, systemctl은 systemd 와 상호 작용하는 데 사용되는 주요 명령줄 도구입니다.

시스템 데몬이란 무엇인가?

데몬 (daemon) 은 Linux 시스템에서 지속적으로 실행되는 백그라운드 프로세스입니다. 이러한 프로세스는 웹 페이지 제공 (Apache, Nginx), 데이터베이스 관리 (MySQL, PostgreSQL) 또는 시스템 이벤트 처리와 같은 다양한 작업을 수행합니다. Systemd 는 "유닛 파일 (unit files)"이라고 하는 표준화된 구성 파일을 통해 이러한 데몬을 관리합니다.

기본 systemctl 명령어

시스템의 현재 상태를 이해하기 위해 몇 가지 기본 systemctl 명령어를 살펴보겠습니다.

  1. 터미널 아이콘을 클릭하여 터미널을 엽니다.

  2. 다음 명령을 사용하여 모든 활성 시스템 서비스를 나열합니다.

systemctl list-units --type=service

systemctl list-units --type=service

이 명령어는 현재 시스템에서 활성화된 모든 서비스를 표시합니다. 다음과 유사한 출력을 볼 수 있습니다.

UNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
accounts-daemon.service                   loaded active running Accounts Service
apparmor.service                          loaded active exited  AppArmor initialization
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
...

Ctrl+C 또는 Q를 눌러 명령을 종료합니다.

  1. 특정 서비스, 예를 들어 SSH 서비스의 상태를 확인합니다.
systemctl status ssh

systemctl status ssh

SSH 서비스에 대한 자세한 정보 (활성 여부, 프로세스 ID, 최근 로그 항목 포함) 를 볼 수 있습니다.

● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-06-13 12:34:56 UTC; 3h 25min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 1234 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 1235 (sshd)
      Tasks: 1 (limit: 4915)
     Memory: 5.6M
        CPU: 236ms
     CGroup: /system.slice/ssh.service
             └─1235 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
  1. systemd 서비스 파일이 저장되는 위치를 살펴보겠습니다. 다음 단계에서 작업할 파일입니다.
ls -l /etc/systemd/system/

이 디렉토리에는 systemd 가 서비스를 관리하는 방법을 정의하는 서비스 유닛 파일이 포함되어 있습니다. 여러 .service 파일과 심볼릭 링크를 볼 수 있습니다.

  1. 시스템에서 제공하는 유닛 파일은 다른 디렉토리에 있습니다. 이를 살펴보겠습니다.
ls -l /lib/systemd/system/

이 디렉토리에는 시스템과 함께 제공되는 기본 서비스 유닛 파일이 포함되어 있습니다.

이제 systemd 의 기본 사항과 서비스 상태를 확인하는 방법을 이해했으므로 다음 단계에서 서비스 파일을 생성하고 수정할 준비가 되었습니다.

간단한 Systemd 서비스 파일 생성

이 단계에서는 사용자 지정 스크립트를 실행하는 간단한 systemd 서비스 파일을 생성합니다. 이를 통해 서비스 파일이 어떻게 작동하는지, 그리고 이를 수정하는 방법을 이해할 수 있습니다.

간단한 스크립트 생성

먼저, 서비스가 실행할 간단한 스크립트를 생성해 보겠습니다.

  1. 스크립트용 디렉토리를 생성합니다.
mkdir -p ~/project/scripts
  1. nano 텍스트 편집기를 사용하여 간단한 스크립트를 생성합니다.
nano ~/project/scripts/hello-service.sh
  1. 스크립트에 다음 내용을 추가합니다.
#!/bin/bash

while true; do
  echo "Hello from custom service: $(date)" >> /tmp/hello-service.log
  sleep 10
done

편집기를 종료하려면 Ctrl+X를 누르고, 파일을 저장하려면 Y를 누른 다음, 파일 이름을 확인하려면 Enter를 누릅니다.

이 스크립트는 10 초마다 현재 날짜와 함께 메시지를 로그 파일에 기록합니다.

  1. 스크립트를 실행 가능하게 만듭니다.
chmod +x ~/project/scripts/hello-service.sh

systemd 서비스 유닛 파일 생성

이제 이 스크립트를 실행할 systemd 서비스 파일을 생성해 보겠습니다.

  1. sudo 권한을 사용하여 새 서비스 파일을 생성합니다.
sudo nano /etc/systemd/system/hello-service.service
  1. 서비스 파일에 다음 내용을 추가합니다.
[Unit]
Description=Hello Service Demo
After=network.target

[Service]
Type=simple
ExecStart=/home/labex/project/scripts/hello-service.sh
Restart=on-failure
User=labex

[Install]
WantedBy=multi-user.target

이 파일의 각 섹션을 이해해 보겠습니다.

  • [Unit]: 메타데이터 및 종속성을 포함합니다.

    • Description: 서비스에 대한 사람이 읽을 수 있는 설명
    • After: 이 서비스가 네트워크가 준비된 후에 시작되어야 함을 지정합니다.
  • [Service]: 서비스가 실행되는 방식을 정의합니다.

    • Type=simple: 서비스가 즉시 시작됩니다.
    • ExecStart: 실행할 명령 (스크립트)
    • Restart: 실패 시 서비스를 자동으로 다시 시작합니다.
    • User: 서비스를 실행할 사용자 계정
  • [Install]: 서비스가 활성화되어야 하는 시기와 방법을 정의합니다.

    • WantedBy: 서비스가 시작되어야 하는 시기를 지정합니다 (multi-user.target 은 정상적인 시스템 작동을 의미합니다).
  1. 파일을 저장하고 편집기를 종료합니다 (nano에서 Ctrl+X, Y, Enter를 누릅니다).

  2. 새로 생성된 서비스 파일을 살펴보겠습니다.

cat /etc/systemd/system/hello-service.service

방금 파일에 추가한 내용을 볼 수 있습니다.

cat /etc/systemd/system/hello-service.service

다음 단계에서는 systemctl daemon-reload 명령을 사용하여 이 서비스를 로드하고 시작하는 방법을 배우게 됩니다.

변경 사항 적용을 위한 systemctl daemon-reload 사용

systemd 서비스 파일을 생성했으므로, 이 새로운 서비스에 대해 systemd 에 알려야 합니다. 여기서 systemctl daemon-reload 명령이 사용됩니다.

systemctl daemon-reload 란 무엇인가?

systemctl daemon-reload 명령은 systemd 에 모든 서비스 파일을 다시 로드하고 내부 구성을 업데이트하도록 지시합니다. 이 작업은 다음과 같은 경우에 필요합니다.

  • 새 서비스 파일을 생성할 때
  • 기존 서비스 파일을 수정할 때
  • 서비스 파일을 삭제할 때

이 명령을 실행하지 않으면 systemd 는 변경 사항을 인식하지 못합니다.

systemd 구성 다시 로드

  1. systemd 구성을 다시 로드하려면 다음 명령을 실행합니다.
sudo systemctl daemon-reload

이 명령은 성공 시 아무런 출력을 생성하지 않지만, systemd 의 내부 구성을 업데이트합니다.

  1. 이제 systemd 가 새 서비스를 인식하는지 확인해 보겠습니다.
systemctl status hello-service

서비스가 로드되었지만 비활성 상태임을 보여주는 출력을 볼 수 있습니다.

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; disabled; vendor preset: enabled)
     Active: inactive (dead)

서비스 시작

  1. 서비스를 시작해 보겠습니다.
sudo systemctl start hello-service
  1. 다시 상태를 확인하여 실행 중인지 확인합니다.
systemctl status hello-service

systemctl status hello-service

이제 서비스가 활성 상태로 실행 중임을 볼 수 있습니다.

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; disabled; vendor preset: enabled)
     Active: active (running) since [timestamp]; [time] ago
   Main PID: [pid number] (hello-service.sh)
      Tasks: 2 (limit: 4915)
     Memory: 592.0K
        CPU: 5ms
     CGroup: /system.slice/hello-service.service
             └─[pid number] /bin/bash /home/labex/project/scripts/hello-service.sh
  1. 서비스가 실제로 작동하는지 확인하기 위해 생성된 로그 파일을 확인합니다.
cat /tmp/hello-service.log

다음과 유사한 여러 줄의 출력을 볼 수 있습니다.

Hello from custom service: Wed Jun 14 15:30:45 UTC 2023
Hello from custom service: Wed Jun 14 15:30:55 UTC 2023
Hello from custom service: Wed Jun 14 15:31:05 UTC 2023

로그 항목은 현재 날짜와 시간을 표시하여 서비스가 예상대로 스크립트를 실행하고 있음을 확인합니다.

  1. 부팅 시 자동으로 시작되도록 서비스를 활성화합니다.
sudo systemctl enable hello-service

다음과 유사한 출력을 볼 수 있습니다.

Created symlink /etc/systemd/system/multi-user.target.wants/hello-service.service → /etc/systemd/system/hello-service.service.

이는 서비스가 이제 활성화되어 시스템 부팅 시 자동으로 시작됨을 의미합니다.

이제 서비스를 성공적으로 생성하고, systemctl daemon-reload를 사용하여 systemd 에 알리고, 서비스를 시작했습니다. 다음 단계에서는 서비스를 수정하고 변경 사항을 적용합니다.

서비스 구성 수정

이 단계에서는 서비스 구성을 수정하고 systemctl daemon-reload를 사용하여 변경 사항을 적용합니다. 이는 서비스 구성을 업데이트할 때 이 명령의 중요성을 보여줍니다.

서비스 파일 수정

메시지를 로깅하는 빈도를 변경하기 위해 서비스를 수정해 보겠습니다.

  1. 서비스 파일을 편집합니다.
sudo nano /etc/systemd/system/hello-service.service
  1. [Service] 섹션에 새로운 환경 변수를 추가하여 sleep 간격을 제어합니다. User=labex 라인 뒤에 다음 라인을 추가합니다.
Environment="SLEEP_INTERVAL=5"
  1. 파일을 저장하고 종료합니다 (nano에서 Ctrl+X, Y, Enter를 누릅니다).

  2. 이제 이 환경 변수를 사용하도록 스크립트를 편집합니다.

nano ~/project/scripts/hello-service.sh
  1. 환경 변수를 사용하도록 스크립트를 수정합니다 (전체 내용을 다음으로 바꿉니다).
#!/bin/bash

## Default to 10 seconds if environment variable is not set
INTERVAL=${SLEEP_INTERVAL:-10}

while true; do
  echo "Hello from custom service: $(date) - Interval: ${INTERVAL}s" >> /tmp/hello-service.log
  sleep $INTERVAL
done
  1. 편집기를 저장하고 종료합니다 (nano에서 Ctrl+X, Y, Enter를 누릅니다).

변경 사항 적용

이제 서비스 파일과 스크립트 모두에 변경 사항을 적용했으므로, 이러한 변경 사항을 적용해야 합니다.

  1. 먼저 systemd 구성을 다시 로드합니다.
sudo systemctl daemon-reload
  1. 그런 다음 서비스를 다시 시작하여 변경 사항을 적용합니다.
sudo systemctl restart hello-service
  1. 서비스의 상태를 확인합니다.
systemctl status hello-service

업데이트된 구성으로 서비스가 실행 중임을 볼 수 있습니다.

  1. 로그 파일을 확인하여 변경 사항이 적용되었는지 확인합니다.
sleep 15 ## Wait to collect a few log entries
cat /tmp/hello-service.log | tail -5

이제 서비스가 10 초 대신 5 초마다 메시지를 로깅하고, 로그 항목에 새로운 간격 정보가 포함되어야 합니다.

Hello from custom service: Wed Jun 14 15:45:10 UTC 2023 - Interval: 5s
Hello from custom service: Wed Jun 14 15:45:15 UTC 2023 - Interval: 5s
Hello from custom service: Wed Jun 14 15:45:20 UTC 2023 - Interval: 5s

cat /tmp/hello-service.log | tail -5

무슨 일이 일어났는지 이해하기

방금 일어난 일을 이해해 보겠습니다.

  1. 환경 변수를 추가하기 위해 서비스 파일을 수정했습니다.
  2. 이 환경 변수를 사용하도록 스크립트를 업데이트했습니다.
  3. 서비스 파일에 대한 변경 사항을 systemd 에 알리기 위해 systemctl daemon-reload를 실행했습니다.
  4. 이러한 변경 사항을 적용하기 위해 서비스를 다시 시작했습니다.

systemctl daemon-reload 명령이 없으면 systemd 는 서비스 파일에 대한 변경 사항을 인식하지 못하고, 서비스를 다시 시작할 때 환경 변수가 스크립트로 전달되지 않습니다.

이는 서비스 파일을 수정할 때마다 systemctl daemon-reload가 필수적인 이유를 보여줍니다. 즉, 서비스를 시작하거나 다시 시작하기 전에 systemd 가 변경 사항을 인식하도록 보장합니다.

문제 해결 및 모범 사례

이 마지막 단계에서는 systemd 서비스 작업 시 발생할 수 있는 일반적인 문제와 이를 해결하는 방법을 배웁니다. 또한 systemctl daemon-reload 작업에 대한 몇 가지 모범 사례도 배웁니다.

일반적인 문제 해결

1. 서비스가 시작되지 않음

서비스가 시작되지 않으면 첫 번째 단계는 상태를 확인하는 것입니다.

systemctl status hello-service

이것은 종종 자세한 오류 정보를 제공합니다. 오류를 해결하는 방법을 보기 위해 의도적으로 오류를 생성해 보겠습니다.

  1. 서비스 파일을 편집합니다.
sudo nano /etc/systemd/system/hello-service.service
  1. ExecStart 라인을 존재하지 않는 스크립트를 가리키도록 변경합니다.
ExecStart=/home/labex/project/scripts/non-existent.sh
  1. 편집기를 저장하고 종료합니다.

  2. systemd 구성을 다시 로드하고 서비스를 다시 시작해 봅니다.

sudo systemctl daemon-reload
sudo systemctl restart hello-service
  1. 상태를 확인하여 오류를 확인합니다.
systemctl status hello-service

스크립트가 존재하지 않는다는 오류 메시지가 표시됩니다.

● hello-service.service - Hello Service Demo
     Loaded: loaded (/etc/systemd/system/hello-service.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since [timestamp]; [time] ago
    Process: [pid] ExecStart=/home/labex/project/scripts/non-existent.sh (code=exited, status=203/EXEC)
   Main PID: [pid] (code=exited, status=203/EXEC)
        CPU: 5ms

[timestamp] systemd[1]: Started Hello Service Demo.
[timestamp] systemd[pid]: hello-service.service: Failed to execute command: No such file or directory
[timestamp] systemd[pid]: hello-service.service: Failed at step EXEC spawning /home/labex/project/scripts/non-existent.sh: No such file or directory
[timestamp] systemd[1]: hello-service.service: Main process exited, code=exited, status=203/EXEC
[timestamp] systemd[1]: hello-service.service: Failed with result 'exit-code'.
  1. 서비스 파일을 수정하여 올바른 스크립트를 다시 가리키도록 합니다.
sudo nano /etc/systemd/system/hello-service.service
  1. ExecStart 라인을 다시 다음으로 변경합니다.
ExecStart=/home/labex/project/scripts/hello-service.sh
  1. 저장하고 종료한 다음, 다시 로드하고 다시 시작합니다.
sudo systemctl daemon-reload
sudo systemctl restart hello-service
  1. 서비스가 다시 실행 중인지 확인합니다.
systemctl status hello-service

2. 자세한 정보를 위해 journal 로그 읽기

문제 해결 시 journalctl을 사용하여 자세한 로그를 볼 수 있습니다.

sudo journalctl -u hello-service

이것은 hello-service unit 에 대한 모든 로그를 표시하며, 문제를 진단하는 데 매우 유용할 수 있습니다.

가장 최근 로그만 보려면:

sudo journalctl -u hello-service -n 20

실시간으로 로그를 따르려면 (tail -f와 유사):

sudo journalctl -u hello-service -f

로그 따라가기 모드를 종료하려면 Ctrl+C를 누릅니다.

systemctl daemon-reload 작업에 대한 모범 사례

systemd 및 daemon-reload 명령을 사용할 때 따라야 할 몇 가지 모범 사례는 다음과 같습니다.

  1. 항상 변경 후 다시 로드: systemd unit 파일을 수정, 추가 또는 제거한 후에는 항상 systemctl daemon-reload를 실행합니다.

  2. 적용하기 전에 구문 확인: 다시 로드하기 전에 다음 명령을 사용하여 서비스 파일의 구문 오류를 확인할 수 있습니다.

sudo systemd-analyze verify /etc/systemd/system/hello-service.service

오류가 없으면 이 명령은 출력을 생성하지 않습니다. 구문 오류가 있으면 보고됩니다.

  1. 서비스 템플릿 사용: 여러 인스턴스가 필요한 서비스의 경우 중복을 피하기 위해 서비스 템플릿 (예: service@.service로 명명된 파일) 을 사용합니다.

  2. 서비스 종속성 검토: 서비스가 올바른 순서로 시작되도록 After=Requires= 지시문을 올바르게 사용했는지 확인합니다.

  3. 적절하게 정리: 서비스를 제거할 때는 서비스 파일을 삭제하기 전에 서비스를 중지하고 비활성화해야 합니다.

sudo systemctl stop hello-service
sudo systemctl disable hello-service
sudo rm /etc/systemd/system/hello-service.service
sudo systemctl daemon-reload

이제 예제 서비스를 정리해 보겠습니다.

sudo systemctl stop hello-service
sudo systemctl disable hello-service

심볼릭 링크가 제거되었음을 나타내는 출력이 표시됩니다.

Removed /etc/systemd/system/multi-user.target.wants/hello-service.service.

확인을 위해 서비스 파일이 아직 필요하므로 아직 삭제하지 않겠습니다.

이제 systemd 서비스를 생성, 수정 및 문제 해결하는 방법과 이러한 서비스를 관리하는 데 있어 systemctl daemon-reload 명령의 중요성을 이해했습니다.

요약

이 랩에서는 Linux 시스템에서 systemctl daemon-reload 명령을 사용하여 시스템 데몬 및 서비스를 관리하는 방법을 배웠습니다. 다음을 수행했습니다.

  • systemd 및 systemctl 의 기본 사항 이해
  • 사용자 정의 systemd 서비스 파일 생성
  • systemctl daemon-reload 를 사용하여 서비스 구성에 변경 사항 적용
  • 서비스 파일 수정 및 해당 변경 사항 적용
  • 일반적인 문제 해결 방법 및 모범 사례 학습

systemctl daemon-reload 명령은 systemd 서비스를 사용할 때 필수적입니다. 이 명령은 systemd 관리자가 서비스 구성에 대한 변경 사항을 인식하도록 보장합니다. 이 명령이 없으면 서비스 파일에 대한 변경 사항은 다음 재부팅까지 시스템에서 인식되지 않습니다.

이 지식은 Linux 시스템으로 계속 작업하면서 서비스를 효과적으로 관리하고 구성 변경 사항이 제대로 적용되도록 하는 데 유용할 것입니다.