본문 바로가기
K8S/Docker

Docker 사용후 이상하게 용량이 많아 진다? - Docker 컨테이너 로그 관리방법

by Rainbound-IT 2026. 2. 20.
반응형

 

 

Docker 컨테이너는 기본적으로 stdout/stderr 출력을 JSON 파일로 저장한다. 별도 설정 없이 운영하면 로그가 무한히 쌓여 디스크를 가득 채우는 주범이 된다.


1. Docker 로그 구조

로그가 쌓이는 원리

컨테이너 stdout/stderr
    ↓
Docker 로그 드라이버 (기본: json-file)
    ↓
/var/lib/docker/containers/<container-id>/<container-id>-json.log

컨테이너 내부에서 console.log(), print(), echo 등으로 출력하는 모든 내용이 이 파일에 JSON 형태로 기록된다.

로그 파일 형식

{"log":"2026-02-20T07:28:15.123Z INFO  Server started on port 8000\\\\n","stream":"stdout","time":"2026-02-20T07:28:15.123456789Z"}
{"log":"2026-02-20T07:28:16.456Z ERROR Connection refused\\\\n","stream":"stderr","time":"2026-02-20T07:28:16.456789012Z"}
  • log: 실제 로그 내용
  • stream: stdout 또는 stderr
  • time: 타임스탬프

기본 설정의 문제점

 

항목  기본값
로그 드라이버 json-file
최대 크기 제한 없음 (무제한)
로테이션 없음
압축 없음

→ 설정 없이 운영하면 로그가 무한히 커진다.


2. 로그 확인 명령어

컨테이너 로그 보기

# 최근 100줄
docker logs <container> --tail 100

# 실시간 스트리밍
docker logs <container> -f

# 특정 시간 이후 로그
docker logs <container> --since "2026-02-20T00:00:00"

# 최근 1시간 로그
docker logs <container> --since 1h

# 타임스탬프 포함
docker logs <container> -t --tail 50

로그 파일 크기 확인

# 특정 컨테이너 로그 경로 확인
docker inspect <container> --format='{{.LogPath}}'

# 특정 컨테이너 로그 크기
du -sh $(docker inspect <container> --format='{{.LogPath}}')

