MLOPS/docker

Docker Mount Volume 용량 초과 이슈

개발허재 2023. 10. 26. 22:09
더보기

글을 작성하기에 앞서 해당 이슈를 제기해준 동료이자 선배인 Lee에게 감사의 말씀을 드립니다...🙇‍♂️

 

Docker 컨테이너에 NAS 또는 local file system 마운트하면서 팀 내에서 ML 모델 개발을 하고 있었습니다.

NAS 크기가 7~800 테라바이트 수준이어서 크게 신경안썼는데 어느 순간 생각치도 못한 크기의 디스크 공간을 차지하면서 실제 사용공간보다 더 많은 공간을 차지하고 있었습니다. 

 

root@C1-L-APOLLO-GPU-001:~# df -h
Filesystem                                      Size  Used Avail Use% Mounted on
udev                                            378G     0  378G   0% /dev
tmpfs                                            76G  3.4M   76G   1% /run
/dev/mapper/C1--L--APOLLO--GPU--001--vg-root   1006G  618G  337G  65% /
tmpfs                                           378G  108K  378G   1% /dev/shm
tmpfs                                           5.0M     0  5.0M   0% /run/lock
tmpfs                                           378G     0  378G   0% /sys/fs/cgroup
/dev/loop0                                       64M   64M     0 100% /snap/core20/1974
/dev/loop2                                      102M  102M     0 100% /snap/conjure-up/1062
/dev/loop10                                     115M  115M     0 100% /snap/multipass/10150
/dev/loop11                                      56M   56M     0 100% /snap/core18/2785
/dev/loop4                                      161M  161M     0 100% /snap/conjure-up/1061
/dev/loop8                                      115M  115M     0 100% /snap/multipass/10167
/dev/sda2                                       722M   85M  600M  13% /boot
/dev/sda1                                       512M  3.4M  508M   1% /boot/efi
/dev/mapper/vgdata-lvdata                       4.3T  4.2T     0 100% /data
tmpfs                                            76G   24K   76G   1% /run/user/115
tmpfs                                            76G     0   76G   0% /run/user/0
10.70.191.16:/data                               98T  5.4T   88T   6% /data/bigdata_fs
/dev/loop12                                      74M   74M     0 100% /snap/core22/858
/dev/loop5                                       56M   56M     0 100% /snap/core18/2790
/dev/loop7                                       64M   64M     0 100% /snap/core20/2015
bigdata-nas-3.wehago.com:/ifs/data/nfs/data/DS  649T  282T  353T  45% /nas_folders/superbook
bigdata-nas-3.wehago.com:/ifs/data/nfs/DS       649T  282T  353T  45% /eachgpu-nas

NAS를 Host의 /eachgpu-nas 경로에 마운트하고 Docker 볼륨을 마운트하면서 쓰고 있었습니다.

 

Trash

Docker Volume은 컨테이너 내부에 사용되는 파일들이 저장되는 장소인데 휴지통의 개념을 가지고 있어 파일 삭제 시 바로 삭제되지 않고 .Trash 디렉토리로 옮겨지게 됩니다.

휴지통에 있는 파일 때문에 실제 사용하는 파일 용량보다 Volume의 용량이 더 큰 경우가 있습니다.

해당 디렉토리안에 파일을 지워서 용량을 확보 할 수 있습니다.

 

root@C1-L-APOLLO-GPU-001:~# du -sh /eachgpu-nas/.Trash-0/

651G	/eachgpu-nas/.Trash-0/

 

아니나 다를까 .Trash 디렉토리가 651G 나 차지하고 있었습니다.

따라서, 해당 디렉토리 내의 파일들을 한번 삭제해주는 작업을 진행해줍니다.

위 작업을 해줌으로, 불필요한 공간의 차지를 막을 수 있게 되었습니다.

 

또한, Daily Clean UP 같은 cron 자동화 작업을 통해 지속적으로 비워줄 수도 있을 것으로 보입니다.

 

 

