infra
Platform

모듈 맵

[Infra Ops] 프로세스(ps), 포트(netstat), 리소스(top) 모니터링 실무

0 / 52 완료

펼치기
0 / 52 완료0%

Infra-ops · 04 / 52

[Infra Ops] 프로세스(ps), 포트(netstat), 리소스(top) 모니터링 실무

서버 상태를 빠르게 파악하는 ps, top, ss, lsof, df, du, free, journalctl 명령어를 실무 장애 대응 관점에서 익힙니다

🚨INCIDENT ALERT
HIGH

오전 9시, 모니터링 알림이 울립니다. "WAS 응답 없음." SSH로 접속해서 무엇부터 확인해야 할까요? 프로세스는 살아있는지, 어느 포트에서 대기 중인지, CPU와 메모리는 어떤지, 디스크는 꽉 차지 않았는지 — 5분 안에 서버 상태를 파악하는 것이 첫 번째 과제입니다.

이 모듈의 명령어들이 장애 대응 첫 5분의 전부입니다.

이번 챕터에서 배울 것
  • 1ps aux와 top으로 프로세스 목록과 CPU/메모리 사용량을 해석할 수 있다
  • 2ss -tlnp로 리스닝 포트와 연결된 프로세스를 확인할 수 있다
  • 3df -h로 디스크 사용량을 확인하고 df -i로 inode 소진 여부를 파악할 수 있다
  • 4free -m으로 메모리/스왑 상태를 해석할 수 있다
  • 5journalctl로 서비스 로그를 시간 기준으로 조회할 수 있다
실습 환경 준비
점검 명령어 사전 확인
which ps top htop ss lsof df du free journalctl
htop 설치 (없는 경우)
sudo apt-get install -y htop 2>/dev/null || sudo dnf install -y htop 2>/dev/null; echo done
lsof 설치 확인
which lsof || sudo apt-get install -y lsof 2>/dev/null || sudo dnf install -y lsof 2>/dev/null

프로세스 점검

💡개념

ps로 프로세스 확인

서버에서 갑자기 CPU가 치솟거나 메모리가 부족해질 때, 어느 프로세스가 문제인지 가장 먼저 파악해야 합니다. ps 명령어를 모르면 top 출력만 바라보다 시간을 낭비하게 됩니다. 실무에서는 ps auxps -ef를 상황에 맞게 구분해서 쓰는 것이 첫 번째 진단 루틴입니다.

장애 대응 첫 5분 — 서버 상태 점검 루틴

장애 알림을 받고 서버에 접속했는데 "뭘 먼저 확인해야 할지" 몰라서 5분을 허비했다면, 원인은 점검 루틴이 없어서입니다. Tomcat 프로세스가 살아있는지, CPU를 독점하는 프로세스가 있는지 — ps를 제대로 읽지 못하면 가장 기본적인 판단도 내릴 수 없습니다. 프로세스 상태를 30초 안에 파악하는 것이 장애 대응 속도의 출발점입니다.

로컬 터미널
# 전체 프로세스 목록 (자주 쓰는 형식)
ps aux
# USER    PID  %CPU %MEM    VSZ   RSS TTY  STAT START  TIME COMMAND
# tomcat  1234  2.5  8.3 3145728 340000 ?  Sl  09:00  2:15 java -Xmx2g ...
# nginx   5678  0.0  0.1   12345   4096 ?  Ss  09:00  0:00 nginx: master

# ps -ef 형식 (PPID 포함, 프로세스 계층 파악에 유용)
ps -ef | grep tomcat

# 특정 프로세스만 필터링
ps aux | grep nginx | grep -v grep

# 프로세스 이름으로 PID만 추출
pgrep -f tomcat
# 또는
pidof nginx

ps aux 컬럼 해석:

컬럼의미주목할 상황
%CPUCPU 사용률지속적으로 100%+ → 무한루프, 고부하
%MEM메모리 사용률지속 증가 → 메모리 누수 의심
VSZ가상 메모리 (KB)Java는 VSZ가 크게 나와도 정상
RSS실제 사용 물리 메모리 (KB)실제 소비량은 RSS 기준
STAT프로세스 상태Z=좀비, D=I/O 대기(많으면 디스크 문제)
TIME누적 CPU 시간갑자기 증가하면 비정상 부하
로컬 터미널
# CPU 사용률 TOP 10
ps aux --sort=-%cpu | head -11

# 메모리 사용률 TOP 10
ps aux --sort=-%mem | head -11
💡개념

top으로 실시간 리소스 모니터링

