Skip to main content
Summary

서비스와 로그를 보면 시스템이 보입니다

지금까지는 명령어를 직접 실행해 파일을 만들고, 프로세스를 확인하고, 네트워크 연결을 점검했습니다. 이제는 한 단계 더 나아가야 합니다. 서버에서는 사용자가 터미널을 열고 있지 않아도 웹 서버, SSH 서버, 데이터베이스 같은 프로그램이 계속 돌아갑니다. 이런 프로그램을 보통 서비스라고 부릅니다.

서비스 관리는 가게 운영과 비슷합니다. 문을 열고 닫는 일은 start, stop입니다. 문제가 생겨 다시 여는 일은 restart입니다. 컴퓨터가 켜질 때 자동으로 문을 열게 하는 일은 enable입니다. 그리고 가게 안에서 무슨 일이 있었는지 남기는 장부가 로그입니다.

대부분의 현대 Linux 배포판은 systemd를 사용해 서비스를 관리합니다. Ubuntu, Debian, Fedora, RHEL, Arch Linux 모두 기본적으로 systemd 기반입니다. 단, 일부 컨테이너나 오래된 시스템, 특수 배포판에서는 systemd가 없을 수 있습니다. 먼저 확인하려면 다음 명령을 실행합니다.

ps -p 1 -o comm=

출력이 systemd라면 이 장의 명령을 그대로 사용할 수 있습니다.

서비스, 로그, 예약 작업 관리AI 생성 이미지

systemctl로 서비스 상태 확인하기

서비스를 다룰 때 가장 먼저 할 일은 실행이 아니라 확인입니다. 예를 들어 웹 서버인 nginx가 설치되어 있다면 다음처럼 상태를 봅니다.

systemctl status nginx

출력에서 특히 볼 부분은 네 가지입니다.

Loaded: loaded (...; enabled; ...)
Active: active (running)
Main PID: 1234 (nginx)

Loaded는 서비스 설정 파일을 systemd가 읽을 수 있는지 보여 줍니다. 여기서 enabled가 보이면 부팅할 때 자동 시작됩니다. disabled라면 자동 시작되지 않습니다.

Active는 현재 실행 상태입니다. active (running)이면 정상 실행 중입니다. inactive (dead)는 지금 꺼져 있다는 뜻입니다. failed는 시작했지만 실패했다는 뜻입니다.

Main PID는 이 서비스를 대표하는 프로세스 번호입니다. 프로세스와 작업 제어에서 배운 PID와 같은 개념입니다.

서비스 이름은 배포판마다 조금 다를 수 있습니다. SSH 서비스는 Ubuntu/Debian 계열에서 보통 ssh이고, Fedora/RHEL/Arch 계열에서는 보통 sshd입니다.

# Ubuntu/Debian 계열
systemctl status ssh

# Fedora/RHEL/Arch 계열
systemctl status sshd

서비스 이름이 헷갈릴 때는 목록에서 찾습니다.

systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service | grep ssh

첫 번째 명령은 현재 실행 중인 서비스 목록을 보여 줍니다. 두 번째 명령은 설치된 서비스 파일 중 이름에 ssh가 들어간 것을 찾습니다.

start, stop, restart, enable, disable

서비스 생명주기를 관리하는 기본 명령은 다음과 같습니다.

sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl enable nginx
sudo systemctl disable nginx

각 명령의 의미는 다릅니다.

  • start: 지금 서비스를 시작합니다.

  • stop: 지금 서비스를 중지합니다.

  • restart: 서비스를 중지한 뒤 다시 시작합니다.

  • enable: 다음 부팅부터 자동 시작되게 합니다.

  • disable: 다음 부팅부터 자동 시작되지 않게 합니다.

enable은 지금 당장 서비스를 시작하지 않습니다. 반대로 start는 다음 부팅 자동 시작 설정을 바꾸지 않습니다. 둘을 동시에 하고 싶다면 다음처럼 씁니다.

sudo systemctl enable --now nginx

자동 시작을 끄면서 지금도 멈추고 싶다면 다음처럼 합니다.

sudo systemctl disable --now nginx

원격 서버에서 ssh 또는 sshd 서비스를 멈추는 명령은 조심해야 합니다.

sudo systemctl stop ssh

