/var/log 는 지우는 것보다 무엇이 쌓이고 있는지 찾는 것이 먼저다. 지우기만 하면 원인이 그대로라 며칠 안에 같은 상태로 돌아온다.
du -xh --max-depth=1 /var/log | sort -h
journalctl --disk-usage
du 의 -x 는 다른 파일시스템으로 넘어가지 않게 한다. /var/log 아래에 별도 마운트가 있으면 이 옵션 없이는 엉뚱한 합계가 나온다.
용량을 크게 먹는 것은 대체로 다음이다.
| 경로 | 쌓는 주체 | 제어 방법 |
|---|---|---|
/var/log/journal |
systemd-journald 의 바이너리 저널 | journald.conf 의 SystemMaxUse |
/var/log/containers · /var/log/pods |
kubelet 이 만드는 컨테이너 로그(실체는 심볼릭 링크) | kubelet 의 containerLogMaxSize · containerLogMaxFiles |
/var/log/messages · secure · cron |
rsyslog | logrotate |
*.gz · *.old |
logrotate 가 남긴 과거 파일 | logrotate 의 rotate 횟수 |
du 합계와 df 사용량이 크게 어긋나면 파일 목록에 없는 무언가가 블록을 잡고 있다는 뜻이다. 순서대로 본다.
삭제됐지만 프로세스가 열어 둔 파일. 가장 흔한 원인이다. logrotate 가 파일을 지웠는데 로그를 쓰던 프로세스가 파일 디스크립터를 계속 들고 있으면 inode 는 남아 있고 블록도 해제되지 않는다.
lsof +L1 | grep /var/log
lsof -nP | grep deleted
(deleted) 가 붙은 대용량 파일이 나오면 그 프로세스를 재시작한다. rsyslog 라면 systemctl restart rsyslog 로 끝난다. 파일을 다시 지우는 것으로는 해결되지 않는다.
inode 고갈. 용량이 아니라 inode 가 바닥난 경우다. 작은 파일이 대량으로 쌓이는 경로에서 나온다.
df -i /var/log
IUse% 가 100% 면 용량을 비워도 쓰기가 실패한다.
/var/log 가 실제로 어디에 있는지. 별도 파티션인지, 루트에 묻혀 있는지, 컨테이너의 오버레이 위인지에 따라 대상이 달라진다.
df -hT /var/log
mount | grep -w /var/log
ext4 의 예약 블록. ext4 는 기본적으로 5% 를 root 전용으로 남겨 둔다. 일반 사용자 프로세스는 이 영역을 쓰지 못해 "가득 참"으로 보인다.
tune2fs -l /dev/<device> | grep -i 'Reserved block'
tune2fs -m 1 /dev/<device>
로그 전용 파티션이라면 예약 비율을 1% 정도로 낮춰도 된다. 루트 파일시스템에서는 줄이지 않는다.
저널부터 줄이는 것이 효과가 가장 크다.
journalctl --vacuum-time=7d
journalctl --vacuum-size=1G
회전된 과거 파일은 나이 기준으로 정리한다.
find /var/log -type f -name '*.gz' -mtime +30 -delete
/var/log/containers 와 /var/log/pods 는 직접 지우지 않는다. kubelet 이 관리하는 경로라 지워도 다시 만들어지고, 실행 중인 파드의 로그를 지우면 kubectl logs 가 깨진다. 아래의 kubelet 설정으로 제한한다.
journald 상한. /etc/systemd/journald.conf 에 상한을 명시한다. 기본값은 파일시스템 용량의 10% 라서 디스크가 크면 저널도 그만큼 커진다.
[Journal]
SystemMaxUse=1G
SystemKeepFree=500M
MaxRetentionSec=7day
systemctl restart systemd-journald
logrotate. /etc/logrotate.d/ 아래 개별 설정이 실제로 도는지 확인한다.
logrotate -d /etc/logrotate.conf
-d 는 실제로 회전하지 않고 판단만 출력한다. 강제로 돌릴 때만 -f 를 쓴다.
kubelet 컨테이너 로그 상한. 쿠버네티스 노드에서는 이 설정이 없으면 /var/log 가 반복해서 찬다.
containerLogMaxSize: 10Mi
containerLogMaxFiles: 5
/var/lib/kubelet/config.yaml 에 넣고 systemctl restart kubelet 으로 반영한다. 기본값은 각각 10Mi 와 5 지만, 배포판이나 설치 도구가 다른 값을 넣어 두는 경우가 있으므로 실제 파일을 확인한다.
lsof 로 열린 파일을 추적하는 방법.