[Docker] no space left on device

2023. 11. 18. 17:43Developers 공간 [Shorts]/Software Basic

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

CONTAINER_NAME=cont1
docker cp file.txt $CONTAINER_NAME:/mnt/dataspace/
Error response from daemon : mount /mnt/dataspace:/var/lib/docker/overlay2/f736590293fj2093jf9023nf02n3f203nf0nsdhf023hf0230fh/merged/mnt/dataspace, flags: 0x5001: no space left on device

 

위와 같은 명령어로 어떤 데이터를 넣어주려고 했는데 위와 같은 에러가 납니다.

 

아래는 시스템과 docker container 별로 사용하고 있는 용량을 확인하는 명령어 입니다.

# Check system storage
df -h

 

시스템 상의 용량은 충분함에도 불구하고, 위와 같은 에러가 지속됩니다. 문제를 확인하기 위해 다양한 시도를 해보았습니다.

 


2. Why? (원인)

다양한 원인을 확인해보고자 합니다.

  1. docker 의 overlay2의 용량이 부족
  2. docker overlay2의 스토리지 상의 문제
  3. overlay2 위치의 권한 문제

3. How? (해결책)

1. docker 의 overlay2의 용량이 부족

docker는 default로 /var/lib/docker에 containers, volume, build 등 다양한 정보가 저장되는데, 특히 /var/lib/docker/overlay2에는 기본 스토리지 드라이버로, image들이 저장되는 곳입니다.

 

먼저 docker의 이미지나 다양한 정보가 많아, 시스템의 용량이 부족할 수도 있다고 생각해 확인해보았습니다. 

# Check docker usage
docker system df -v

 

실제로 docker에서 많은 용량을 차지하고 있는 것으로 확인하고, 아래와 같이 docker에서 안쓰는 볼륨, 컨테이너, 이미지를 정리해주는 명령어를 진행했습니다.

 

# Remove unused volume
docker volume prune

# Remove unused containers
docker image prune

# Remove unused images
docker image prune

# Remove All unused volume & container & images
docker system prune

# Remove All unused volume & container & images which are unused 7 days
docker system prune -af --filter "until=$((7*24))h"

 

예를 들어 docker system prune을 실행하면 다음과 같은 명령어가 실행되며 재확인 메시지가 뜹니다.

WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache

Are you sure you want to continue? [y/N]

 

이후에 결과가 아래와 같이 뜰 것 입니다.

Total reclaimed space : 7.21GB

 


2. docker overlay2의 스토리지 상의 문제

 

위를 통해 container에 필요한 데이터를 정리해도 문제가 지속되었습니다. 그래서 혹시나 docker를 관리하는 폴더가 파일시스템 상에서 malfunction하는 것은 아닐까 싶었습니다.

 

먼저 아래 명령어를 통해 각각의 용량을 확인해 보았습니다.