이외에도 여러 Docker의 용량을 정리하는 방법이 아래와 같이 있습니다.

Docker의 현재 용량 확인

아래 명령어로 Docker의 root 디렉토리 위치 확인 후 해당 위치에서 du -hs * 명령어로 어떤 디렉토리가 용량이 큰지 확인합니다.

docker info | grep "Docker Root Dir"
 

Overlay2 용량이 큰 경우

아래 명령어를 통해서 용량이 많은 컨테이너 디렉토리를 확인 후 해당 디렉토리들을 삭제합니다. /diff/tmp 디렉토리는 백업과 같은 역할을 수행하기 위한 용도입니다.

du -sh */diff/tmp |sort -nr
 

 

Volumes 용량이 큰 경우

Docker Volume은 컨테이너 내부에 사용되는 파일들이 저장되는 장소인데 휴지통의 개념을 가지고 있어 파일 삭제 시 바로 삭제되지 않고 .Trash 디렉토리로 옮겨지게 됩니다.  휴지통에 있는 파일 때문에 실제 사용하는 파일 용량보다 Volume의 용량이 더 큰 경우가 있습니다.

해당 디렉토리안에 파일을 지워서 용량을 확보 할 수 있습니다.

image 용량이 큰 경우

Prune 사용

로컬 환경에 Docker를 계속 사용하다보면 컨테이너, 이미지, 볼륨, 네트워크 등 여러가지 오브젝트들이 시스템에 쌓여 디스크를 차지하게 됩니다. Prune명령어가 Docker의 garbage collection의 역할을 하여 사용하지 않는 오브젝트들을 간편하게 삭제 할 수 있습니다.

docker container prune : 중지된 모든 컨테이너 삭제
docker image prune : 사용하지 않는 이미지 삭제(dangling images)
docker volume prune : 컨테이너와 연결되지 않은 모든 볼륨 삭제
docker network prune : 컨테이너와 연결되지 않은 모든 네트워크 삭제
docker system prune -a : 위에 명령어를 통합해서 한번에 실행. 사용하지 않는 모든 오브젝트를 삭제
 

Filter 옵션

Prune에는 filter 옵션을 주어서 삭제 대상을 필터링 할 수 있습니다. filtering 할 수 있는 key 옵션은 두가지가 있습니다.

  • until (<timestamp>) : 지정된 타임스탬프 전에 생성된 컨테이너만 제거합니다.
  • label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) : 지정된 라벨이 있는 컨테이너만 혹인 지정된 라벨이 있는 컨테이너를 제외하고 제거합니다.

Daily Clean UP 설정

 

간단하게 Crontab에 docker prune 명령어를 등록하여 매일 정리를 할 수 있습니다.

//docker-prune 생성
cd /etc/cron.daily
sudo nano docker-prune

//docker-prune 내용 입력
#!/bin/bash
docker system prune -af  --filter "until=$((30*24))h"

//docker-prune 권한 설정
sudo chmod +x /etc/cron.daily/docker-prune

 

참고사항

Prune 명령어와 rm 명령의 차이점

실행 결과로는 큰 차이는 없어 보입니다. 다만 rm 명령과 비교했을 경우 Docker Container prune의 특징이 있습니다.

  • filter 옵션을 사용할 수 있습니다.
  • 데몬에서 동시실행을 차단하는 보호 장치가 있습니다.
  • 실행중인 컨테이너에 대해서는 처음부터 제외하고 중지된 컨테이너 대상으로만 동작합니다. 그렇기에 실행중인 컨테이너를 중지하고 삭제를 해달라는 등의 불필요한 로그가 발생하지 않습니다.
  • 총 얼마의 공간을 정리했는지에 대한 텍스트 형식의 보고서 제공 (Total reclaimed space: 10GB)
  • 명령어가 짧습니다. ( docker image prune -a VS docker rmi $(docker images -f dangling=true -q)

 

Reference

https://confluence.curvc.com/pages/releaseview.action?pageId=109642597