systemctl 마스터하기: Linux 서비스 관리를 위한 필수 명령어

systemd 환경에서 Linux 서비스 관리를 위한 필수 `systemctl` 명령어를 마스터하세요. 이 가이드는 서비스 시작, 중지, 재시작, 활성화, 비활성화를 위한 기본 구문과 함께 중요한 상태 확인 및 고급 문제 해결을 위한 `journalctl` 활용법을 자세히 설명합니다. 즉시 효율적이고 안정적인 시스템 관리를 달성하세요.

systemctl 마스터하기: Linux 서비스 관리를 위한 필수 명령어

Linux 서버를 운영한다면 systemctl을 끊임없이 사용하게 될 것입니다. Nginx가 시작되지 않을 때, PostgreSQL이 재부팅 후에 실행되어야 할 때, 배포 시 깔끔한 재시작이 필요할 때, 서비스가 "실패"했다고 표시되지만 실제 오류가 저널에 묻혀 있을 때 사용합니다.

이 명령어는 어렵지 않지만, 몇 가지 중요한 차이점이 있습니다: 시작은 활성화와 같지 않고, 리로드는 재시작과 같지 않으며, 비활성화는 마스킹과 같지 않습니다. 이것들이 명확해지면 서비스 관리는 훨씬 덜 신비로워집니다.


systemd와 systemctl 이해하기

systemd는 일반적인 Debian, Ubuntu, Fedora 및 RHEL 계열 배포판을 포함한 많은 주요 Linux 배포판에서 사용되는 init 시스템이자 서비스 관리자입니다. 사용자 공간을 초기화하고 프로세스, 세션, 타이머, 소켓, 마운트 및 서비스를 관리합니다.

systemctl은 systemd 관리자와 그 구성 요소(유닛)의 상태를 제어하고 검사하는 데 사용되는 기본 명령줄 유틸리티입니다. 백그라운드에서 실행되는 프로그램(데몬)인 서비스는 서비스 유닛(일반적으로 .service로 끝남)으로 관리됩니다.

주요 개념: 유닛과 타겟

이 문서는 서비스에 초점을 맞추지만, systemctl은 다양한 유닛을 관리한다는 점을 기억하세요:

  • 서비스 유닛 (.service): 백그라운드 프로세스 관리용 (예: nginx.service).
  • 타겟 유닛 (.target): 특정 시스템 상태를 나타내기 위해 유닛을 그룹화하는 용도 (예: 일반적인 서버 환경을 나타내는 multi-user.target).

서비스 제어를 위한 필수 명령어 (런타임 상태)

이 명령어들은 활성 시스템 세션에서 서비스가 현재 실행 중인지 중지되었는지를 직접 제어합니다.

1. 서비스 시작하기

start 명령어를 사용하여 부팅 구성과 관계없이 서비스를 즉시 실행합니다.

sudo systemctl start <service_name>.service
# 예: Apache 웹 서버 시작
sudo systemctl start apache2.service

2. 서비스 중지하기

stop 명령어를 사용하여 실행 중인 서비스를 정상적으로 종료합니다.

sudo systemctl stop <service_name>.service
# 예: MySQL 데이터베이스 서비스 중지
sudo systemctl stop mariadb.service

3. 서비스 재시작하기

이 명령어는 일반적으로 설정 파일 변경 후에 사용됩니다. 서비스를 중지한 후 즉시 다시 시작합니다.

sudo systemctl restart <service_name>.service
# 예: SSH 데몬 재시작
sudo systemctl restart sshd.service

4. 설정 리로드하기

많은 서비스는 리로드 작업을 지원하며, 기존 연결을 중단하거나 프로세스를 완전히 중지하지 않고 새 설정 파일을 적용합니다. 이는 전체 재시작보다 빠르고 덜 방해가 됩니다.

sudo systemctl reload <service_name>.service
# 예: Nginx 설정 리로드
sudo systemctl reload nginx.service

팁: 항상 서비스 문서를 확인하세요. 서비스가 reload를 지원하지 않는 경우 설정 변경 후 restart를 사용해야 합니다.


서비스 지속성을 위한 필수 명령어 (부트 상태)