SSH로 접속한 상태에서 SSH 서비스를 중지하면 새 접속이 막히거나 현재 연결이 끊길 수 있습니다. 원격 서버에서는 콘솔 접속 수단이 있는지 먼저 확인하고, 가능하면 restart 전에 설정 검사를 수행합니다.

서비스 설정을 바꾼 뒤에는 단순히 재시작하기보다 해당 프로그램의 설정 검사 명령을 먼저 찾는 습관이 좋습니다. 예를 들어 Nginx는 다음처럼 검사할 수 있습니다.

sudo nginx -t
sudo systemctl reload nginx

reload는 가능한 경우 서비스를 완전히 끊지 않고 설정만 다시 읽게 합니다. 모든 서비스가 reload를 지원하지는 않습니다. 지원 여부는 상태나 문서로 확인해야 합니다.

journalctl로 서비스 로그 읽기

서비스가 왜 실패했는지는 추측하지 말고 로그에서 확인합니다. systemd 환경에서는 journalctl이 핵심 도구입니다.

현재 부팅 이후의 전체 로그를 보려면 다음 명령을 사용합니다.

journalctl -b

특정 서비스의 로그만 보려면 -u 옵션을 씁니다.

journalctl -u nginx.service

최근 50줄만 보고 싶다면 다음처럼 합니다.

journalctl -u nginx.service -n 50

새 로그가 추가되는 모습을 실시간으로 보려면 -f를 붙입니다.

journalctl -u nginx.service -f

이 명령은 파일 내용 확인과 텍스트 편집에서 배운 tail -f와 비슷합니다. 새 로그가 들어올 때마다 화면에 이어서 출력됩니다. 중지하려면 Ctrl+C를 누릅니다.

오류만 빠르게 보고 싶을 때는 우선순위 필터를 사용합니다.

journalctl -p err -b

현재 부팅 이후 오류 수준 이상의 로그만 보여 줍니다. 특정 시간 이후 로그도 볼 수 있습니다.

journalctl --since "1 hour ago"
journalctl -u nginx.service --since "2026-05-23 09:00"

로그를 읽을 때는 맨 아래 한 줄만 보지 말고, 실패 직전의 흐름을 함께 봐야 합니다. 보통 원인은 마지막 오류 한 줄보다 그 앞의 경고나 설정 파일 경로에 숨어 있습니다.

로그가 너무 많으면 디스크 사용량도 확인할 수 있습니다.

journalctl --disk-usage

로그를 줄이는 명령도 있지만, 초보자는 무조건 삭제하기보다 먼저 어떤 서비스가 많은 로그를 만드는지 확인해야 합니다. 로그는 문제 해결의 증거이기 때문입니다.

dmesg로 커널과 하드웨어 메시지 확인하기

journalctl이 서비스와 시스템 로그를 보는 도구라면, dmesg는 커널이 남긴 메시지를 확인하는 도구입니다. 커널은 디스크, USB, 네트워크 카드, 메모리 같은 하드웨어와 가장 가까운 층에서 동작합니다.

예를 들어 USB 저장 장치를 꽂았는데 인식되지 않거나, 디스크 오류가 의심될 때 dmesg가 도움이 됩니다.

sudo dmesg -T | less

-T는 시간을 사람이 읽기 쉬운 형태로 보여 줍니다. 일부 시스템에서는 보안 설정 때문에 sudo 없이 dmesg를 읽을 수 없습니다.

특정 단어를 찾아볼 수도 있습니다.

sudo dmesg -T | grep -i error
sudo dmesg -T | grep -i usb
sudo dmesg -T | grep -i disk

systemd 환경에서는 커널 메시지를 journalctl로도 볼 수 있습니다.

journalctl -k -b

여기서 -k는 커널 메시지를 뜻하고, -b는 현재 부팅 이후를 뜻합니다. 하드웨어 문제를 볼 때는 일반 서비스 로그와 커널 로그를 함께 확인하면 원인을 좁히기 쉽습니다.

cron으로 반복 작업 예약하기

사람이 매번 같은 명령을 실행한다면 언젠가는 잊거나 실수합니다. 예약 작업은 정해진 시간에 명령을 자동 실행하는 기능입니다. 가장 오래되고 널리 쓰이는 방식이 cron입니다.

Ubuntu/Debian에서는 보통 cron 패키지와 cron 서비스가 사용됩니다. Fedora/RHEL/Arch 계열에서는 cronie 패키지와 crond 또는 cronie 서비스가 흔합니다.