# 전체 컨테이너 로그 크기 한눈에 보기
du -sh /var/lib/docker/containers/*/*-json.log | sort -rh

# Docker 전체 디스크 사용량
docker system df -v

3. 로그 즉시 정리

truncate (권장)

# 특정 컨테이너 로그 비우기
sudo truncate -s 0 $(docker inspect <container> --format='{{.LogPath}}')
  • 컨테이너 재시작 없음
  • 서비스 중단 없음
  • Docker가 같은 파일에 새 로그를 계속 씀
  • 기존 로그 내용만 사라짐

rm은 왜 안 되나?

# ❌ 이렇게 하면 안 됨
sudo rm $(docker inspect <container> --format='{{.LogPath}}')

 

비교  truncate  RM
파일 핸들 유지됨 끊어짐
디스크 해제 즉시 프로세스 종료 후
서비스 영향 없음 로그 기록 오류 가능
복구 방법 불필요 컨테이너 재시작 필요

Docker 데몬이 로그 파일을 열어둔(open) 상태이므로, rm으로 삭제해도 프로세스가 파일 핸들을 유지하여 디스크 공간이 즉시 해제되지 않는다. lsof +L1 명령으로 이런 "삭제됐지만 공간을 차지하는" 파일을 확인할 수 있다.

전체 컨테이너 로그 일괄 비우기

# 모든 컨테이너 로그 비우기
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'

4. 로그 크기 제한 설정

방법 1: daemon.json (전역 설정)

모든 컨테이너에 일괄 적용되는 Docker 데몬 레벨 설정이다.

sudo tee /etc/docker/daemon.json <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
EOF

 

옵션  설명  권장값
max-size 로그 파일 1개의 최대 크기 50m ~ 200m
max-file 로테이션 파일 수 3 ~ 5
compress gzip 압축 여부 "true" (선택)

위 설정이면 컨테이너당 최대 300MB (100MB × 3파일)로 제한된다.

# 적용 (Docker 재시작 필요)
sudo systemctl restart docker

주의사항:

  • Docker 재시작 시 모든 컨테이너가 재시작된다
  • 설정은 새로 생성되는 컨테이너부터 적용
  • 기존 컨테이너는 재생성해야 적용됨

방법 2: docker-compose.yml (서비스별 설정)

서비스마다 다른 로그 설정을 적용할 수 있다.

services:
  # API 서버 - 로그 많으므로 넉넉하게
  api:
    image: myapp:latest
    logging:
      driver: json-file
      options:
        max-size: "200m"
        max-file: "5"

  # Worker - 로그 적으므로 작게
  worker:
    image: myapp-worker:latest
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

  # 로그 불필요한 서비스
  redis:
    image: redis:7
    logging:
      driver: "none"
# 재생성하여 적용
docker compose down && docker compose up -d

방법 3: docker run 개별 설정

docker run -d \\\\
  --log-opt max-size=100m \\\\
  --log-opt max-file=3 \\\\
  --name myapp \\\\
  myapp:latest

설정 우선순위

docker run --log-opt  >  docker-compose logging  >  daemon.json
(개별 컨테이너)          (서비스별)                    (전역)

개별 설정이 전역 설정보다 우선한다.


5. 로그 드라이버 종류

json-file 외에도 다양한 로그 드라이버를 선택할 수 있다.

 

드라이버  설명  docker logs 지원
json-file 기본값. JSON 파일 저장 O
local 최적화된 로컬 저장 (압축 지원) O
journald systemd journal로 전달 O
syslog syslog 서버로 전달 X
fluentd Fluentd로 전달 X
awslogs AWS CloudWatch로 전달 X
gcplogs Google Cloud Logging으로 전달 X
none 로그 비활성화 X

local 드라이버 (json-file 대안)

{
  "log-driver": "local",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

json-file과의 차이:

  • 내부적으로 압축 저장하여 디스크 절약
  • 20~30% 더 적은 공간 사용
  • docker logs 명령 사용 가능
  • 단, 외부 로그 수집기가 JSON 파일을 직접 읽는 방식이면 호환 안 됨

로그 드라이버를 none으로 설정

로그가 불필요한 서비스(Redis, DB 등)는 아예 끌 수 있다.

docker run -d --log-driver none redis:7

6. 자동화: 로그 정리 Cron

간단한 cron 설정

# 매일 새벽 2시에 1GB 이상인 로그 파일 비우기
echo '0 2 * * * find /var/lib/docker/containers/ -name "*-json.log" -size +1G -exec truncate -s 0 {} \\\\;' | sudo crontab -

종합 정리 스크립트

#!/bin/bash
# /usr/local/bin/docker-log-cleanup.sh

LOG_FILE="/var/log/docker-log-cleanup.log"
THRESHOLD="500M"  # 이 크기 이상인 로그만 정리

echo "=== Docker Log Cleanup $(date) ===" >> $LOG_FILE

# 정리 전 사용량
echo "Before:" >> $LOG_FILE
du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -rh | head -5 >> $LOG_FILE

# 500MB 이상 로그 파일 truncate
find /var/lib/docker/containers/ -name "*-json.log" -size +${THRESHOLD} -exec truncate -s 0 {} \\\\;

# 정리 후 사용량
echo "After:" >> $LOG_FILE
df -h / | tail -1 >> $LOG_FILE

echo "=== Cleanup Complete ===" >> $LOG_FILE
sudo chmod +x /usr/local/bin/docker-log-cleanup.sh

# 매일 새벽 2시 실행
echo "0 2 * * * /usr/local/bin/docker-log-cleanup.sh" | sudo crontab -

7. 모니터링: 로그 크기 알림

디스크 사용량 감시 스크립트

#!/bin/bash
# /usr/local/bin/docker-log-alert.sh

THRESHOLD_GB=5  # 5GB 이상이면 알림
ALERT_FILE="/tmp/docker-log-alert"

total_size=$(du -sb /var/lib/docker/containers/*/*-json.log 2>/dev/null | awk '{sum+=$1} END {print sum}')
threshold_bytes=$((THRESHOLD_GB * 1024 * 1024 * 1024))

