Docker Mount Volume 용량 초과 이슈
글을 작성하기에 앞서 해당 이슈를 제기해준 동료이자 선배인 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