서비스를 시작하면 지금 실행되지만, 활성화 또는 비활성화는 시스템 부팅 시 자동으로 시작될지 여부를 제어합니다.

1. 서비스 활성화하기

재부팅 후 서비스가 자동으로 시작되도록 하려면 활성화해야 합니다. 이는 systemd 설정 디렉토리(/etc/systemd/system/)에 필요한 심볼릭 링크를 생성합니다.

sudo systemctl enable <service_name>.service
# 예: PostgreSQL이 부팅 시 시작되도록 활성화
sudo systemctl enable postgresql.service

2. 서비스 비활성화하기

부팅 시 서비스가 자동으로 시작되지 않도록 하려면 비활성화해야 합니다. 이는 enable 명령어로 생성된 심볼릭 링크를 제거합니다.

sudo systemctl disable <service_name>.service
# 예: 서버에서 블루투스 서비스 비활성화
sudo systemctl disable bluetooth.service

3. 서비스 마스킹하기

유닛을 마스킹하면 수동, 자동 또는 종속성을 통해 시작되지 않도록 방지합니다. "이것을 시작하지 마십시오"가 disable보다 더 강력해야 할 때 사용하세요.

sudo systemctl mask <service_name>.service

# 마스킹 해제:
sudo systemctl unmask <service_name>.service

서비스 상태 및 정보 확인하기

서비스가 실행 중인지 알고 실패하는 이유를 아는 것은 문제 해결에 중요합니다.

1. 상태 확인하기

status 명령어는 서비스의 활성 상태, 로드 여부, 프로세스 ID 및 최근 로그 항목을 포함한 상세하고 즉각적인 스냅샷을 제공합니다.

systemctl status <service_name>.service
# 예: 방화벽 상태 확인
systemctl status firewalld.service

출력 해석:

출력에서 세 가지 주요 줄을 찾으세요:

  • Loaded: 유닛 파일이 올바르게 로드되었는지 표시 (예: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)).
  • Active: 현재 런타임 상태 표시 (예: active (running) 또는 failed).
  • CGroup: 서비스와 관련된 프로세스 트리 표시.

2. 부트 지속성 확인하기

전체 상태 출력을 확인하지 않고 서비스가 자동으로 시작되도록 설정되었는지 확인할 수 있습니다:

systemctl is-enabled <service_name>.service
# 출력은 'enabled', 'disabled' 또는 'masked'입니다.

3. journalctl로 로그 보기

status마지막 몇 줄의 출력을 보여주지만, 심층 디버깅을 위해서는 **journalctl**을 사용해야 합니다. 이 명령어는 모든 시스템 및 서비스 로그를 수집하는 systemd 저널을 쿼리합니다.

특정 서비스의 로그를 보려면:

# 마지막 재부팅 이후 서비스의 모든 로그 보기
journalctl -u <service_name>.service

# 실시간 로그 보기 (tail -f와 유사)
journalctl -u <service_name>.service -f

# 어제 이후 로그 보기
journalctl -u <service_name>.service --since "yesterday"

경고: 서비스가 failed 상태를 표시하면 journalctl -u <service> -r (역순, 최신 항목 먼저 표시)이 실패 원인이 된 오류 메시지를 보는 가장 빠른 방법인 경우가 많습니다.

4. 스크립트에서 서비스 실행 여부 확인하기

셸 스크립트의 경우 systemctl status는 너무 장황합니다. 쿼리 명령어를 사용하세요:

systemctl is-active --quiet nginx.service
echo $?

systemctl is-failed nginx.service
systemctl is-enabled nginx.service

is-active --quiet는 전체 상태 페이지를 출력하지 않고 유용한 종료 상태를 반환합니다. 따라서 상태 확인 및 자동화에 더 적합합니다.

if ! systemctl is-active --quiet nginx.service; then
    echo "nginx가 실행 중이 아닙니다" >&2
    exit 1
fi

5. 유닛 나열하기

정확한 서비스 이름을 모를 때 유닛을 나열하세요:

systemctl list-units --type=service
systemctl list-units --type=service --state=failed
systemctl list-unit-files --type=service