설치가 필요하다면 배포판에 맞게 실행합니다.

# Ubuntu/Debian 계열
sudo apt update
sudo apt install cron
sudo systemctl enable --now cron

# Fedora/RHEL 계열
sudo dnf install cronie
sudo systemctl enable --now crond

# Arch 계열
sudo pacman -S cronie
sudo systemctl enable --now cronie

사용자별 예약 작업은 crontab -e로 편집합니다.

crontab -e

cron 시간 형식은 다섯 칸과 명령으로 이루어집니다.

분 시 일 월 요일 명령

예를 들어 10분마다 현재 시간을 파일에 남기려면 다음 줄을 추가합니다. 사용자명 부분은 실제 홈 디렉터리 경로에 맞게 바꿉니다.

*/10 * * * * date >> /home/사용자명/linux-practice/jobs/heartbeat.log 2>&1

실습 전에 디렉터리를 만듭니다.

mkdir -p ~/linux-practice/jobs

cron에서는 현재 터미널과 환경이 다릅니다. PATH가 짧고, 현재 디렉터리도 기대와 다를 수 있습니다. 그래서 예약 작업에는 가능한 한 절대 경로를 쓰는 것이 안전합니다. 출력도 반드시 파일로 남기는 편이 좋습니다.

0 3 * * * /usr/bin/tar -czf /home/사용자명/linux-practice/jobs/home-backup.tar.gz /home/사용자명/linux-practice >> /home/사용자명/linux-practice/jobs/backup.log 2>&1

이 예시는 매일 새벽 3시에 ~/linux-practice를 압축 백업하고 실행 결과를 로그에 남깁니다.

등록된 cron 작업은 다음으로 확인합니다.

crontab -l

crontab -r은 현재 사용자의 cron 목록을 통째로 삭제합니다. 실수 복구가 어렵기 때문에 초보자는 바로 사용하지 말고 crontab -e에서 필요한 줄만 지우는 편이 안전합니다.

systemd timer로 예약 작업 관리하기

cron은 단순하고 강력합니다. 하지만 서비스 의존성, 실행 로그, 실패 상태 확인까지 systemd와 함께 관리하고 싶다면 systemd timer를 사용할 수 있습니다.

개념은 두 파일로 나뉩니다.

  • .service: 실제 실행할 작업

  • .timer: 언제 실행할지 정하는 일정

사용자 권한으로 간단한 타이머를 만들어 보겠습니다.

mkdir -p ~/.config/systemd/user
mkdir -p ~/linux-practice/jobs
nano ~/linux-practice/jobs/daily-check.sh

파일 내용은 다음처럼 작성합니다.

#!/usr/bin/env bash
date >> "$HOME/linux-practice/jobs/systemd-timer.log"
df -h >> "$HOME/linux-practice/jobs/systemd-timer.log"
echo "---" >> "$HOME/linux-practice/jobs/systemd-timer.log"

실행 권한을 줍니다.

chmod +x ~/linux-practice/jobs/daily-check.sh

서비스 파일을 만듭니다.

nano ~/.config/systemd/user/daily-check.service

내용은 다음과 같습니다.

[Unit]
Description=Practice daily check job

[Service]
Type=oneshot
ExecStart=%h/linux-practice/jobs/daily-check.sh

타이머 파일을 만듭니다.

nano ~/.config/systemd/user/daily-check.timer

내용은 다음과 같습니다.

[Unit]
Description=Run practice daily check every 15 minutes

[Timer]
OnCalendar=*:0/15:00
Persistent=true

[Install]
WantedBy=timers.target

등록하고 시작합니다.

systemctl --user daemon-reload
systemctl --user enable --now daily-check.timer

타이머 목록은 다음으로 확인합니다.

systemctl --user list-timers

실행 로그는 다음처럼 봅니다.

journalctl --user -u daily-check.service -n 30

사용자 타이머는 로그인 세션과 관련이 있습니다. 서버에서 사용자가 로그아웃한 뒤에도 계속 실행되게 하려면 별도 설정이 필요할 수 있습니다. 운영 서버의 핵심 작업은 보통 /etc/systemd/system/ 아래에 시스템 단위 서비스와 타이머로 등록합니다. 처음에는 cron으로 시작하고, 서비스 상태와 로그까지 함께 관리해야 할 때 systemd timer로 넘어가면 됩니다.