CPU가 100%를 찍고 있는데 어떤 프로세스가 원인인지 모르면 재시작만 반복하게 됩니다. 재시작하면 잠깐 나아지다가 30분 후 다시 튀는 패턴이 반복됐는데, top으로 확인하니 특정 배치 스크립트가 주기적으로 CPU를 독점하고 있었습니다. load average가 코어 수보다 높다는 것의 의미, wa(I/O 대기)가 높을 때의 판단 기준을 알아야 원인을 좁힐 수 있습니다.

로컬 터미널
top
# top - 14:30:00 up 2 days, 3:15,  2 users,  load average: 0.52, 0.48, 0.45
# Tasks: 185 total,   1 running, 184 sleeping,   0 stopped,   0 zombie
# %Cpu(s):  5.2 us,  1.1 sy,  0.0 ni, 93.5 id,  0.1 wa,  0.0 hi,  0.0 si
# MiB Mem :  7821.4 total,  2341.2 free,  3621.8 used,  1858.4 buff/cache
# MiB Swap:  2048.0 total,  2048.0 free,     0.0 used.  3819.4 avail Mem

load average 해석:

  • 0.52, 0.48, 0.45: 1분, 5분, 15분 평균 실행 큐 길이
  • CPU 4코어 서버에서 load average 4.0 = 100% 포화
  • CPU 코어 수보다 지속적으로 높으면 응답 지연 발생

%Cpu 컬럼 해석:

항목의미주목 기준
us사용자 프로세스 CPU높으면 앱 레벨 부하
sy시스템(커널) CPU높으면 시스템 콜 과다
waI/O 대기높으면(5%+) 디스크/네트워크 병목
id유휴(idle)낮으면 전체 CPU 부하 높음

top 인터랙티브 키:

q: 종료
k: 프로세스 종료 (PID 입력)
M: 메모리 사용률 기준 정렬
P: CPU 사용률 기준 정렬 (기본)
1: 코어별 CPU 사용률 표시
프로세스 부하 진단 실습
🔍실행 후 확인할 것
  • ps aux 첫 컬럼은 USER — 서비스 계정(tomcat, nginx 등)으로 떠있으면 정상
  • STAT 컬럼에서 Z(좀비) 프로세스가 있으면 부모 프로세스 문제 의심
  • nproc 결과가 4인 서버에서 load average가 4.0 이상이면 CPU 포화 상태
  • TIME 컬럼 값이 갑자기 큰 프로세스는 최근 CPU를 집중 소비한 것

포트 점검

💡개념

ss와 lsof로 포트 확인

"서비스가 안 뜬다"는 제보를 받았는데 systemctl status는 정상이라고 합니다.

포트 진단 흐름 — 서비스 연결 불가 시 확인 순서 확인해보니 Tomcat이 8080이 아닌 18080으로 기동됐고, Nginx의 proxy_pass는 여전히 8080을 바라보고 있었습니다. 포트 번호가 맞지 않으면 서비스가 뜨더라도 트래픽이 전달되지 않습니다. 어떤 프로세스가 어느 포트를 점유하는지 1분 안에 파악하는 것이 연결 문제 진단의 핵심입니다.

netstat은 deprecated입니다. 현대 Linux에서는 ss를 사용합니다.

로컬 터미널
# 리스닝 중인 TCP 포트 전체 + 프로세스 정보
ss -tlnp
# State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
# LISTEN  0       128     0.0.0.0:80         0.0.0.0:*          users:(("nginx",pid=1234,fd=6))
# LISTEN  0       511     0.0.0.0:8080       0.0.0.0:*          users:(("java",pid=5678,fd=32))
# LISTEN  0       128     127.0.0.1:3306     0.0.0.0:*          users:(("mysqld",pid=9012,fd=25))

# UDP 포트 포함
ss -ulnp

# 특정 포트에 무엇이 연결됐는지
ss -tnp | grep ':8080'

# 특정 포트를 점유한 프로세스 확인
sudo lsof -i:8080
# COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# java    5678 tomcat  123u  IPv4  89012      0t0  TCP *:8080 (LISTEN)

# 특정 PID가 열고 있는 파일/소켓
sudo lsof -p 5678 | head -20

일반적인 포트 매핑:

