Linux 프로세스와 서비스 관리 완벽 이해: ps, top, kill, systemctl, systemd, journalctl 실무 활용법
Linux 서버를 운영하다 보면 특정 프로그램이 정상적으로 실행되고 있는지 확인하거나, CPU와 메모리를 과도하게 사용하는 프로세스를 찾아야 하는 상황이 자주 발생합니다.
웹 서버가 응답하지 않거나 데이터베이스가 갑자기 중단되었을 때도 가장 먼저 확인해야 하는 것이 프로세스와 서비스의 상태입니다.
예를 들어 Nginx가 실행되고 있는지 확인하고, PostgreSQL 프로세스가 정상적으로 동작하는지 확인하며, CPU 사용률이 높은 프로세스의 원인을 분석해야 합니다.
이러한 작업을 수행하기 위해 Linux에서는 ps, top, htop, kill, systemctl, systemd, journalctl 등의 명령어를 제공합니다.
이번 글에서는 Linux 프로세스의 기본 개념부터 프로세스 상태 확인, 종료, 서비스 관리, systemd와 journalctl을 이용한 장애 분석까지 시스템 엔지니어가 실무에서 자주 사용하는 내용을 단계별로 알아보겠습니다.
프로세스(Process)는 실행 중인 프로그램을 의미합니다.
예를 들어 디스크에 저장된 nginx라는 프로그램 자체는 실행 파일이지만, 실제로 실행되면 Linux 커널은 이를 하나의 프로세스로 관리합니다.
다음과 같은 프로그램이 실행되면 각각 프로세스가 생성될 수 있습니다.
Nginx
PostgreSQL
Redis
Python
Java
SSH
Docker
프로세스에는 여러 가지 정보가 연결됩니다.
대표적으로 다음과 같습니다.
PID
PPID
실행 사용자
CPU 사용량
메모리 사용량
프로세스 상태
실행 프로그램
이러한 정보를 이용하면 서버에서 현재 어떤 프로그램이 실행되고 있는지 확인할 수 있습니다.
Linux에서 실행 중인 프로세스는 PID(Process ID)라는 고유한 번호를 부여받습니다.
현재 실행 중인 프로세스를 확인하려면 다음 명령어를 사용할 수 있습니다.
ps
더 많은 정보를 확인하려면 다음과 같이 사용합니다.
ps -ef
예를 들어 다음과 같은 결과를 볼 수 있습니다.
root 1024 1 0 07:00 ? 00:00:02 nginx
admin 2048 1980 0 07:01 pts/0 00:00:00 bash
여기서 중요한 항목은 다음과 같습니다.
UID : 프로세스를 실행한 사용자
PID : 현재 프로세스 ID
PPID : 부모 프로세스 ID
CMD : 실행된 프로그램
PID는 프로세스를 관리할 때 매우 중요한 식별자입니다.
Linux에서는 프로세스가 다른 프로세스를 생성할 수 있습니다.
이때 프로세스를 생성한 프로세스를 부모 프로세스(Parent Process), 새롭게 생성된 프로세스를 자식 프로세스(Child Process)라고 합니다.
ps -ef를 사용하면 PPID를 확인할 수 있습니다.
ps -ef
예를 들어 다음과 같은 구조가 있을 수 있습니다.
systemd
├── sshd
│ └── bash
├── nginx
└── cron
Linux 시스템에서는 프로세스 간의 부모·자식 관계를 이해하는 것이 장애 분석에 도움이 됩니다.
서버에서 실행 중인 모든 프로세스를 확인할 때 가장 기본적으로 사용하는 명령어가 ps입니다.
ps -ef
또는
ps aux
특정 프로그램을 찾을 때는 grep과 함께 사용할 수 있습니다.
ps -ef | grep nginx
예를 들어 Nginx가 실행되고 있는지 빠르게 확인할 수 있습니다.
다만 grep nginx 명령 자체도 검색 결과에 표시될 수 있으므로 실제 운영 환경에서는 pgrep을 활용하는 것도 좋습니다.
pgrep -a nginx
현재 시스템의 실시간 상태를 확인할 때 가장 많이 사용하는 명령어 중 하나가 top입니다.
top
실행하면 CPU, 메모리, Load Average와 함께 프로세스별 사용량을 확인할 수 있습니다.
예를 들어 다음과 같은 정보를 볼 수 있습니다.
load average
CPU usage
Memory usage
PID
USER
%CPU
%MEM
COMMAND
특정 프로세스가 CPU를 과도하게 사용하는지 확인할 때 매우 유용합니다.
서버가 갑자기 느려졌다면 가장 먼저 top을 실행해 보는 것이 좋습니다.
top
CPU 사용률이 매우 높다면 어떤 프로세스가 CPU를 사용하는지 확인합니다.
예를 들어 다음과 같은 상황을 가정해 볼 수 있습니다.
PID %CPU COMMAND
1234 98.5 python
2456 2.1 nginx
이 경우 Python 프로세스가 CPU를 집중적으로 사용하고 있다는 것을 알 수 있습니다.
다음 단계에서는 해당 프로세스가 무엇을 수행하고 있는지 로그와 애플리케이션 상태를 함께 확인해야 합니다.
htop은 top보다 사용하기 편리한 대화형 프로세스 모니터링 도구입니다.
htop
환경에 따라 설치가 필요할 수 있습니다.
Rocky Linux 계열에서는 시스템에 활성화된 저장소에 따라 다음과 같이 설치할 수 있습니다.
sudo dnf install htop
htop에서는 CPU별 사용량과 메모리 상태를 보다 직관적으로 확인할 수 있으며 프로세스를 선택하여 종료하는 등의 작업도 수행할 수 있습니다.
다만 운영 서버에서는 패키지 설치 정책을 확인한 후 사용하는 것이 좋습니다.
문제가 있는 프로세스를 종료해야 할 경우 kill 명령어를 사용할 수 있습니다.
먼저 PID를 확인합니다.
ps -ef | grep application
예를 들어 PID가 1234라면 다음과 같이 종료 요청을 보낼 수 있습니다.
kill 1234
기본적으로 kill은 SIGTERM 신호를 전달합니다.
프로세스에게 정상적으로 종료할 기회를 주는 방식입니다.
프로세스가 정상적으로 종료되지 않는 경우 강제 종료를 사용할 수 있습니다.
kill -9 1234
-9는 SIGKILL을 의미합니다.
SIGKILL은 프로세스가 종료 요청을 처리할 기회를 주지 않고 커널이 강제로 종료시키는 신호입니다.
따라서 운영 서버에서는 처음부터 kill -9를 사용하는 것보다 다음 순서를 권장합니다.
kill 1234
잠시 기다린 후 상태를 확인합니다.
ps -p 1234
그래도 종료되지 않는 경우에만 강제 종료를 고려합니다.
중요한 개념이 있습니다.
프로세스를 직접 kill하는 것과 서비스를 systemctl stop하는 것은 같은 작업이 아닙니다.
예를 들어 Nginx 서비스를 관리한다면 다음과 같이 사용하는 것이 일반적입니다.
sudo systemctl stop nginx
반면 Nginx의 PID를 찾아 직접 종료할 수도 있습니다.
kill PID
서비스 관리가 필요한 프로그램은 일반적으로 systemctl을 이용하는 것이 더 적절합니다.
왜냐하면 systemd가 해당 서비스의 실행 상태와 재시작 정책 등을 관리하기 때문입니다.
현재 대부분의 주요 Linux 배포판에서는 systemd가 시스템과 서비스 관리의 핵심 역할을 담당합니다.
Rocky Linux, RHEL 계열, Ubuntu 등에서도 systemd를 기반으로 서비스를 관리합니다.
systemd는 다음과 같은 역할을 수행합니다.
서비스 시작
서비스 중지
서비스 재시작
부팅 시 서비스 시작
서비스 상태 관리
서비스 간 의존성 관리
로그 관리 연계
프로세스 관리
systemd가 관리하는 서비스 단위를 일반적으로 unit이라고 부릅니다.
그중 서버 운영에서 가장 많이 접하는 것이 service unit입니다.
서비스 상태를 확인합니다.
sudo systemctl status nginx
서비스를 시작합니다.
sudo systemctl start nginx
서비스를 중지합니다.
sudo systemctl stop nginx
서비스를 재시작합니다.
sudo systemctl restart nginx
설정을 변경한 후 서비스를 다시 읽게 해야 하는 경우에는 reload를 사용할 수도 있습니다.
sudo systemctl reload nginx
단, reload 지원 여부와 동작 방식은 서비스마다 다릅니다.
서버가 재부팅된 후에도 특정 서비스가 자동으로 실행되어야 하는 경우가 많습니다.
예를 들어 Nginx를 부팅 시 자동으로 시작하도록 설정하려면 다음과 같이 합니다.
sudo systemctl enable nginx
현재 활성화 여부는 다음과 같이 확인할 수 있습니다.
systemctl is-enabled nginx
반대로 자동 시작을 해제하려면
sudo systemctl disable nginx
를 사용합니다.
여기서 enable과 start를 혼동하지 않는 것이 중요합니다.
start는 현재 서비스를 시작하는 것이고 enable은 부팅 시 자동으로 시작하도록 설정하는 것입니다.
둘은 서로 다른 기능입니다.
현재 시스템에 등록된 서비스 목록을 확인할 수 있습니다.
systemctl list-units --type=service
실행 중인 서비스만 확인하려면
systemctl list-units --type=service --state=running
부팅 과정에서 실패한 서비스가 있는지 확인하려면
systemctl --failed
이 명령은 장애 대응에서 매우 유용합니다.
서버가 부팅된 후 특정 서비스가 실행되지 않는다면 먼저 다음 명령어를 실행하는 습관을 들이는 것이 좋습니다.
systemctl --failed
예를 들어 Nginx가 실행되지 않는다고 가정해 보겠습니다.
첫 번째로 상태를 확인합니다.
sudo systemctl status nginx
두 번째로 로그를 확인합니다.
sudo journalctl -u nginx
세 번째로 최근 로그만 확인합니다.
sudo journalctl -u nginx -n 50
네 번째로 설정 파일 오류를 확인합니다.
sudo nginx -t
설정에 문제가 없다면 서비스를 다시 시작합니다.
sudo systemctl restart nginx
마지막으로 상태를 다시 확인합니다.
sudo systemctl status nginx
이러한 순서로 접근하면 무작정 서비스를 반복해서 재시작하는 것보다 장애 원인을 정확하게 찾을 수 있습니다.
journalctl은 systemd의 저널 로그를 조회하는 명령어입니다.
Linux 시스템에서 서비스가 왜 시작되지 않았는지 확인할 때 매우 중요한 도구입니다.
전체 로그를 확인하려면
journalctl
특정 서비스의 로그만 확인하려면
journalctl -u nginx
최근 로그만 확인하려면
journalctl -u nginx -n 100
실시간으로 로그를 확인하려면
journalctl -u nginx -f
를 사용할 수 있습니다.
-f는 로그가 추가되는 것을 실시간으로 확인할 수 있어 서비스 장애를 재현하면서 원인을 추적할 때 유용합니다.
서버 부팅 과정에서 발생한 문제를 확인할 때는 다음 명령어가 유용합니다.
journalctl -b
현재 부팅에서 발생한 로그를 확인할 수 있습니다.
이전 부팅의 로그를 확인하려면 시스템의 journal 보존 설정과 환경에 따라 다음과 같은 방식으로 확인할 수 있습니다.
journalctl --list-boots
특정 부팅 로그를 조회할 때는 부팅 ID를 기준으로 확인할 수 있습니다.
journalctl -b -1
이 기능은 서버가 재부팅된 직후 “재부팅 전에 무슨 문제가 있었는가?“를 분석하는 데 특히 유용합니다.
모든 로그가 journal에만 저장되는 것은 아닙니다.
애플리케이션이나 웹 서버는 자체 로그 파일을 생성할 수 있습니다.
예를 들어 Nginx에서는 일반적으로 다음과 같은 로그를 사용합니다.
/var/log/nginx/access.log
/var/log/nginx/error.log
실시간으로 로그를 확인하려면
tail -f /var/log/nginx/error.log
특정 오류를 검색하려면
grep "error" /var/log/nginx/error.log
와 같이 사용할 수 있습니다.
즉 서버 장애를 분석할 때는 systemd 로그와 애플리케이션 로그를 함께 확인해야 합니다.
Linux에서는 프로세스의 계층 구조를 확인하는 것도 중요합니다.
다음 명령어를 사용할 수 있습니다.
pstree
특정 프로세스의 관계를 확인하려면
pstree -p
예를 들어 다음과 같은 구조가 나타날 수 있습니다.
systemd
├─sshd
│ └─bash
├─nginx
│ ├─nginx
│ └─nginx
└─postgres
이러한 구조를 이해하면 특정 프로세스가 어떤 부모 프로세스에 의해 실행되었는지 확인할 수 있습니다.
Linux 프로세스는 여러 상태를 가질 수 있습니다.
대표적으로 다음과 같습니다.
R = Running
S = Sleeping
D = Uninterruptible Sleep
T = Stopped
Z = Zombie
특히 시스템 엔지니어가 알아야 할 상태가 D와 Z입니다.
D 상태는 일반적으로 디스크나 네트워크 파일 시스템 등의 I/O 작업을 기다리는 상황에서 나타날 수 있습니다.
이 상태의 프로세스가 많다면 저장장치나 I/O 경로에 문제가 있는지 확인해야 합니다.
Z는 Zombie 프로세스입니다.
자식 프로세스가 종료되었지만 부모 프로세스가 종료 상태를 제대로 수거하지 않은 경우 발생할 수 있습니다.
Zombie 프로세스가 지속적으로 증가한다면 해당 애플리케이션의 프로세스 관리 구조를 점검해야 합니다.
먼저 다음 명령어를 실행합니다.
top
CPU를 많이 사용하는 PID를 확인합니다.
ps -p PID -o pid,ppid,user,%cpu,%mem,cmd
그다음 해당 프로세스의 애플리케이션 로그와 systemd 로그를 확인합니다.
journalctl -u 서비스명
단순히 프로세스를 종료하는 것이 아니라 왜 CPU를 많이 사용하는지 원인을 찾는 것이 중요합니다.
free -h
그리고
top
을 이용하여 메모리를 많이 사용하는 프로세스를 찾습니다.
프로세스별 메모리 사용량은 다음과 같이 확인할 수 있습니다.
ps aux --sort=-%mem | head
Swap 사용량도 함께 확인해야 합니다.
free -h
메모리 부족이 지속된다면 애플리케이션 메모리 누수, 프로세스 증가, 캐시, Swap 사용량 등을 종합적으로 분석해야 합니다.
서비스가 실행 중이었다가 갑자기 종료된다면 다음을 확인합니다.
sudo systemctl status 서비스명
그리고
sudo journalctl -u 서비스명 -n 100
OOM(Out Of Memory) 여부도 확인해야 합니다.
journalctl -k | grep -i "out of memory"
또는
dmesg | grep -i -E "oom|killed process"
환경과 권한에 따라 dmesg 접근이 제한될 수 있습니다.
서비스가 종료된 원인이 메모리 부족인지, 설정 오류인지, 애플리케이션 자체 오류인지 구분하는 것이 핵심입니다.
Linux 서버 운영에서 다음 명령어는 반드시 익혀두는 것이 좋습니다.
프로세스 확인:
ps -ef
실시간 모니터링:
top
프로세스 검색:
pgrep -a nginx
프로세스 종료:
kill PID
강제 종료:
kill -9 PID
서비스 상태:
systemctl status nginx
서비스 시작:
systemctl start nginx
서비스 중지:
systemctl stop nginx
서비스 재시작:
systemctl restart nginx
부팅 자동 시작:
systemctl enable nginx
실패한 서비스 확인:
systemctl --failed
서비스 로그:
journalctl -u nginx
실시간 서비스 로그:
journalctl -u nginx -f
프로세스와 서비스 장애를 해결할 때 가장 중요한 것은 “일단 재시작”하는 습관을 버리는 것입니다.
예를 들어 웹 서버가 응답하지 않는다고 해서 바로
systemctl restart nginx
를 실행하는 것보다 다음과 같은 순서로 접근하는 것이 좋습니다.
1. 서비스 상태 확인
2. 프로세스 상태 확인
3. CPU 확인
4. 메모리 확인
5. 디스크 및 I/O 확인
6. 서비스 로그 확인
7. 애플리케이션 로그 확인
8. 설정 파일 확인
9. 네트워크 상태 확인
10. 필요한 조치 수행
11. 서비스 상태 재확인
이러한 과정을 거쳐야 장애의 원인을 정확하게 파악할 수 있습니다.
단순히 서비스를 재시작하면 일시적으로 문제가 해결되는 것처럼 보일 수 있지만, 근본 원인이 남아 있다면 같은 장애가 다시 발생할 수 있습니다.
Linux에서 프로세스와 서비스 관리는 시스템 엔지니어에게 반드시 필요한 핵심 기술입니다.
ps를 사용하면 현재 실행 중인 프로세스와 PID를 확인할 수 있고, top과 htop을 이용하면 CPU와 메모리 사용량을 실시간으로 분석할 수 있습니다.
프로세스를 종료해야 할 때는 kill을 사용하며, 정상적인 종료를 먼저 시도한 후 필요한 경우에만 kill -9를 사용해야 합니다.
서비스 관리에서는 systemctl과 systemd의 관계를 이해하는 것이 중요합니다.
systemctl status
systemctl start
systemctl stop
systemctl restart
systemctl enable
등의 명령어를 이용하면 서버에서 실행되는 서비스를 체계적으로 관리할 수 있습니다.
또한 장애가 발생했을 때 journalctl은 매우 중요한 분석 도구입니다.
journalctl -u 서비스명
을 이용하면 특정 서비스에서 발생한 오류를 확인할 수 있으며,
journalctl -b
를 사용하면 현재 부팅 과정에서 발생한 시스템 로그를 확인할 수 있습니다.
결국 Linux 서버 운영에서 중요한 것은 명령어를 많이 외우는 것이 아니라 현재 서버에서 어떤 프로세스가 실행되고 있고, 어떤 서비스가 그 프로세스를 관리하며, 문제가 발생했을 때 로그를 통해 원인을 어떻게 추적할 것인지 이해하는 것입니다.