서비스가 시작되지 않을 때 점검 순서

서비스 실패는 대부분 몇 가지 범주 안에 있습니다. 순서를 정해 보면 당황하지 않습니다.

첫째, 상태를 봅니다.

systemctl status nginx

Active, Loaded, 마지막 로그 줄을 확인합니다. 더 자세히 보려면 다음 명령을 사용합니다.

journalctl -u nginx.service -n 100 --no-pager

둘째, 설정 파일을 검사합니다. 서비스마다 검사 명령이 다릅니다.

sudo nginx -t
sudo sshd -t

명령이 없다면 로그에 나온 설정 파일 경로와 줄 번호를 확인합니다. 설정 파일을 수정했다면 파일 내용 확인과 텍스트 편집에서 배운 것처럼 백업본과 비교합니다.

셋째, 포트 충돌을 확인합니다. 웹 서버가 80번 포트를 열어야 하는데 이미 다른 프로세스가 쓰고 있으면 시작하지 못합니다.

sudo ss -ltnp | grep ':80'

넷째, 권한을 확인합니다. 서비스가 읽어야 할 파일을 읽지 못하거나, 로그 디렉터리에 쓰지 못하면 실패합니다.

ls -ld /var/log/nginx
ls -l /etc/nginx/nginx.conf

다섯째, 의존 서비스를 확인합니다. 데이터베이스, 네트워크, 마운트된 디스크가 준비되기 전에 서비스가 먼저 시작되면 실패할 수 있습니다.

systemctl list-dependencies nginx

문제를 고친 뒤에는 다시 시작하고 상태를 확인합니다.

sudo systemctl restart nginx
systemctl status nginx

실패 상태 표시가 남아 있을 때는 원인을 고친 뒤 다음 명령으로 실패 표시를 초기화할 수 있습니다.

sudo systemctl reset-failed nginx

이 명령은 문제를 해결하지 않습니다. systemd에 남아 있는 실패 표시만 지웁니다. 반드시 로그와 원인을 먼저 확인해야 합니다.

짧은 실습 과제

  1. 현재 실행 중인 서비스 5개를 확인합니다.

systemctl list-units --type=service --state=running | head
  1. SSH 서비스 상태를 확인합니다. 배포판에 맞는 이름을 사용합니다.

systemctl status ssh
systemctl status sshd
  1. 현재 부팅 이후 오류 로그를 확인합니다.

journalctl -p err -b
  1. 커널 메시지에서 디스크 관련 항목을 찾아봅니다.

sudo dmesg -T | grep -i disk
  1. cron 또는 systemd timer 중 하나를 골라 10분 또는 15분마다 현재 시간을 로그 파일에 남깁니다. 예약 후에는 로그 파일이 실제로 늘어나는지 확인합니다.

tail -f ~/linux-practice/jobs/heartbeat.log

실제 문제 해결 시나리오

상황을 가정해 보겠습니다. 웹 사이트가 열리지 않습니다. 브라우저에는 연결 실패가 나오고, 서버에는 SSH로 접속할 수 있습니다.

먼저 서비스 상태를 봅니다.

systemctl status nginx

failed라면 로그를 확인합니다.

journalctl -u nginx.service -n 100 --no-pager

로그에 설정 파일 오류가 나오면 설정 검사를 실행합니다.

sudo nginx -t

포트 사용 오류가 나오면 80번 포트를 누가 쓰는지 봅니다.

sudo ss -ltnp | grep ':80'

권한 오류가 나오면 로그에 표시된 파일이나 디렉터리의 소유자와 권한을 확인합니다.

ls -l /문제가/된/경로

수정 후에는 서비스를 재시작하고 다시 상태를 봅니다.

sudo systemctl restart nginx
systemctl status nginx

마지막으로 웹 응답을 직접 확인합니다.

curl -I http://localhost

이 흐름이 중요합니다. 서비스를 무작정 재시작하지 않습니다. 상태를 보고, 로그를 읽고, 원인을 좁힌 뒤, 필요한 부분만 고칩니다. 이 습관이 Linux를 단순히 사용하는 단계에서 안정적으로 운영하는 단계로 넘어가게 해 줍니다.

책 목록

처음부터 실전까지, 터미널이 두렵지 않은 Linux 활용법

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기