← 전체 글로 돌아가기

서버 운영

Ubuntu 서버 디스크 사용량을 오해하지 않게 du와 df를 함께 본 설정 노트

df와 du의 숫자가 다를 때 삭제한 파일을 다시 지우기보다 열린 파일과 마운트를 확인한 순서입니다.

숫자가 서로 맞지 않았던 아침

배포 로그가 더 이상 기록되지 않아 df -h를 먼저 실행했다. 루트 파티션은 92%였는데, 프로젝트 디렉터리에서 du -sh *를 더한 값은 절반도 되지 않았다. 예전이라면 큰 Docker 이미지부터 지웠겠지만, 이번에는 두 명령이 무엇을 측정하는지부터 구분했다.

  • df: 파일시스템이 할당한 블록 기준
  • du: 디렉터리에서 이름으로 접근 가능한 파일 기준

열린 삭제 파일을 확인했다

프로세스가 파일을 연 채로 삭제하면 디렉터리에서는 사라져도 공간은 프로세스가 닫을 때까지 반환되지 않는다. 다음 명령으로 삭제 표시가 붙은 파일을 찾았다.

sudo lsof +L1
sudo du -xhd1 /var 2>/dev/null | sort -h
findmnt --df

실제로 오래 실행 중인 Node 프로세스가 회전 전 로그 파일을 붙잡고 있었다. 로그 파일을 다시 만들도록 graceful reload를 하고, 무작정 kill하지 않은 이유는 진행 중인 요청을 끊지 않기 위해서였다.

sudo systemctl reload my-app
sleep 2
sudo lsof +L1

Docker 정리는 마지막에 했다

그 다음에야 Docker 사용량을 확인했다. docker system df의 reclaimable 값만 보고 전부 지우면 아직 사용 중인 이미지까지 다시 내려받게 된다.

docker system df
sudo journalctl --disk-usage
sudo du -xhd1 /var/lib/docker 2>/dev/null | sort -h

정리 기준은 컨테이너가 참조하지 않는 이미지와 오래된 journal만으로 제한했다. Docker volume은 데이터베이스가 들어 있을 수 있어 자동 삭제 대상에서 제외했다.

운영 중 정한 기준

디스크 경보는 80%에서 알리고, 90%에서는 새 배포를 멈추고 원인을 기록한다. dfdu의 차이가 크면 아래 순서를 지킨다.

  1. 다른 파일시스템을 섞지 않도록 du -x로 범위를 고정한다.
  2. lsof +L1로 삭제됐지만 열린 파일을 찾는다.
  3. 마운트 지점과 컨테이너 로그를 확인한다.
  4. 마지막에만 캐시와 미사용 이미지를 정리한다.

디스크가 찼다는 사실과 어떤 파일을 지워야 하는지는 다른 문제였다. 숫자가 다를수록 삭제 명령보다 파일 핸들 조사가 먼저다.