변경 사항을 ECS에 배포 후 발생하는 에러를 확인해보니 아래와 같은 메시지가 확인 되었습니다.
OSError: [Errno 28] No space left on device: '/usr/local/...-airflow/logs'
우선은 급하게 EBS 볼륨 10GB를 추가하고 본격적으로 원인을 찾아보았습니다.
실제 사용되는 디스크 용량을 확인해보니 루트 EBS 볼륨 블록 디바이스(/dev/nvme0n1)의 용량이 상당히 많은 양을 차지하는 것을 알 수 있었습니다.
처음에는 단순히 logfile이 많이 쌓여 발생했겠구나 싶어서 확인해보니 해당 프로젝트의 로깅 레벨은 ERROR
였고, 실제 저장되어있는 로그 파일의 용량이 매우 적은 것을 확인했습니다.
문득 도커 컨테이너 용량이 궁금해져 docker system df -v
명령어를 통해 확인해보니 아래와 같이 사용되지 않는 컨테이너가 정리되지 않고 있었습니다. (아래 사진은 당시의 결과가 아닙니다 .. 당시 캡쳐를 하지 못해 다른 사진으로 대체합니다)
💡 docker system df
: 현재 사용중인 이미지, 컨테이너 및 볼륨이 얼마나 많은 공간을 사용하고 있는지 확인할 수 있는 명령어. 뒤에 -v
(vervose)옵션을 추가하면 사용하지 않는 이미지와 컨테이너도 확인 가능
실제 컨테이너의 SIZE의 크기가 수십 KB에서 많게는 800MB 까지 정리되지 않은 컨테이너들이 많았고, 이에 볼륨(디스크)이 찼던 것이었습니다.
다행히도 빠르게 원인을 발견 할 수 있었고, 구글링을 통해 docker prune
이라는 해결방법을 찾을 수 있었습니다.
💡 docker prune
: 사용하지 않는 컨테이너 이미지를 제거하는 명령어. prune의 가장 큰 특징은 어떠한 옵션을 주는가에 따라 그 역할이 달라진다는 것
docker volume prune
: 미사용 볼륨 제거docker container prune
: 미사용 컨테이너 제거docker image prune
: 미사용 이미지 제거docker system prune
: 미사용 중인 이미지, 컨테이너, 볼륨 모두 제거우선적으로 docker systme prune
명령어를 통해 일부 용량을 확보 할 수 있었습니다.
추가적으로 재발 방지를 위해, 아래와 같이 일주일이 지난 컨테이너 및 이미지 등에 대하여 주기적으로 삭제하는 크론탭을 daily.cron에 등록하였습니다. prune 명령어에는 —-filter
옵션이 있는데 이를 잘 활용하면 운영에 큰 이점이 있습니다.
docker system prune -af --filter "until=$((7*24))h"
/var/lib/docker
내부에는 컨테이너, 볼륨, 빌드 등 다양한 정보가 저장됩니다. 여기서부터는 관리자 권한이니 sudo su
나 root 계정으로 로그인하여 진행하면 편합니다.
특히 docker/ 이하 overlay2는 기본 스토리지 드라이버이며 docker의 image가 저장되는 곳이기도 합니다. docker image는 layer 방식을 통해 관리됩니다.
💡 레이어: 기존 이미지에 추가적인 파일이 필요할 때 다시 다운로드 받는 방식이 아니라 해당 파일을 추가하기 위한 개념. 이미지는 여러 개의 읽기 전용 레이어로 구성되고, 파일이 추가되면 새로운 레이어가 생성
즉 overlay2/diff/tmp 디렉토리의 역할은 이미지의 변경 사항을 저장하고, 백업의 역할을 수행하기 위해 생긴 곳입니다. 따라서 잦은 빌드를 통해 새로운 컨테이너가 생성된다면 해당 디렉토리 내부의 용량이 커질 수도 있습니다. 따라서 이곳을 정리한다면 용량을 확보 할 수도 있습니다.
docker info
docker exec -it [container id] /bin/bash
docker run
과 비슷함. docker run
의 경우 새로운 컨테이너 환경을 만드는 반면 docker exec
는 이미 실행된 특정 컨테이너의 환경을 디버깅 하는 용도로 사용-it
옵션-i
: 표준 입출력을 사용하겠다는 의미-t
: 가상 tty를 통해 접속하겠다는 의미exit
를 통해 간단하게 빠져나올 수 있음docker ps
docker stats
—-no-stream
옵션을 추가하면 반복출력하지 않고 현 시점의 결과만 1회 출력