du -lhs /var/lib/docker/*

 

파일시스템이 이상하게 동작하는 것이라면 아예 다른 곳으로 옮겨 보면 어떨까해서 다른 위치로 이동시켜 보았습니다.

 

이 때 아래와 같이 /etc/docker/daemon.json에 data-root 항목을 추가해 위치를 변경해주겠습니다.

{
    "runetimes" : {
        "nvidia" : {
            "path" : "nvidia-container-runtime",
            "runtimeArgs" : []
        }
    },
    "data-root" : "/mnt/dockerspace"
}

 

docker를 재시작합니다.

# Restart Method1
sudo systemctl daemon-reload
sudo systemctl restart docker

# Restart Method2
sudo service docker restart
더보기

----------------------------------------------------

<systemctl과 service의 다른 점>

systemctl과 service는 같은 목적을 가진 명령어이므로 많은 공통점을 가졌지만 몇개의 다른점이 있습니다.

  • Systemctl
    • 초기화 : /lib/systemd 폴더를 활용
    • 다양한 linux 시스템에 조금 덜 호환적이다.
    • systemd와 직접적 상호작용한다.
    • 동작 범위가 더 넓습니다.
  • Service
    • 초기화 : /etc/init.d 폴더를 활용
    • 다양한 linux 시스템에 조금 더 호환적이다.
    • /etc/init.d 폴더를 통해 systemctl 명령어를 redirect합니다.
    • 동작 범위가 더 좁습니다.

----------------------------------------------------

 

다만, 위와 같이 실행을 하면 docker가 참조하던 /var/lib/docker 폴더의 컨테이너와 이미지 정보를 내가 원하는 위치에 자동으로 옮겨주지는 않습니다. 따라서 아래와 같이 직접 옮겨주면, 기존의 내용들을 유지하면서 위치를 변경할 수 있습니다.

sudo mv /var/lib/docker /mnt/dockerspace

sudo service docker restart

 


3. overlay2 위치의 권한 문제

 

위 방법으로도 해결되지 않아, 혹시 이미지를 생성하는데 있어서 /var/lib/docker/overlay2 폴더의 권한 문제는 아닐까하는 생각에 권한을 확인해보았습니다.

 

먼저 아래와 같은 다양한 명령어를 통해 나의 user와 group을 확인해봅니다.

# Check my user
lslogins 	# print all (/etc/passwd, /etc/shadow)
users 		# print all who logged in
who 		# print all who logged in
whoami 		# print me only
w			# print me only
logname 	# print me only

# Check my group
groups			# print me only (/etc/passwd, /etc/shadow)
groups $USER	# print me only (/etc/passwd, /etc/shadow)

# Check my user and group
id

 

또는 위와 다르게 /etc/passwd 파일을 확인하면 어떤 user가 어떤 group에 속해있는지 확인할 수 있습니다. 아래의 경우 tkay 계정은 1000이라는 UID(User ID)를 가지고 1000이라는 GID(Group ID)에 속해있네요.

...
root:x:0:0:root:/root:/bin/bash
tkay:x:1000:1000:tkay,,,:/home/tkay:/bin/bash
...

 

또한 /etc/sudoers 파일에서 어떤 user들이 sudo권한을 가지고 있는지 확인해주었습니다. 아래는 모든 user들이 sudo 권한을 가지게 되어있네요.

# User privilege specification
root    ALL=(ALL:ALL) ALL

 

이제 본격적으로 docker 폴더의 권한을 확인해 보겠습니다.

ls -ald /var/lib/docker
drwx--x--x 13 root root 409 11월 19 2023 /var/lib/docker/

 

위를 보면 root user와 root group으로 되어있네요. 또한, user는 read, write, executable 권한을 가지며, groupother는 executable 권한만 가지고 있네요.

** 결과에 대한 자세한 설명은(https://tkayyoo.tistory.com/148)를 참조하세요.

 

따라서 폴더 자체는 sudo 권한만 있다면 자유롭게 다룰 수 있는 것으로 보입니다.

 

그럼 docker폴더 내의 overlay2 폴더의 권한을 확인해보겠습니다.

ls -al /var/lib/docker/
...
drwx-----x 51 root root 409 11월 19 2023 overlay2
...

역시나 root user와 root group으로 되어있네요. 또한, user는 read, write, executable 권한을 가지며, group은 권한이 없으며, other는 executable 권한만 가지고 있네요.

 

역시나 sudo 권한만 있다면 자유롭게 다룰 수 있는 것으로 보입니다.

 

결과적으로 저의 user인, tkay는 sudo 권한을 가지고 있고, sudo 권한이 있다면 문제 없이 해당 폴더를 다룰 수 있는 것으로 보이므로 문제가 없어보입니다.

 

 

** 최종 결과

결국 위와 같은 과정으로 문제를 해결하지는 못했는데, 조금은 허무하지만 시스템을 reboot한 이후에 정상동작 했습니다.

 

예상하는 이유로는 초기에 df -h를 했을 때 Used+Avail=Size 가 되어야 맞지만, 이상하게 매칭이 되지 않았습니다. 

 

이는 리눅스에서 사용하는 EXT2/3/4 파일시스템에서는 disk를 max로 채우지 않고 5%정도의 여분은 남겨둔다고 합니다. 이는 메타 데이터를 저장하거나 시스템에서 사용하기 위해 남겨둡니다.

 

또한 삭제된 데이터들이 open file형태(삭제되었지만 기록은 되지않은)로 유지되기 때문에 반영이 되지 않았을 수도 있습니다.

 

따라서 실제로 용량이 시스템상 부족하게 느껴졌지만 reboot를 하면서 해당 정보들이 반영되어 충분해진 상황이 된것으로 보았습니다.


 

728x90
반응형