- Published on
journalctl 로그 폭증? systemd 압축·보관 최적화
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버를 운영하다 보면 어느 날 갑자기 디스크가 가득 차고, 원인을 추적해보니 journalctl(정확히는 systemd-journald) 로그가 /var/log/journal 아래에서 폭증하는 경우가 있습니다. 특히 컨테이너 런타임, 프록시, 애플리케이션이 stdout/stderr로 과도하게 뿜는 환경에서는 journald가 “사실상의 로그 집하장”이 되면서 디스크 IO와 용량을 동시에 잡아먹습니다.
이 글에서는 journald의 저장 방식(휘발성/영구), 압축, 보관(로테이션/보존 기간/상한), 그리고 장애를 피하는 운영 팁까지 실전 관점으로 정리합니다. 로그가 폭증하면 장애 징후(예: OOMKilled, CrashLoopBackOff의 단서)도 함께 묻히기 쉬우니, 용량 최적화와 관측 가능성 사이의 균형이 핵심입니다. 관련 장애 추적 관점은 K8s CrashLoopBackOff에서 OOMKilled 원인 추적도 함께 참고하면 좋습니다.
1) journald가 디스크를 먹는 구조 이해하기
journald는 바이너리 저널 파일로 로그를 저장합니다. 주요 포인트는 아래와 같습니다.
- 저장 위치
- 영구 저장:
/var/log/journal - 휘발성 저장:
/run/log/journal(재부팅 시 사라짐)
- 영구 저장:
- 로테이션 방식
- 파일 단위로 쪼개고(세그먼트), 크기/시간/정책에 따라 오래된 파일을 정리합니다.
- 압축
- 기본적으로 압축을 지원하며, 정책에 따라 디스크 사용량이 크게 달라집니다.
- rate limit
- 특정 서비스가 초당 수천 줄을 뿜으면 journald가 자체적으로 드롭하거나(설정에 따라), 디스크를 빠르게 채울 수 있습니다.
journald의 현재 상태를 가장 먼저 확인하는 커맨드는 다음입니다.
journalctl --disk-usage
저널 파일이 어디에 얼마나 있는지, 파일 목록을 보고 싶다면:
ls -lh /var/log/journal
ls -lh /run/log/journal
2) 응급 조치: 당장 디스크를 비우는 방법
디스크가 이미 꽉 찼다면 “정책을 바꾸기 전에” 먼저 공간을 확보해야 서비스가 살아납니다.
2-1) 크기 기준으로 즉시 정리
예를 들어 저널 총량을 1GB로 줄입니다.
sudo journalctl --vacuum-size=1G
2-2) 기간 기준으로 즉시 정리
최근 7일만 남기고 삭제:
sudo journalctl --vacuum-time=7d
2-3) 파일 개수 기준 정리
저널 파일을 10개만 남김:
sudo journalctl --vacuum-files=10
주의할 점은, vacuum은 “정책을 영구 적용”하는 설정이 아니라는 것입니다. 재발 방지를 위해서는 journald.conf에 보관 상한을 설정해야 합니다.
3) 재발 방지: journald.conf로 보관·압축 정책 고정
설정 파일은 보통 아래 중 하나입니다.
/etc/systemd/journald.conf/etc/systemd/journald.conf.d/*.conf(권장: 드롭인)
드롭인 방식 예시는 다음과 같습니다.
sudo mkdir -p /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/99-retention.conf > /dev/null <<'EOF'
[Journal]
SystemMaxUse=2G
SystemKeepFree=1G
SystemMaxFileSize=200M
SystemMaxFiles=20
Compress=yes
EOF
적용 후 재시작:
sudo systemctl restart systemd-journald
3-1) 핵심 옵션 설명
SystemMaxUse- 영구 저널(
/var/log/journal)이 사용할 수 있는 최대 용량 상한
- 영구 저널(
SystemKeepFree- 파일시스템에 남겨둘 최소 여유 공간(이 값만큼은 비워두려 함)
SystemMaxFileSize- 저널 단일 파일의 최대 크기(너무 크면 vacuum/회전 비용이 커짐)
SystemMaxFiles- 유지할 파일 개수 상한
Compress- 압축 사용 여부
운영 팁: SystemMaxUse만 설정하면 “디스크가 꽉 찰 때까지” 커질 수 있습니다. SystemKeepFree를 함께 설정해, 운영체제/컨테이너 레이어/DB가 쓸 공간을 강제로 남겨두는 편이 안전합니다.
4) 영구 저장이 필요 없으면 휘발성으로 전환
일부 워커 노드나 배치 서버처럼 “재부팅 후 로그가 필요 없다”면, 애초에 디스크에 남기지 않는 것이 가장 확실한 최적화입니다.
[Journal]
Storage=volatile
Storage=volatile은/run/log/journal에만 저장합니다.- 장애 분석을 위해 최소한의 보관이 필요하다면,
Storage=persistent를 유지하되 용량 상한을 강하게 두는 방식이 더 현실적입니다.
5) 로그 폭증의 근본 원인: rate limit과 noisy 서비스 제어
5-1) journald rate limit 조정
폭주 서비스가 있어도 journald가 무한히 받아 적지 않도록 제한할 수 있습니다.
[Journal]
RateLimitIntervalSec=30s
RateLimitBurst=10000
RateLimitIntervalSec동안RateLimitBurst를 초과하면 드롭이 발생할 수 있습니다.- 드롭이 싫다면 burst를 올리는 게 아니라, “원인 서비스의 로그량을 줄이는 것”이 먼저입니다.
5-2) 특정 유닛의 로그 레벨/출력 줄이기
애플리케이션이 디버그 로그를 stdout으로 과도하게 출력하면 journald가 그대로 저장합니다. systemd 유닛에서 환경 변수를 내려 로그 레벨을 낮추거나, 애플리케이션 로거 설정을 조정하세요.
또한 컨테이너 환경에서 docker logs가 journald로 연결된 경우, 로그가 기하급수로 늘 수 있습니다. docker exec가 멈추거나 cgroup/TTY 이슈로 디버깅이 길어질 때 로그도 같이 폭증하는 경우가 있어, 원인 파악은 Docker exec가 멈출 때 - cgroup v2·TTY 원인도 같이 보면 도움이 됩니다.
6) 점검 루틴: “정책이 먹었는지” 확인하는 커맨드
6-1) journald 설정 확인
systemd-analyze cat-config systemd/journald.conf
드롭인 포함 최종 적용값을 보여주므로, “내가 쓴 값이 실제로 적용됐는지” 확인하기에 좋습니다.
6-2) 현재 디스크 사용량
journalctl --disk-usage
6-3) 특정 기간/유닛만 빠르게 조회
폭증 원인을 찾을 때는 전체를 뒤지기보다, 유닛 단위로 범위를 좁히는 게 효율적입니다.
# 최근 1시간, 특정 유닛
journalctl -u nginx.service --since "1 hour ago" --no-pager
# 부팅 이후 에러 레벨만
journalctl -p err -b --no-pager
6-4) 가장 많이 말하는 주범 찾기(간이)
_SYSTEMD_UNIT 기준으로 카운트해보면 noisy 유닛을 빠르게 찾을 수 있습니다.
journalctl --since "24 hours ago" -o json \
| jq -r '._SYSTEMD_UNIT // "(none)"' \
| sort | uniq -c | sort -nr | head
jq가 없다면 설치 후 진행하거나, journalctl -u로 후보 유닛을 좁혀가며 확인하는 방식이 현실적입니다.
7) 운영에서 자주 하는 실수와 권장 조합
7-1) SystemMaxUse만 설정하고 끝내기
- 문제: 디스크 여유가 줄어들 때 다른 서비스가 먼저 죽습니다.
- 권장:
SystemMaxUse+SystemKeepFree를 같이 둡니다.
7-2) vacuum으로만 대응
- 문제: 며칠 뒤 다시 폭증합니다.
- 권장: vacuum은 응급,
journald.conf는 상시 정책.
7-3) 압축을 끄기
- 문제: CPU는 아낄 수 있어도 디스크를 더 빨리 먹습니다.
- 권장: 대부분 서버에서는
Compress=yes가 유리합니다. CPU가 극도로 빡빡한 시스템에서만 신중히 검토하세요.
7-4) 로그가 중요한 시스템인데 Storage=volatile
- 문제: 재부팅 후 장애 단서가 사라집니다.
- 권장: 장애 분석이 중요한 서버는 영구 저장 + 강한 상한 + 중앙 로그 수집(예: Loki/ELK/CloudWatch 등)을 고려합니다.
인증/권한 문제로 장애가 반복될 때 로그가 핵심 단서가 되는 경우가 많습니다. 예를 들어 배포 파이프라인에서 OIDC 권한 이슈가 터지면 짧은 시간에 에러 로그가 폭증하기도 합니다. 이런 케이스는 GitHub Actions 403 권한오류 해결 - GITHUB_TOKEN·OIDC처럼 원인 자체를 제거하는 것이 로그 최적화보다 우선입니다.
8) 추천 설정 템플릿(보수적, 운영 친화)
아래는 “디스크를 지키되, 최근 로그는 남기는” 보수적 템플릿입니다.
[Journal]
Storage=persistent
Compress=yes
# 저널 총량 상한
SystemMaxUse=2G
# 디스크 여유를 강제로 확보
SystemKeepFree=2G
# 파일이 너무 커지지 않게
SystemMaxFileSize=200M
SystemMaxFiles=20
# 폭주 방지(환경에 맞게 조정)
RateLimitIntervalSec=30s
RateLimitBurst=20000
적용 절차:
sudo mkdir -p /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/99-journal-tuning.conf > /dev/null <<'EOF'
[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=2G
SystemKeepFree=2G
SystemMaxFileSize=200M
SystemMaxFiles=20
RateLimitIntervalSec=30s
RateLimitBurst=20000
EOF
sudo systemctl restart systemd-journald
journalctl --disk-usage
마무리
journalctl 로그 폭증은 단순히 “로그가 많다” 문제가 아니라, 디스크 고갈로 이어져 서비스 장애를 유발하는 운영 이슈입니다. 응급 시에는 journalctl --vacuum-*로 즉시 공간을 확보하고, 이후에는 SystemMaxUse/SystemKeepFree/SystemMaxFileSize/Compress 조합으로 보관 정책을 고정하세요. 마지막으로 rate limit과 noisy 서비스 자체의 로그량을 줄여, journald가 병목이나 장애 원인이 되지 않도록 만드는 것이 장기적으로 가장 효과적입니다.