list-units는 로드된 유닛과 현재 런타임 상태를 보여줍니다. list-unit-files는 유닛 파일과 활성화, 비활성화, 정적, 마스킹 또는 생성되었는지 여부를 보여줍니다. 이 차이는 서비스가 디스크에 존재하지만 활성 유닛 목록에 나타나지 않는 이유를 설명합니다.


시스템 상태 관리 (타겟)

systemctl은 주로 타겟을 통해 전역 시스템 상태를 관리하는 데에도 사용됩니다.

1. 현재 시스템 상태 보기

시스템이 현재 어떤 타겟으로 부팅되었는지 확인하려면 (예: 서버 환경 또는 그래픽 데스크탑):

systemctl get-default

2. 기본 부트 타겟 변경하기

GUI를 실행해서는 안 되는 서버를 구성하는 경우 기본 타겟을 multi-user.target으로 설정할 수 있습니다:

sudo systemctl set-default multi-user.target

3. 재부팅 및 종료

rebootshutdown 명령어가 여전히 작동하지만, systemctl은 이러한 작업을 수행하는 기본 방법을 제공합니다:

# 시스템 즉시 재부팅
sudo systemctl reboot

# 시스템 종료 (전원 끄기)
sudo systemctl poweroff

유닛 변경 후 systemd 리로드하기

유닛 파일을 편집하거나 /etc/systemd/system 아래에 드롭인을 추가할 때 systemd는 자동으로 다시 읽지 않습니다. 다음을 실행하세요:

sudo systemctl daemon-reload

그런 다음 영향을 받는 서비스를 재시작하거나 리로드하세요:

sudo systemctl restart myapp.service

벤더 파일과 드롭인이 병합된 후 최종 유닛을 검사하려면:

systemctl cat myapp.service
systemctl show myapp.service -p FragmentPath -p DropInPaths

이것은 "잘못된 파일을 편집했다"는 문제를 찾는 가장 빠른 방법 중 하나입니다.

실제 문제 해결 흐름

서비스 시작에 실패하면 다음 순서로 작업하세요:

  1. 상태 확인:
systemctl status myapp.service
  1. 해당 유닛의 로그 읽기:
journalctl -u myapp.service -r
  1. 최근에 서비스 파일을 편집했다면 systemd 리로드:
sudo systemctl daemon-reload
  1. 다시 시작하고 실시간 로그 확인:
sudo systemctl restart myapp.service
journalctl -u myapp.service -f
  1. 즉시 실패하면 유닛 정의 확인:
systemctl cat myapp.service
systemctl show myapp.service -p ExecStart -p User -p WorkingDirectory

대부분의 실패는 평범합니다: ExecStart의 잘못된 경로, 누락된 환경 파일, 권한 문제, 잘못된 작업 디렉토리, 이미 사용 중인 포트 또는 애플리케이션 자체의 설정 구문 오류입니다.

시작, 활성화, 재시작, 리로드: 정신적 모델

이 네 가지 동사는 혼동하기 쉽습니다:

  • start는 현재 런타임 상태를 변경합니다.
  • enable은 부트 동작을 변경합니다.
  • restart는 프로세스를 중지하고 시작합니다.
  • reload는 서비스가 지원하는 경우 기존 프로세스에 설정을 다시 읽도록 요청합니다.

예를 들어, Nginx 설치 후:

sudo systemctl start nginx.service
sudo systemctl enable nginx.service

첫 번째 명령어는 지금 시작합니다. 두 번째 명령어는 재부팅 후 시작되도록 합니다. start만 실행하면 서비스가 다음 재부팅 후 사라질 수 있습니다. enable만 실행하면 유닛에 특별한 설치 동작이 없는 한 다음 재부팅까지 실행되지 않을 수 있습니다.

Nginx 설정을 편집한 후 먼저 애플리케이션 설정을 테스트한 다음 리로드하세요:

sudo nginx -t
sudo systemctl reload nginx.service

애플리케이션이 리로드를 지원하지 않으면 재시작을 사용하고 중단을 계획하세요:

sudo systemctl restart myapp.service

마스킹의 안전한 사용