포트서비스비고
80HTTP (Nginx/Apache)
443HTTPS
8080Tomcat HTTP
8443Tomcat HTTPS
3306MySQL/MariaDB127.0.0.1만 LISTEN이 정상
5432PostgreSQL
6379Redis
22SSH
로컬 터미널
# 외부에서 DB 포트가 열려있는지 확인 (보안 점검)
ss -tlnp | grep ':3306'
# LISTEN  0  80  127.0.0.1:3306  0.0.0.0:*  ← 안전 (127.0.0.1만 바인딩)
# LISTEN  0  80  0.0.0.0:3306    0.0.0.0:*  ← 위험! 모든 IP에서 접근 가능
포트 점유 상태 진단 실습
🔍실행 후 확인할 것
  • ss -tlnp 결과에서 Local Address가 0.0.0.0이면 모든 IP에서 접근 가능
  • 127.0.0.1로 바인딩된 포트는 로컬에서만 접근 가능 — DB 포트의 올바른 상태
  • 예상 포트(8080 등)가 목록에 없으면 서비스가 다른 포트로 떴거나 죽은 것
  • 같은 포트가 두 줄 이상 보이면 포트 충돌 — 서비스 기동 실패 원인

리소스 점검

💡개념

df로 디스크 사용량 확인

자정에 로그 파일이 자동 삭제됐는데 디스크 사용률이 100%에서 내려오지 않았습니다. 삭제된 파일을 열고 있는 프로세스가 파일 핸들을 놓지 않고 있었기 때문입니다. 공간은 있는데 파일이 안 만들어지는 경우는 inode가 소진됐을 때입니다. df -hdf -i를 항상 세트로 확인해야 이런 함정에서 벗어날 수 있습니다.

로컬 터미널
# 마운트된 파티션별 디스크 사용량
df -h
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda1        50G   32G   16G  67% /
# /dev/sdb1       200G   45G  145G  24% /data
# tmpfs           3.9G  1.2M  3.9G   1% /dev/shm

# inode 사용량 (공간이 있어도 파일 못 만드는 상황 진단)
df -i
# Filesystem     Inodes  IUsed  IFree IUse% Mounted on
# /dev/sda1     3276800 198432 3078368    7% /
# /var            655360 654990    370  100% /var  ← inode 소진!

# 특정 디렉터리가 어느 파티션에 있는지 확인
df -h /opt/tomcat/logs

디스크 가득 찼을 때 원인 찾기:

