Docker로 애플리케이션을 배포하여 서비스를 운영 중인 Linux 서버에 디스크 용량이 부족하다는 오류나 경고 메시지가 발생한 경험이 있으신가요? 실제 애플리케이션에 의해 생성되어 저장되는 데이터 및 로그가 차지하는 용량은 그렇게 많지 않은데, 시스템 전체 스토리지 용량이 Full 될 수 있습니다.
왜 그런 것일까요?
Docker를 사용할 때 스토리지 용량이 부족해지는 원인은 여러 가지가 있을 수 있습니다.
그중 가장 많이 발생하는 것으로 Docker 컨테이너 로그가 원인일 수 있습니다.
이번 포스트에서는 잘 못 설정하면 시스템의 디스크 용량 부족으로 이어지는 Docker의 로깅 드라이버에 대해 알아보겠습니다.
Docker 로깅 드라이버 및 로그 위치
Docker에는 실행 중인 컨테이너 및 서비스에서 정보를 얻는 데 도움이 되는 여러 로깅 메커니즘이 포함되어 있습니다. 이러한 메커니즘을 로깅 드라이버라고 합니다.
docker logs
명령은 실행 중인 컨테이너가 기록한 정보를 보여줍니다. docker service logs
명령은 서비스에 참여하는 모든 컨테이너가 기록한 정보를 보여줍니다.
기본적으로 Docker는 모든 컨테이너 로그의 표준 출력(stdout
) 또는 표준 에러(stderr
)를 캡처하여 JSON 형식으로 파일에 기록하는 json-file
로깅 드라이버를 사용합니다.
docker run
또는 docker-compose up
명령어로 Docker 컨테이너를 실행하면 /var/lib/docker/containers/[Container-ID]/[Container-ID]-json.log
파일이 생성되고 로그가 기록됩니다.
기본적으로 json-file
로깅 드라이버는 로그 로테이션(log-rotation)을 수행하지 않습니다. 결과적으로 이 로깅 드라이버에 의해 저장된 로그 파일은 많은 양의 출력을 생성하는 컨테이너이면 상당한 양의 디스크 공간을 사용할 수 있으며, 이로 인해 디스크 공간이 고갈될 수 있습니다.
Docker는 Docker의 이전 버전과의 호환성을 유지하고 Docker가 Kubernetes의 런타임으로 사용되는 상황을 위해
json-file
로깅 드라이버(로그 로테이션 없이)를 기본값으로 유지합니다.
Docker 컨테이너 로그 크기 줄이기
docker rm
또는 docker-compose down
명령어를 실행하면 Docker 컨테이너가 삭제되는데, 이때 /var/lib/docker/containers
하위에 [Container-ID]
에 해당하는 디렉터리도 삭제됩니다. 이렇게 하면 많은 디스크 공간을 차지했던 [Container-ID]-json.log
파일도 같이 삭제되기 때문에 시스템 전체 디스크 공간을 확보할 수 있습니다.
야간에 서비스 중인 Docker 컨테이너를 삭제한 후 재실행하여 디스크 공간을 늘릴 수 있습니다. 좋은 방법일까요?
truncate -s 0 <json-log-file>
명령을 실행하면 로그 파일 크기를 0
으로 만들 수 있습니다.
$ cd /var/lib/docker/containers/0707f472977c3e18ea9dbaa2a015d8f4106c5720aa4314fcbf5fda3cc5208cef
$ truncate -s 0 0707f472977c3e18ea9dbaa2a015d8f4106c5720aa4314fcbf5fda3cc5208cef-json.log
$ ls -al
total 44
drwx--x--- 4 root root 4096 Nov 21 12:44 .
drwx--x--- 8 root root 4096 Nov 21 15:21 ..
-rw-r----- 1 root root 0 Nov 21 15:35 0707f472977c3e18ea9dbaa2a015d8f4106c5720aa4314fcbf5fda3cc5208cef-json.log
drwx------ 2 root root 4096 Nov 21 12:44 checkpoints
-rw------- 1 root root 4423 Nov 21 12:44 config.v2.json
-rw-r--r-- 1 root root 1593 Nov 21 12:44 hostconfig.json
-rw-r--r-- 1 root root 13 Nov 21 12:44 hostname
-rw-r--r-- 1 root root 173 Nov 21 12:44 hosts
drwx--x--- 2 root root 4096 Nov 21 12:44 mounts
-rw-r--r-- 1 root root 92 Nov 21 12:44 resolv.conf
-rw-r--r-- 1 root root 71 Nov 21 12:44 resolv.conf.hash
위와 같은 명령어를 실행하는 Crontab을 설정하여 로그 파일 크기를 줄일 수도 있으나, 가장 좋은 방법은 로그 로테이션을 설정하는 것입니다.
로그 로테이션 설정
로그 파일의 최대 크기(max-size
)와 최대 파일 개수(max-file
)를 지정하여 로그 로테이션을 활성화할 수 있습니다. 파일의 크기가 설정한 최댓값에 도달하면 새로운 파일로 교체되고, 기존 파일은 ...-json.log.1
, ...-json.log.2
, ...으로 최대 개수까지 로그 파일이 생성되고 초과하면 가장 오래된 파일이 제거되어 Docker 컨테이너의 로그 파일 크기가 무한정 커지는 것을 방지할 수 있습니다.
기본 로깅 드라이버 구성으로 설정
특정 로깅 드라이버 및 옵션으로 Docker 데몬을 구성하면 이 기본값이 생성되는 모든 컨테이너에 적용됩니다.
/etc/docker
디렉터리의 daemon.json
파일을 편집합니다. (파일이 없으면 생성합니다.)
sudo vi /etc/docker/daemon.json
아래와 같이 작성하고 저장합니다.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "10"
}
}
Docker를 재시작하면 새로 생성되는 컨테이너에 변경사항이 적용됩니다.
sudo systemctl restart docker
기존 컨테이너에는 변경사항이 적용되지 않습니다.