kill -9를 습관처럼 치고 있다면 한 번 멈춰야 합니다. kill은 프로세스를 "죽이는" 명령이 아니라 시그널을 보내는 명령입니다. 어떤 시그널을 보내느냐에 따라 프로세스가 정리하고 나가는지, 그냥 끊기는지가 갈립니다.
kill은 시그널 전송이다
kill 1234 # 기본값 SIGTERM(15) 전송
kill -9 1234 # SIGKILL(9) 전송
kill -l # 시그널 목록 보기
kill에 PID만 주면 기본으로 SIGTERM을 보냅니다. -9는 SIGKILL을 보내는 것이고, 이 둘의 동작은 전혀 다릅니다.
SIGTERM vs SIGKILL — 결정적 차이
| 시그널 | 번호 | 프로세스가 받으면 | 가로챌 수 있나 |
|---|---|---|---|
| SIGTERM | 15 | 정리 후 스스로 종료(graceful) | 가능(핸들러 등록) |
| SIGKILL | 9 | 즉시 강제 종료 | 불가능 |
SIGTERM은 "정리하고 나가라"는 정중한 요청입니다. 프로세스는 이 시그널을 받으면 핸들러를 실행해 열린 파일을 닫고, 진행 중인 요청을 마치고, 커넥션을 반환한 뒤 종료할 수 있습니다.
SIGKILL은 커널이 프로세스를 즉시 끊어버립니다. 프로세스는 이 시그널을 가로챌 수 없으므로 정리 작업이 불가능합니다. 그래서 쓰다 만 파일, 반환 안 된 락, 끊긴 요청이 남을 수 있습니다.
graceful shutdown이 왜 중요한가
웹 서버를 예로 들면, SIGTERM을 받은 서버는 새 요청은 거절하되 처리 중인 요청은 끝까지 응답한 뒤 종료합니다. 이게 graceful shutdown입니다. Docker의 docker stop, 쿠버네티스의 Pod 종료도 먼저 SIGTERM을 보내고 유예 시간(기본 30초 등)을 준 다음, 그래도 안 죽으면 SIGKILL을 보냅니다.
docker stop <컨테이너> # SIGTERM 후 10초 기다렸다가 SIGKILL
즉 SIGKILL은 최후의 수단이지 1순위가 아닙니다.
안 죽는 프로세스 — 단계적 종료
kill 1234 # 1) 먼저 SIGTERM (정중히)
# 몇 초 기다려도 살아있으면
kill -9 1234 # 2) 그래도 안 되면 SIGKILL
ps -p 1234 # 종료됐는지 확인
SIGKILL로도 안 죽는다면 프로세스가 커널 안에서 I/O를 기다리는 D(uninterruptible sleep) 상태일 수 있습니다. 이때는 시그널이 통하지 않으니 디스크·NFS 등 I/O 원인을 봐야 합니다.
체크리스트
kill <PID> # 1순위: SIGTERM, graceful 종료 유도
ps -p <PID> # 종료됐는지 확인
kill -9 <PID> # 최후 수단: SIGKILL(정리 불가)
kill -l # 시그널 번호·이름 확인
시그널과 프로세스 상태를 직접 보내보고 관찰하는 실습은 리눅스 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.