로컬 터미널
# 각 디렉터리별 사용량 (1단계 깊이만)
du -sh /var/log/* | sort -rh | head -20

# 특정 디렉터리 하위 상세 확인
du -sh /var/log/nginx/*

# 가장 큰 파일 TOP 10 찾기 (전체 시스템)
sudo find / -xdev -type f -exec du -sh {} + 2>/dev/null | sort -rh | head -10

# /var 디렉터리 하위 큰 파일들
sudo du -ah /var | sort -rh | head -20

inode 소진 시 대응:

로컬 터미널
# inode 많이 쓰는 디렉터리 찾기
for dir in /var /tmp /opt; do
  echo "$dir: $(find $dir -maxdepth 3 -type f 2>/dev/null | wc -l) files"
done

# 오래된 세션 파일, 임시 파일 정리 예시
find /var/lib/php/sessions -type f -mtime +7 -delete
find /tmp -type f -mtime +3 -delete
💡개념

free로 메모리 상태 확인

Java 서비스가 갑자기 응답이 느려졌는데 CPU는 멀쩡했습니다. Swap 사용량을 보니 1GB가 사용 중이었고, JVM이 메모리 부족으로 디스크 swap을 쓰고 있었습니다. Swap은 디스크 속도로 동작하기 때문에 Java 애플리케이션은 swap이 0이어야 정상입니다. free -m을 보는 법을 모르면 이 상황을 메모리 문제로 진단하지 못합니다.

로컬 터미널
free -m
#               total   used   free  shared  buff/cache  available
# Mem:           7821   3621   2341      45        1858       3819
# Swap:          2047      0   2047

# 지속적으로 모니터링
watch -n 2 free -m

free 출력 해석 핵심:

  • available: 실제로 사용 가능한 메모리 (가장 중요한 지표)

    • free + buff/cache 중 회수 가능한 것의 합
    • available이 total의 10~15% 미만이면 메모리 부족 경고
  • buff/cache: OS 캐시 (필요 시 회수 가능) → 정상 현상

    • Linux는 남는 메모리를 캐시로 활용해 성능 향상
    • used가 높아 보여도 buff/cache가 대부분이면 문제없음
  • Swap used > 0: 메모리 부족으로 디스크를 메모리처럼 사용 중

    • 응답 속도 급감의 원인, Java 애플리케이션은 특히 치명적
로컬 터미널
# Java 프로세스 실제 메모리 사용량 확인
ps aux --sort=-%mem | awk 'NR==1 || /java/'

# /proc으로 상세 확인
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree|Cached'
💡개념

journalctl로 서비스 로그 조회

서비스가 재시작됐는데 왜 재시작됐는지 알 수 없었습니다. catalina.out을 봤는데 로그가 너무 많아 어디서 오류가 났는지 찾기 힘들었습니다. journalctl로 시간 범위를 지정하면 장애 발생 시점의 로그만 추출할 수 있어 원인을 빠르게 좁힐 수 있습니다. 로그 파일을 전체 스크롤하는 것과 시간 기반으로 필터링하는 것의 차이는 30분 대 2분입니다.

서버 터미널
# 특정 서비스 로그 (최근 100줄)
journalctl -u nginx -n 100 --no-pager

# 시간 범위 지정 조회
journalctl -u tomcat --since "2025-01-15 09:00:00" --until "2025-01-15 10:00:00"
journalctl -u tomcat --since "1 hour ago"
journalctl -u tomcat --since "30 min ago"

# 에러 레벨 이상만 조회
journalctl -u myapp -p err --since "today"

# 실시간 로그 팔로우
journalctl -u nginx -f

# 부팅 이후 전체 로그
journalctl -b

# 커널 메시지 (OOM killer 등 확인)
journalctl -k --since "today" | grep -E 'oom|killed|error' -i

OOM(Out of Memory) 발생 확인:

서버 터미널
# OOM Killer가 프로세스를 죽였는지 확인
journalctl -k --since "today" | grep -i "oom\|killed process\|out of memory"
# 또는
dmesg | grep -i "oom\|killed"
디스크·메모리 상태 진단 실습
🔍실행 후 확인할 것
  • df -h에서 Use%가 85% 이상인 파티션은 즉시 원인 파악 필요
  • df -i에서 IUse%가 90% 이상이면 파일 생성 불가 위험 — 작은 파일 대량 생성 서비스 점검
  • free -m에서 Swap used가 0 이상이면 메모리 부족 상태 — Java 서비스 성능 저하 원인
  • available이 total의 10% 미만이면 메모리 부족 경보
5분 서버 상태 점검 루틴 실습
🔍실행 후 확인할 것
  • uptime 명령어에서 load average 3개 값(1/5/15분)이 CPU 코어 수 이하면 정상
  • ss -tlnp에서 서비스에 해당하는 포트(예: 8080, 3306)가 LISTEN 상태로 보인다
  • free -m의 available 값이 전체 메모리의 20% 이상이면 여유 있는 상태
  • df -i 실행 시 IUse%가 90% 미만이면 inode 고갈 위험 없음
  • systemctl list-units --state=failed 결과가 비어있으면 전체 서비스 정상
💼
실무 맥락
현업 패턴

실제 업무에서 이 지식이 쓰이는 상황:

이 모듈의 명령어들은 장애 대응 시 가장 먼저 실행하는 것들입니다.

온콜(On-call) 대응 시 첫 3분:

로컬 터미널
# 1. 부하 확인
uptime; top -bn1 | head -15

# 2. 문제 서비스 상태
systemctl status tomcat nginx

# 3. 포트 확인 (서비스가 떠있는지)
ss -tlnp | grep ':8080'

# 4. 최근 에러 로그
journalctl -u tomcat --since "5 min ago" --no-pager

# 5. 디스크/메모리
df -h; free -m

이 다섯 단계로 대부분의 원인을 3분 안에 좁힐 수 있습니다. "뭔지 모르겠어요"가 아니라 "CPU 문제입니다" "디스크 꽉 찼습니다" "프로세스가 죽었습니다"로 빠르게 전달할 수 있어야 합니다.

다음 모듈에서는 이런 점검 과정을 자동화하는 Shell 스크립팅을 다룹니다.

지식 확인

퀴즈 — 4문제

Q1

ss -tlnp 명령어에서 각 옵션의 의미로 올바른 것은?

Q2

df -h 출력에서 Use% 98%로 나오는 파티션이 있습니다. 먼저 확인해야 할 것은?

Q3

top 명령어에서 load average가 CPU 코어 수보다 높을 때 의미하는 것은?

Q4

df -i 명령어로 무엇을 확인할 수 있는가?

0 / 4 답변

🧪 실습으로 확인하기

Nginx 설치 및 기동

초급

Linux 서버에 Nginx를 설치하고 systemd 서비스로 등록하여 80포트에서 응답하는 상태까지 만든다.

30📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

infra-ops입문 · 55
[Infra Ops] Linux 사용자/그룹/권한 체계와 서비스 계정 관리
인프라 서비스 운영 트랙 계속
linux입문 · 30
[Linux] 개발자가 왜 리눅스 서버와 커맨드라인을 반드시 배워야 하는가
Linux 트랙 시작점