if [ "$total_size" -gt "$threshold_bytes" ] 2>/dev/null; then
    total_human=$(echo $total_size | awk '{printf "%.1fGB", $1/1024/1024/1024}')

    # 큰 로그 파일 Top 3
    top_logs=$(du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -rh | head -3)

    echo "Docker 로그 경고: 총 ${total_human} (임계값: ${THRESHOLD_GB}GB)"
    echo "Top 3:"
    echo "$top_logs"

    # 여기에 Slack/Email 알림 추가 가능
fi
# 매시간 체크
echo "0 * * * * /usr/local/bin/docker-log-alert.sh" | sudo crontab -

8. 운영 환경별 권장 설정

개발 환경

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "2"
  }
}

컨테이너당 최대 100MB. 디버깅용 로그만 유지.

스테이징/프로덕션 (로컬 보관)

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "200m",
    "max-file": "5",
    "compress": "true"
  }
}

컨테이너당 최대 1GB. 압축으로 실제 저장 공간은 더 적다.

프로덕션 (외부 전송)

{
  "log-driver": "fluentd",
  "log-opts": {
    "fluentd-address": "localhost:24224",
    "tag": "docker.{{.Name}}"
  }
}

Fluentd/Fluent Bit → ElasticSearch/CloudWatch 등으로 중앙 수집. 로컬 디스크에 로그를 쌓지 않으므로 용량 문제가 원천 차단된다.


9. 트러블슈팅

로그 truncate 했는데 용량이 안 줄어요

# 삭제됐지만 프로세스가 잡고 있는 파일 확인
sudo lsof +L1

# 해당 프로세스 확인 후 Docker 재시작 (최후의 수단)
sudo systemctl restart docker

daemon.json 적용했는데 기존 컨테이너에 안 먹어요

# 기존 컨테이너의 로그 설정 확인
docker inspect <container> --format='{{.HostConfig.LogConfig}}'

# docker-compose라면 재생성
docker compose down && docker compose up -d

# 개별 컨테이너라면
docker stop <container> && docker rm <container>
# 다시 run (daemon.json 설정이 적용됨)

어떤 컨테이너가 로그를 많이 쌓는지 모르겠어요

# 컨테이너별 로그 크기 + 이름 매핑
for id in $(docker ps -q); do
  name=$(docker inspect $id --format='{{.Name}}')
  size=$(du -sh $(docker inspect $id --format='{{.LogPath}}') 2>/dev/null | awk '{print $1}')
  echo "$size $name"
done | sort -rh

10. 빠른 참조 (Quick Reference)

# === 확인 ===
docker logs <container> --tail 100       # 최근 100줄
docker logs <container> -f               # 실시간 스트리밍
docker inspect <container> --format='{{.LogPath}}'  # 로그 파일 경로
du -sh /var/lib/docker/containers/*/*-json.log | sort -rh  # 전체 크기

# === 정리 ===
sudo truncate -s 0 $(docker inspect <id> --format='{{.LogPath}}')  # 비우기 (권장)
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'  # 전체 비우기

# === 제한 설정 ===
# /etc/docker/daemon.json (전역)
{"log-driver":"json-file","log-opts":{"max-size":"100m","max-file":"3"}}

# docker-compose.yml (서비스별)
logging:
  driver: json-file
  options:
    max-size: "100m"
    max-file: "3"

# 적용
sudo systemctl restart docker             # daemon.json
docker compose down && docker compose up -d  # docker-compose

참고

반응형

댓글