Docker 로그 정리 완벽 가이드: json.log로 디스크가 가득 차는 것을 막는 5가지 방법

빠른 결론: 먼저 급한 불을 끄고 근본 원인을 해결하세요
Docker 로그가 디스크를 가득 채웠다면 가장 효과적인 처리 순서는 다음과 같습니다.
먼저 truncate로 급한 불을 끄고 공간을 확보한 뒤, max-size + max-file을 설정해 로그를 로테이션하고, 마지막으로 컨테이너를 다시 생성해 설정을 적용합니다.
정리만 하고 설정하지 않으면 문제가 재발합니다. 설정만 하고 컨테이너를 다시 만들지 않으면 기존 컨테이너의 로그도 계속 커집니다.
새벽 3시 17분, 휴대폰 진동이 얕은 잠에 빠져 있던 저를 깨웠습니다.
화면에는 눈에 띄는 빨간색 경고가 떠 있었습니다. “운영 서버 디스크 사용률 100%, 모든 서비스가 응답을 멈췄습니다.” 순간 가슴이 철렁했습니다. 수십만 명의 사용자가 이용하는 전자상거래 플랫폼이었고, 서비스가 1분 멈출 때마다 실제 손실이 발생하는 상황이었습니다.
곧바로 SSH로 서버에 접속했습니다. df -h를 실행하니 루트 파티션이 실제로 가득 차 있었습니다. 여러 항목을 점검한 끝에 /var/lib/docker/containers/ 디렉터리에서 원인을 찾았습니다. 컨테이너 하나의 xxx-json.log 파일이 무려 82GB였습니다!
솔직히 당시에는 당황했습니다. 컨테이너는 멀쩡히 실행되고 있었는데, 로그가 어떻게 이렇게까지 커진 걸까요?
나중에야 이것이 드문 일이 아니라는 사실을 알게 됐습니다. Docker는 기본적으로 로그 파일 크기를 제한하지 않습니다. stdout과 stderr의 모든 출력이 json.log 파일에 기록되고, 디스크가 가득 찰 때까지 계속해서 커집니다.
Docker 로그 때문에 골치가 아프더라도 걱정하지 마세요. 이 글에서는 대용량 로그 파일을 긴급하게 정리하는 방법, 재발 방지를 위해 로그 로테이션을 설정하는 방법, 상황에 맞는 로그 드라이버를 선택하는 방법을 설명합니다. 제가 직접 겪었던 시행착오도 정리했으니 같은 문제를 피하는 데 도움이 되길 바랍니다.
Docker 로그는 왜 디스크를 가득 채울까요?
Docker의 로그 저장 방식
먼저 Docker가 로그를 처리하는 방식부터 살펴보겠습니다.
컨테이너가 console.log(), System.out.println() 또는 다른 방식으로 stdout과 stderr에 내용을 출력하면 Docker는 그 내용을 모두 JSON 형식의 로그 파일에 기록합니다. 이 파일은 /var/lib/docker/containers/<container-id>/<container-id>-json.log에 있습니다.
여기까지는 정상적으로 들립니다. 문제는 Docker가 기본적으로 어떠한 로그 로테이션도 수행하지 않는다는 점입니다.
즉, 로그 파일은 계속 커지고 오래된 로그가 자동으로 분할되거나 삭제되지 않습니다. 컨테이너가 하루 동안 실행되며 1GB를 기록한다면 일주일 뒤에는 7GB, 한 달 뒤에는 30GB가 됩니다. 애플리케이션이 로그를 특히 많이 남긴다면, 예를 들어 로그 레벨을 DEBUG로 설정했다면 증가 속도는 훨씬 더 빠릅니다.
간단히 계산해 봤습니다. 트래픽이 중간 정도인 웹 애플리케이션이 초당 100개의 로그를 출력하고, 각 로그의 평균 크기가 100바이트라면 하루 동안 쌓이는 로그는 다음과 같습니다.
초당 100개 × 86400초 × 100바이트 ≈ 하루 864MB ≈ 월 25GB
이런 컨테이너가 10개라면 100GB 디스크가 한 달도 되기 전에 가득 찰 수 있습니다. 이것도 보수적으로 계산한 수치입니다.
특히 문제가 생기기 쉬운 상황
저와 주변 동료들의 경험을 보면 다음 상황이 가장 위험합니다.
1. 애플리케이션 로그 레벨이 너무 낮은 경우
개발할 때 디버깅하기 편하도록 로그 레벨을 INFO 또는 DEBUG로 설정하고, 운영 환경에 배포할 때 되돌리는 것을 잊는 경우입니다. 그러면 모든 HTTP 요청마다 많은 디버그 정보가 출력되면서 로그가 빠르게 증가합니다.
제가 본 가장 심한 사례는 요청 본문 로깅을 켠 Node.js 서비스였습니다. 사용자가 이미지를 업로드할 때마다 전체 base64 문자열을 로그에 기록해 요청 하나가 몇 MB의 로그를 만들었습니다. 3일도 지나지 않아 200GB 디스크가 가득 찼습니다.
2. 프로그램에서 오류가 반복되는 경우
이 경우는 더 치명적입니다. 버그 때문에 애플리케이션이 무한 루프에 빠져 예외와 스택 정보를 계속 출력하면 로그 파일 증가 속도가 무서울 정도로 빨라집니다.
한번은 데이터베이스 연결 풀 설정 문제 때문에 마이크로서비스 하나가 초당 수백 번씩 연결을 재시도했고, 매번 전체 예외 스택을 출력했습니다. 그 결과 3시간 만에 컨테이너 로그가 2GB에서 120GB로 치솟아 디스크가 다운됐습니다.
3. 장기간 실행되는 운영 컨테이너
운영 환경에서 컨테이너를 몇 달이나 몇 년 동안 계속 실행하면서 로그 로테이션을 설정하지 않았다면 로그 파일이 상당히 커질 수 있습니다.
예전에 인수한 프로젝트에는 8개월 동안 실행된 Nginx 컨테이너가 있었고, 로그 파일이 이미 150GB에 달했습니다. docker logs로 로그를 볼 때마다 Docker가 거대한 파일을 읽어야 해서 한참 동안 멈췄습니다.
4. 트래픽이 많은 애플리케이션
방문량이 많은 애플리케이션은 당연히 로그도 많습니다. 일일 PV가 수백만인 웹사이트는 요청마다 정상적인 액세스 로그를 한 줄만 남겨도 누적량이 엄청납니다.
많은 사람이 이 문제를 인식하지 못한다는 것이 핵심입니다. 어느 날 새벽 디스크가 가득 차 시스템이 다운되고 나서야 Docker 로그에 이런 함정이 있다는 사실을 알게 됩니다.
긴급 정리: 디스크 공간을 즉시 확보하는 방법
이제 디스크가 가득 찼고 서비스는 멈췄으며 상사가 단체 채팅방에서 계속 여러분을 찾고 있다고 해보겠습니다. 당황하지 말고 먼저 공간부터 확보하세요.
1단계: 원인이 되는 파일 찾기
먼저 어떤 로그 파일이 가장 큰지 알아야 합니다. 다음 명령을 실행하세요.
find /var/lib/docker/ -name "*.log" -exec ls -sh {} \; | sort -h -r | head -20
크기가 큰 로그 파일 20개를 크기순으로 보여줍니다. 다음과 비슷한 결과가 표시됩니다.
82G /var/lib/docker/containers/a1b2c3d4.../a1b2c3d4...-json.log
35G /var/lib/docker/containers/e5f6g7h8.../e5f6g7h8...-json.log
12G /var/lib/docker/containers/i9j0k1l2.../i9j0k1l2...-json.log
...
가장 큰 파일 몇 개를 찾고 container ID, 즉 긴 문자열을 기록해 둡니다.
특정 컨테이너의 로그 위치를 알고 싶다면 다음 명령을 사용하세요.
docker inspect --format='{{.LogPath}}' <container_name_or_id>
예를 들어 nginx 컨테이너의 경우 다음과 같습니다.
docker inspect --format='{{.LogPath}}' nginx
# 출력: /var/lib/docker/containers/abc123.../abc123...-json.log
2단계: 로그를 안전하게 비우기
중요합니다. 로그 파일을 rm으로 직접 삭제하지 마세요!
저도 처음에는 같은 실수를 했습니다. rm -f xxx-json.log로 파일을 바로 삭제하자 Docker가 제대로 처리하지 못했습니다. Docker 프로세스가 계속 파일 핸들을 잡고 있기 때문에 파일을 삭제해도 Docker는 파일이 있다고 생각하고 계속 기록하며, 실제로는 해당 디스크 공간이 해제되지 않습니다.
올바른 방법은 파일을 삭제하는 것이 아니라 내용을 비우는 것입니다.
방법 1: cat 명령으로 비우기
cat /dev/null > $(docker inspect --format='{{.LogPath}}' <container_id>)
이 명령은 로그 파일에 빈 내용을 덮어씁니다. 파일은 그대로 있지만 크기가 0이 됩니다. Docker 프로세스는 변화를 인식하지 못한 채 정상적으로 계속 작동합니다.
예를 들어 nginx 컨테이너의 로그를 비우려면 다음 명령을 사용합니다.
cat /dev/null > $(docker inspect --format='{{.LogPath}}' nginx)
방법 2: truncate 명령 사용(권장)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_id>)
truncate는 파일을 자르는 데 사용하는 더 직접적인 명령입니다. -s 0은 파일 크기를 0바이트로 설정한다는 뜻입니다.
nginx 컨테이너 로그를 비우려면 다음과 같이 실행합니다.
truncate -s 0 $(docker inspect --format='{{.LogPath}}' nginx)
방법 3: 모든 컨테이너 로그 일괄 비우기
모든 컨테이너의 로그가 크고 한 번에 정리하고 싶다면 다음 명령을 사용할 수 있습니다.
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'
주의: 이 명령은 모든 컨테이너의 모든 로그를 비웁니다. 신중하게 사용하세요. 실행하기 전에 보관해야 할 과거 로그가 없는지 확인하는 것이 좋습니다.
저는 보통 긴급 상황에서만 이 명령을 사용합니다. 평소에는 중요한 로그를 실수로 지우지 않도록 하나씩 정리하는 편을 권합니다.
결과 확인
정리가 끝나면 df -h를 실행해 디스크 공간을 확인합니다.
df -h /var/lib/docker/
사용률이 크게 낮아진 것을 볼 수 있어야 합니다. 낮아지지 않았다면 일부 컨테이너가 여전히 로그를 매우 빠르게 기록하고 있을 수 있습니다. 이때는 DEBUG 로그를 끄거나 반복 오류 버그를 수정하는 등 해당 애플리케이션의 문제부터 해결해야 합니다.
저는 당시 82GB 로그 파일을 정리한 뒤 디스크 사용률이 100%에서 60%로 한 번에 떨어졌고 서비스도 곧바로 복구됐습니다. 하지만 이것은 증상만 해결한 것이라는 점을 알고 있었습니다. 문제를 근본적으로 해결하려면 로그 로테이션을 설정해야 합니다.
근본 해결책: 로그 로테이션 설정
긴급 정리는 급한 상황만 해결합니다. 문제를 완전히 해결하려면 Docker가 로그 크기를 자동으로 관리하도록 설정해 무한히 커지지 않게 해야 합니다.
전역 설정: daemon.json 수정
가장 간단하고 흔히 사용하는 방법은 Docker 전역 설정 파일에서 로그 로테이션 매개변수를 지정하는 것입니다.
설정 파일 위치: /etc/docker/daemon.json
파일이 없다면 새로 만들고 다음 내용을 추가합니다.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
각 매개변수의 의미는 다음과 같습니다.
- max-size: 개별 로그 파일의 최대 크기입니다. 이 크기에 도달하면 로테이션되어 새 파일이 생성됩니다.
- max-file: 보관할 로그 파일의 최대 개수입니다. 이 수를 넘으면 가장 오래된 파일이 삭제됩니다.
- compress: 로테이션된 오래된 로그 파일을 압축해 공간을 절약할지 결정합니다.
이 설정에서는 각 컨테이너가 로그에 사용하는 공간이 최대 10MB × 3 = 30MB입니다. 압축 효과는 계산에 포함하지 않았습니다.
운영 환경 권장값:
제 경험과 업계 관행을 기준으로 운영 환경에서는 다음처럼 설정할 수 있습니다.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"compress": "true"
}
}
max-size: "100m"은 문제 분석을 위해 더 많은 로그를 남길 수 있는 공간을 제공합니다. max-file: "3"은 파일 3개, 즉 최근 300MB의 로그 기록을 보관합니다.
실제 상황에 맞게 조정할 수도 있습니다.
- 로그 양이 적은 애플리케이션:
max-size: "10m",max-file: "3" - 로그 양이 중간인 애플리케이션:
max-size: "50m",max-file: "3" - 로그 양이 많은 애플리케이션:
max-size: "100m",max-file: "5"
중요: Docker는 문자열 형식을 요구하므로 모든 설정값을 따옴표로 감싸야 합니다. ““max-size”: 10m`처럼 따옴표 없이 작성하면 오류가 발생합니다.
Docker를 재시작해 설정 적용
daemon.json을 수정한 뒤에는 반드시 Docker 서비스를 재시작해야 합니다.
sudo systemctl restart docker
재시작하면 Docker가 새 설정을 불러옵니다. 하지만 중요한 점은 이 설정이 새로 생성하는 컨테이너에만 적용되고, 이미 실행 중인 컨테이너에는 적용되지 않는다는 것입니다.
그러면 어떻게 해야 할까요? 컨테이너를 다시 생성해야 합니다.
docker run으로 시작한 컨테이너라면 다음과 같이 실행합니다.
docker stop <container_name>
docker rm <container_name>
docker run [原来的参数] <image>
docker-compose를 사용한다면 다음과 같이 실행합니다.
docker-compose down
docker-compose up -d
down은 컨테이너를 중지하고 삭제하며, up -d는 새 설정으로 컨테이너를 다시 생성합니다. 새 컨테이너에는 이제 로그 로테이션 설정이 적용됩니다.
개별 컨테이너 설정
전역 설정을 바꾸지 않고 로그가 특히 많은 컨테이너 하나만 제한하고 싶을 수도 있습니다. 이때는 컨테이너를 시작할 때 다음 옵션을 지정하면 됩니다.
docker run 사용:
docker run -d \
--name my-app \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:latest
docker-compose.yml 사용:
version: '3.8'
services:
web:
image: nginx:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
compress: "true"
이 방법은 유연하다는 장점이 있습니다. 컨테이너마다 서로 다른 로그 정책을 적용할 수 있습니다. 예를 들면 다음과 같습니다.
- Nginx 컨테이너에는 더 많은 로그 보관:
max-size: "50m",max-file: "5" - 중요도가 낮은 예약 작업 컨테이너:
max-size: "5m",max-file: "2"
설정 적용 여부 확인
설정이 실제로 적용됐는지 어떻게 확인할까요? docker inspect로 컨테이너의 로그 설정을 확인합니다.
docker inspect <container_name> | grep -A 10 LogConfig
다음과 비슷한 결과가 표시됩니다.
"LogConfig": {
"Type": "json-file",
"Config": {
"max-file": "3",
"max-size": "10m",
"compress": "true"
}
}
{}라는 빈 객체가 보이면 컨테이너가 여전히 기본 설정, 즉 무제한 증가 설정을 사용하고 있다는 뜻입니다. 이 경우 컨테이너를 다시 생성해야 합니다.
저는 당시 설정을 마친 뒤 모든 컨테이너의 로그 설정을 확인하는 작은 스크립트까지 작성해 누락된 컨테이너가 없는지 확인했습니다. 그 후에는 로그가 디스크를 가득 채우는 문제로 더는 고생하지 않았습니다.
로그 드라이버 선택 가이드
앞에서 설명한 내용은 모두 기본 json-file 드라이버를 기준으로 합니다. 하지만 Docker는 용도가 서로 다른 여러 로그 드라이버를 지원합니다.
어떤 드라이버를 써야 할지 궁금할 수 있습니다.
json-file(기본 드라이버)
Docker의 기본 선택입니다.
장점:
docker logs명령을 지원해 문제를 분석하기 편리합니다.- 설정이 간단하며
max-size와max-file만 추가하면 됩니다. - 로컬에 저장하므로 접근 속도가 빠릅니다.
단점:
- 기본적으로 로테이션하지 않아 디스크가 가득 찰 수 있습니다. 이것이 이 글에서 다루는 핵심 문제입니다.
- 로그가 호스트에 저장되기 때문에 컨테이너를 삭제하면 로그도 사라집니다.
적합한 상황: 대부분의 상황에 적합합니다. 로그 로테이션만 제대로 설정하면 충분히 사용할 수 있습니다.
권장 설정:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3",
"compress": "true"
}
}
local 드라이버(권장)
Docker 18.09 이상을 사용한다면 저는 이 드라이버를 더 권합니다.
장점:
- 자동 로테이션을 지원하며 기본적으로 로그 크기를 제한하므로 직접 설정하지 않아도 됩니다.
- 파일 형식이 더 효율적이어서 json-file보다 성능이 좋습니다.
docker logs명령도 지원합니다.
단점:
- Docker 18.09 이상이 필요합니다.
- 로그 형식이 바이너리여서
cat으로 직접 볼 수 없습니다. 하지만 일반적으로 직접 볼 필요는 없습니다.
적합한 상황: 운영 환경에서 적극 권장합니다. 관리가 편하고 성능도 좋습니다.
설정 방법:
{
"log-driver": "local",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
저는 요즘 새 프로젝트에서 모두 이 드라이버를 사용합니다. 확실히 json-file보다 관리하기 편합니다.
journald 드라이버
서버가 systemd를 사용한다면, 예를 들어 Ubuntu 16.04+나 CentOS 7+라면 이 드라이버를 고려할 수 있습니다.
장점:
- 시스템 로그와 통합해 한곳에서 관리할 수 있습니다.
- 자동으로 로테이션하므로 디스크를 가득 채우지 않습니다.
- 컨테이너 ID와 컨테이너 이름 같은 메타데이터가 포함된 구조화 로그를 제공합니다.
docker logs와journalctl명령을 지원합니다.
단점:
- systemd 시스템에서만 사용할 수 있습니다.
- journald에 익숙하지 않다면 학습이 필요할 수 있습니다.
적합한 상황: 운영 체계가 이미 systemd와 journald를 기반으로 한다면 일관성을 유지할 수 있습니다.
설정 방법:
{
"log-driver": "journald"
}
journalctl로 컨테이너 로그 보기:
journalctl -u docker.service -f CONTAINER_NAME=my-app
syslog 드라이버
주로 로그를 syslog 서버로 전송하는 데 사용합니다.
장점:
- 원격 syslog 서버로 보내 중앙 집중식으로 로그를 관리할 수 있습니다.
- TCP와 UDP를 지원하며 TCP가 더 안정적입니다.
- 기존 syslog 인프라가 있다면 자연스럽게 통합할 수 있습니다.
단점:
docker logs명령을 지원하지 않습니다. 문제를 분석할 때 불편하다는 큰 단점입니다.- 네트워크 지연이 생길 수 있습니다.
- syslog 서버를 설정하고 유지해야 합니다.
적합한 상황: 성숙한 syslog 중앙 로그 시스템을 이미 운영하는 대규모 클러스터입니다.
설정 방법:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://192.168.1.100:514",
"syslog-facility": "daemon",
"tag": "{{.Name}}/{{.ID}}"
}
}
솔직히 꼭 필요한 경우가 아니라면 syslog는 그다지 권하지 않습니다. docker logs를 사용할 수 없어 문제를 분석할 때 정말 불편하기 때문입니다.
제안
상황에 맞춰 다음처럼 선택하세요.
| 상황 | 권장 드라이버 | 이유 |
|---|---|---|
| 단일 서버 또는 소규모 클러스터 | local 또는 json-file+로테이션 | 간단하고 안정적이며 docker logs 지원 |
| systemd 환경 | journald | 시스템 로그와 통합해 일관되게 관리 |
| 대규모 클러스터 | fluentd/loki + 로컬 드라이버 | 중앙 집중식 로그와 긴급 대응용 로컬 로그를 함께 제공 |
| 기존 syslog 사용 | syslog + 로컬 드라이버 | 원격과 로컬에 모두 보관하는 이중 보호 |
제 경우 소규모 프로젝트에서는 local 드라이버를 사용하고, 대규모 프로젝트에서는 json-file과 Loki를 함께 사용해 로그를 중앙 집중식으로 관리합니다. 로컬에는 긴급 분석을 위해 최근 수백 MB만 보관합니다.
어떤 드라이버를 선택하든 한 가지 원칙을 기억하세요. 로컬 로그 크기를 반드시 제한해야 합니다. 무한히 커지도록 두면 언젠가는 디스크가 가득 찹니다.
모범 사례와 운영 조언
당장의 문제를 해결했으니 이제 장기적인 운영 경험을 살펴보겠습니다.
운영 환경 설정 체크리스트
운영 환경을 담당한다면 다음 항목을 하나씩 확인해 보세요.
1. 전역 로그 설정
{
"log-driver": "local",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
또는 json-file 사용:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"compress": "true"
}
}
2. 모든 컨테이너 설정 확인
모든 컨테이너에 로그 로테이션이 적용됐는지 확인하는 스크립트를 작성합니다.
#!/bin/bash
for container in $(docker ps -q); do
name=$(docker inspect --format='{{.Name}}' $container | sed 's/\///')
logconfig=$(docker inspect --format='{{json .HostConfig.LogConfig}}' $container)
echo "容器: $name"
echo "日志配置: $logconfig"
echo "---"
done
한 번 실행해 빠진 컨테이너가 없는지 확인하세요.
3. 모니터링 알림 설정
디스크가 가득 찬 뒤에 알게 되어서는 안 됩니다. 미리 다음 알림을 설정하세요.
- 디스크 사용률 > 80%: 경고
- 디스크 사용률 > 90%: 심각한 경고
/var/lib/docker/containers/디렉터리 크기가 임계값 초과: 경고
저는 Prometheus + Grafana + Alertmanager를 사용하며 설정은 매우 간단합니다.
- alert: HighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes > 0.8
for: 5m
annotations:
summary: "磁盘使用率超过80%"
4. 정기 점검
매주 또는 매달 로그 점검 스크립트를 실행해 어떤 컨테이너의 로그가 가장 빠르게 늘어나는지 확인합니다.
# Docker 디렉터리 전체 크기 확인
du -sh /var/lib/docker/
# 로그 디렉터리 크기 확인
du -sh /var/lib/docker/containers/
# 가장 큰 로그 파일 찾기
find /var/lib/docker/containers/ -name "*-json.log" -exec du -h {} \; | sort -h -r | head -10
이상 징후를 발견하면 즉시 처리합니다.
애플리케이션 계층 최적화 제안
Docker 로그 관리는 인프라 계층의 일이지만 애플리케이션 계층에서도 함께 대응해야 합니다.
1. 로그 레벨 조정
운영 환경에서는 지나치게 많은 로그를 만드는 DEBUG나 INFO 레벨을 사용하지 마세요. 다음 설정을 권합니다.
- 운영 환경: WARN 또는 ERROR
- 테스트 환경: INFO
- 개발 환경: DEBUG
이렇게 하면 로그 양을 최소 80% 줄일 수 있습니다.
2. 전문 로그 시스템 사용
애플리케이션 로그 양이 특히 많다면 Docker 로그만으로 감당하려 하지 마세요. 다음과 같은 방식을 사용해야 합니다.
- 애플리케이션에서 ELK(Elasticsearch + Logstash + Kibana)로 직접 기록
- 또는 더 가벼운 Loki + Grafana 사용
- 또는 클라우드 업체의 로그 서비스 사용(Alibaba Cloud SLS, Tencent Cloud CLS 등)
Docker 로그는 긴급 분석을 위한 최근 소량의 로그만 보관합니다.
3. 구조화 로그
나중에 쉽게 분석할 수 있도록 JSON 형식의 구조화 로그를 출력합니다.
// 나쁜 방법
console.log("用户登录成功,用户ID: " + userId);
// 좋은 방법
console.log(JSON.stringify({
level: "info",
event: "user_login",
userId: userId,
timestamp: new Date().toISOString()
}));
구조화 로그는 검색하고 분석하기가 더 쉽습니다.
4. 로그 샘플링
일부 로그의 양이 너무 많다면, 예를 들어 모든 HTTP 요청을 기록한다면 샘플링을 고려할 수 있습니다.
// 요청 로그의 10%만 기록
if (Math.random() < 0.1) {
console.log("HTTP请求详情...");
}
또는 오류가 발생했을 때만 세부 정보를 기록합니다.
if (error) {
console.log("详细请求信息: ", requestDetails);
}
자주 묻는 질문(FAQ)
Q1: daemon.json을 설정한 뒤 Docker를 재시작하면 실행 중인 컨테이너에 영향이 있나요?
A: 없습니다. Docker를 재시작해도 컨테이너는 중지되지 않고 계속 실행됩니다. 하지만 설정은 새 컨테이너에만 적용되므로 기존 컨테이너는 다시 생성해야 합니다.
Q2: 로그 파일을 비우면 애플리케이션 실행에 영향이 있나요?
A: 없습니다. Docker 프로세스는 계속 파일 핸들을 잡고 있으므로 truncate로 파일을 비운 뒤에도 Docker가 계속 기록합니다. 애플리케이션은 전혀 알아차리지 못합니다.
Q3: log-driver=journald를 사용한다면 max-size도 설정해야 하나요?
A: 필요하지 않습니다. journald는 자체 로테이션 방식으로 로그 크기를 관리합니다.
Q4: 로그 로테이션을 이미 설정했는데 로그가 여전히 큰 이유는 무엇인가요?
A: 다음 두 가지를 확인하세요.
- 컨테이너를 다시 생성했나요? daemon.json은 새 컨테이너에만 적용됩니다.
- 애플리케이션이 매우 큰 단일 행 로그를 출력하나요? 로그 로테이션 기준은 행 수가 아니라 파일 크기입니다.
Q5: /var/lib/docker/containers/ 디렉터리의 오래된 로그 파일을 직접 삭제해도 되나요?
A: 이미 로테이션된 오래된 파일, 예를 들어 xxx-json.log.1.gz라면 삭제할 수 있습니다. 하지만 현재 사용 중인 xxx-json.log는 삭제하지 말고 truncate로 비우세요.
주의 사항 요약
마지막으로 실수하지 않도록 핵심 사항을 정리하겠습니다.
- daemon.json 설정은 새 컨테이너에만 적용되므로 기존 컨테이너는 다시 생성해야 합니다.
- 설정 매개변수는 반드시 따옴표로 감싸야 합니다. 예를 들어
"max-size": "10m"로 작성해야 하며"max-size": 10m로 작성하면 안 됩니다. - truncate는 안전하고 rm은 위험합니다. 로그를 비울 때는 truncate를 사용하고 파일을 삭제하지 마세요.
- 로그 드라이버마다 docker logs 지원 여부가 다릅니다. syslog는 지원하지 않고 json-file과 journald는 지원합니다.
- daemon.json을 수정한 뒤 Docker를 재시작해야 합니다.
systemctl restart docker를 사용하세요. - 로그 설정을 정기적으로 확인하세요. 새로 배포한 컨테이너에 설정이 누락되지 않도록 해야 합니다.
지금까지 많은 내용을 설명했지만 핵심은 한 문장입니다. 미리 설정하고 정기적으로 점검하며, 디스크가 가득 찬 뒤에야 수습하지 마세요.
결론
글 앞부분에서 이야기한 새벽 3시 알림으로 돌아가 보겠습니다.
당시 로그를 정리하는 데 30분, 로그 로테이션과 모니터링을 설정하는 데 2시간을 썼고, 모든 컨테이너를 다시 생성했습니다. 아침 6시가 되어서야 모든 작업을 마쳤습니다.
하지만 이 사고를 통해 한 가지를 배웠습니다. Docker 로그 관리는 절대 가볍게 볼 문제가 아닙니다. 평소에는 드러나지 않다가 한 번 터지면 큰 문제가 되는 시한폭탄과 같습니다.
이 글의 핵심 내용을 정리하면 다음과 같습니다.
긴급 상황: truncate로 대용량 로그 파일을 비워 즉시 공간을 확보하고 서비스를 복구합니다.
예방: daemon.json에서 로그 로테이션(max-size + max-file)을 설정하고 적절한 로그 드라이버(local 또는 json-file 권장)를 선택한 뒤, 모든 컨테이너를 다시 생성해 설정을 적용합니다.
장기 운영: 디스크 모니터링 알림을 설정하고, 로그 설정을 정기적으로 확인하며, 애플리케이션의 로그 출력을 최적화합니다.
현재 Docker를 개발 환경이나 운영 환경에서 사용하고 있다면 지금 바로 다음 항목을 확인해 보세요.
find /var/lib/docker/ -name "*.log" -exec ls -sh {} \; | sort -h -r | head -10을 실행해 매우 큰 로그 파일이 있는지 확인합니다./etc/docker/daemon.json에 로그 로테이션이 설정돼 있는지 확인합니다.docker inspect로 모든 컨테이너에 로그 제한이 적용됐는지 확인합니다.
새벽에 알림 때문에 잠에서 깬 뒤에야 이 문제를 깨닫지 마세요.
이 글이 도움이 됐다면 같은 문제를 겪을 수 있는 분들과 공유해 주세요. 모두가 시행착오를 줄이고 잠을 더 잘 수 있길 바랍니다.
다음 글
Docker 로그 정리 전체 절차
json.log로 디스크가 가득 차는 것을 막는 5가지 방법: json.log 정리, 로그 로테이션 설정, 적절한 로그 드라이버 선택
⏱️ Estimated time: 30 min
- 1
Step 1: 문제의 심각성 이해 및 긴급 정리
문제의 심각성:
• 운영 서버 디스크 사용률이 100%가 되어 모든 서비스가 응답을 멈춤
• 컨테이너 하나의 xxx-json.log 파일이 무려 82GB에 달함
• Docker는 기본적으로 로그 파일 크기를 제한하지 않음
• stdout과 stderr의 모든 출력이 json.log 파일에 기록되고 디스크가 가득 찰 때까지 계속 커짐
대용량 로그 파일 긴급 정리:
• truncate 명령으로 로그 파일 비우기:
truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
• 또는 로그 파일을 삭제한 뒤 컨테이너를 재시작해 디스크 공간을 빠르게 확보 - 2
Step 2: 로그 로테이션 및 로그 크기 제한 설정
로그 로테이션 설정:
• daemon.json에서 log-opts 설정(max-size: 10m, max-file: 3)
• 개별 로그 파일 크기와 보관 파일 수 제한
• 로그 파일을 자동으로 로테이션해 무한 증가 방지
설정 예시:
• /etc/docker/daemon.json에 다음 내용 추가:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
• Docker 서비스 재시작: systemctl restart docker
로그 크기 제한:
• max-size로 개별 로그 파일 크기 제한(10m, 50m 등)
• max-file로 보관 파일 수 제한(3, 5 등)
• 제한을 넘으면 오래된 로그 자동 삭제 - 3
Step 3: 로그 드라이버 선택 및 모범 사례
로그 드라이버 선택:
• json-file(기본값, 개발 환경에 적합)
• syslog(운영 환경과 중앙 집중식 관리에 적합)
• journald(systemd 시스템에 적합)
• none(로그 비활성화)
• 상황에 맞는 로그 드라이버 선택
모범 사례:
• 로그 로테이션을 설정하고 로그 크기 제한
• 적절한 로그 드라이버 사용
• 오래된 로그 정기 정리: docker system prune
• 디스크 사용량 모니터링 및 알림 설정
• 새로 배포한 컨테이너에서 설정이 빠지지 않도록 로그 설정 정기 점검
핵심은 한 문장입니다. 미리 설정하고 정기적으로 점검하며, 디스크가 가득 찬 뒤에야 수습하지 마세요.
FAQ
Docker 로그 파일은 왜 디스크를 가득 채우나요?
• 운영 서버 디스크 사용률이 100%가 되어 모든 서비스가 응답을 멈춤
• 컨테이너 하나의 xxx-json.log 파일이 무려 82GB에 달함
• Docker는 기본적으로 로그 파일 크기를 제한하지 않음
• stdout과 stderr의 모든 출력이 json.log 파일에 기록됨
• 그 뒤 디스크가 가득 찰 때까지 계속 커짐
로그 파일 위치: /var/lib/docker/containers/<container-id>/<container-id>-json.log. 각 컨테이너의 로그가 이곳에 저장되며, 로그 로테이션을 설정하지 않으면 로그 파일이 무한히 커집니다.
Docker 로그 파일을 긴급하게 정리하려면 어떻게 해야 하나요?
• truncate 명령으로 로그 파일 비우기:
truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
• 또는 로그 파일을 삭제한 뒤 컨테이너를 재시작해 디스크 공간을 빠르게 확보
대용량 로그 파일 찾기:
• find 명령으로 큰 파일 찾기:
find /var/lib/docker/containers -name '*-json.log' -size +1G
• du 명령으로 디렉터리 크기 확인:
du -sh /var/lib/docker/containers/*
• 공간을 많이 차지하는 로그 파일 식별
Docker 로그 로테이션은 어떻게 설정하나요?
• daemon.json에서 log-opts 설정(max-size: 10m, max-file: 3)
• 개별 로그 파일 크기와 보관 파일 수 제한
• 로그 파일을 자동으로 로테이션해 무한 증가 방지
설정 예시:
• /etc/docker/daemon.json에 다음 내용 추가:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
• Docker 서비스 재시작: systemctl restart docker
로그 크기 제한:
• max-size로 개별 로그 파일 크기 제한(10m, 50m 등)
• max-file로 보관 파일 수 제한(3, 5 등)
• 제한을 넘으면 오래된 로그 자동 삭제
Docker 로그 정리의 모범 사례는 무엇인가요?
• 로그 로테이션을 설정하고 로그 크기 제한
• 적절한 로그 드라이버 사용
• 오래된 로그 정기 정리: docker system prune
• 디스크 사용량 모니터링 및 알림 설정
• 새로 배포한 컨테이너에서 설정이 빠지지 않도록 로그 설정 정기 점검
핵심은 한 문장입니다. 미리 설정하고 정기적으로 점검하며, 디스크가 가득 찬 뒤에야 수습하지 마세요. docker inspect로 모든 컨테이너에 로그 제한이 적용됐는지 확인하세요. 새벽에 알림 때문에 잠에서 깬 뒤에야 이 문제를 깨닫지 마세요.
4분 읽기 · 게시일: 2025년 12월 18일 · 수정일: 2026년 9월 4일
Docker 실전 가이드
검색으로 들어왔다면 같은 시리즈의 이전 글이나 다음 글로 이동하는 것이 가장 빠릅니다.
이전
Docker logs 명령어 완벽 가이드: 컨테이너 문제를 빠르게 찾는 7가지 팁
실시간 확인, 시간 필터링, grep 검색, 로그 파일 위치, 운영 환경 모범 사례까지 docker logs 명령어의 실용적인 7가지 팁을 자세히 알아보고 컨테이너 문제를 빠르게 진단합니다.
33편 중 29편
다음
Docker 컨테이너 디버깅 가이드: exec 명령으로 컨테이너에 들어가 문제를 해결하는 올바른 방법
docker exec 명령으로 컨테이너에 들어가 디버깅하는 올바른 방법을 설명합니다. exec와 attach의 차이, 도구 설치 요령, 사용자 권한 지정 등 실무 시나리오와 전체 명령 예제로 컨테이너 문제를 빠르게 해결해 보세요.
33편 중 31편



댓글
GitHub로 로그인하여 댓글을 남기세요