Featured image of post Docker Container 출력이 Disk 를 채운다

Docker Container 출력이 Disk 를 채운다

로그 (Log) 를 파일로 저장하는 Docker Daemon, 제어할 방법은?

어느 날, GCP 에서 알람이 날아왔다. 테스트로 docker container를 하나 올려 둔 VM (Compute Engine) 에서 Disk 가 꽉 차서 아무것도 할 수 없다는 것이었다.

디스크를 쓴다고? 이 container 는 mount 된 volume 도 없었고, container 가 하는 일은 소스에서 데이터를 받아 계산한 뒤 GCP Cloud Storage 에 저장하는 것 밖에 하지 않는데?

문제

Docker container 만 떠 있고 아무런 작업을 하지 않는 Host 의 디스크 사용량이 계속해서 줄어든다. 결국, 디스크를 100% 가까이 쓰게 되어 시스템을 마비시킨다.

진단

우선 해당 Host (VM 또는 on-premise) 에 접속해서 df -h 를 실행하자. / 경로에서 디스크 사용량이 압도적으로 많다면, 해당 문제에 접근한 것이다.

이제 이 부분을 실행해 보자. (root 가 아니라면, sudoer 권한이 필요하다)

sudo du -h -d 1 /var/lib/docker/containers

해당 경로에서 특정 container 의 디스크 사용량이 df -h 를 입력했을 때의 사용량과 비슷하다면, 이 친구가 문제다.

분석

그렇다면 왜 디스크를 쓰는 container 가 아닌데, 이렇게 디스크를 먹었던 것일까?

docker logs 를 입력하면 container 의 stdout/stderr 출력 내용을 볼 수 있다. 문제는, Docker daemon 은 별다른 지시가 없다면 container 가 출력하는 내용을 전부 디스크에 쓴다는 것이다.

바로 /var/lib/docker/containers 경로에 말이다!


Docker docs 페이지에도 같은 내용을 경고하고 있다.

By default, no log-rotation is performed. As a result, log-files stored by the default json-file logging driver logging driver can cause a significant amount of disk space to be used for containers that generate much output, which can lead to disk space exhaustion.

해결

container directory 를 지우는 것은, 문제를 완화하고 서비스를 잠시 정상으로 되돌려 놓을 순 있지만 진짜 해결책은 아니다.

분석에서 말한 대로, container 가 출력하는 내용을 rotation 으로 기록하도록 만들어야 한다. 즉, 최근 출력만 기억하게 하고 오래된 것은 삭제하도록 말이다.

먼저, /etc/docker/daemon.json 에 아래 내용을 넣는다. (없으면 만든다)

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

container 가 출력하는 최신 내용을 JSON 포맷으로 10MB 씩 3개의 파일로 저장하고, 오래된 내용은 없애도록 하는 것이다. 원하는 값으로 수정하거나, Docker docs 페이지 를 참고해 다양한 설정으로 바꿔줘도 무방하다.

설정이 끝났다면, Docker daemon 을 재시작한다. 나의 경우엔 sudo service docker restart 로 재시작했다.

이후 container 를 다시 실행시킨 뒤, 출력이 쌓일 때 까지 기다렸다가 /var/lib/docker/containers/ 에서 {container_id} directory 에 있는 .log 파일이 3개 생성되어 있는지 확인하면 된다.


Hugo 기반 / JimmyStack 테마를 사용 중입니다.