마스킹은 유용하지만, 다음에 서비스를 시작하려는 사람을 혼란스럽게 할 수 있습니다.

sudo systemctl mask bluetooth.service
systemctl is-enabled bluetooth.service

서비스는 masked를 보고합니다. 해제하려면:

sudo systemctl unmask bluetooth.service

명확한 충돌, 예를 들어 이전 서비스를 새 서비스로 교체한 후 시작되지 않도록 방지하는 데 마스킹을 사용하세요. 일반적인 "부팅 시 시작하지 않음" 동작에는 disable을 사용하세요.

유지 관리 가능한 방식으로 유닛 편집하기

패키지된 서비스를 변경해야 할 때 /usr/lib/systemd/system 또는 /lib/systemd/system 아래의 파일을 직접 편집하지 마세요. 패키지 업그레이드가 해당 파일을 대체할 수 있습니다. 오버라이드를 사용하세요:

sudo systemctl edit myapp.service

그러면 /etc/systemd/system/myapp.service.d/ 아래에 드롭인이 생성됩니다. 예를 들어:

[Service]
Environment=APP_ENV=production
Restart=on-failure
RestartSec=5s

그런 다음 적용하세요:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service

나중에 오버라이드를 제거해야 하는 경우 먼저 드롭인을 검사하세요:

systemctl show myapp.service -p DropInPaths

그런 다음 특정 드롭인 파일을 제거하고 daemon-reload를 실행하세요. 이렇게 하면 로컬 변경 사항을 확인하고 감사하기 쉽게 유지할 수 있습니다.

사용자 서비스

모든 서비스가 시스템 서비스는 아닙니다. 데스크탑 도구, 개발 데몬 및 사용자별 백그라운드 프로세스는 사용자 관리자 아래에서 실행될 수 있습니다:

systemctl --user status pipewire.service
systemctl --user restart my-user-job.service

사용자 서비스는 동일한 방식으로 sudo를 사용하지 않으며 사용자의 systemd 인스턴스 아래에 있습니다. 명령어가 systemctl --user에서는 작동하지만 일반 systemctl에서는 작동하지 않는다면 시스템 유닛이 아닌 사용자 유닛을 보고 있는 것입니다.

서버에서 장기 실행 사용자 서비스의 경우 로그인/세션 동작이 중요할 수 있습니다. 일부 배포판에서는 로그아웃 후에도 사용자 서비스를 계속 실행하려면 lingering이 필요합니다:

loginctl enable-linger deploy

의도적으로 사용하세요. 사용자 서비스는 개발 또는 사용자 범위 자동화에 적합한 도구일 수 있지만, 프로덕션 데몬은 명시적인 사용자 및 권한이 있는 시스템 서비스로서 더 명확한 경우가 많습니다.

필수 systemctl 명령어 요약

작업 명령어 구문 목적
지금 시작 sudo systemctl start name.service 서비스를 즉시 실행합니다.
지금 중지 sudo systemctl stop name.service 실행 중인 서비스를 종료합니다.
재시작 sudo systemctl restart name.service 서비스를 중지했다가 시작합니다.
리로드 sudo systemctl reload name.service 지원되는 경우 전체 재시작 없이 설정 변경 사항을 적용합니다.
활성화 sudo systemctl enable name.service 부팅 시 서비스가 시작되도록 설정합니다.
비활성화 sudo systemctl disable name.service 부팅 시 서비스가 시작되지 않도록 방지합니다.
상태 systemctl status name.service 런타임 상태 및 최근 로그를 확인합니다.
로그 보기 journalctl -u name.service 서비스에 대한 전체 systemd 저널 기록에 액세스합니다.

이 명령어들은 대부분의 일상적인 서비스 작업을 다룹니다. start와 stop은 현재 프로세스를 제어합니다. enable과 disable은 부트 동작을 제어합니다. status, is-activejournalctl은 무슨 일이 일어났는지 알려줍니다. daemon-reload는 systemd를 유닛 파일 편집과 동기화 상태로 유지합니다. 이러한 역할을 분리하면 systemctl은 오래된 노트에서 복사하는 명령어가 아니라 실용적인 문제 해결 도구가 됩니다.