[IT]/Docker

[Docker][Volume] 도커 데이터 저장 / Volume Mount vs Bind Mount 비교하기

ee2ee2 2022. 6. 9. 13:44
728x90
반응형

Docker의 Storage 부분을 공부하다가 Volume과 Bind Mount가 헷갈려 정리하기 위해 적는 글 입니다.

혹시 틀린 부분이 있다면 지적해주시면 감사하겠습니다 : )


 

Docker 컨테이너에 쓰여지는 데이터는 기본적으로 컨테이너가 삭제될 때 같이 삭제된다. Docker 컨테이너 특성상 삭제하고 생성하는 일이 잦기 때문에 많은 어플리케이션은 컨테이너 주기와 상관없이 데이터를 영속적으로 저장할 필요가 있다. 혹은, 여러 개의 Docker 컨테이너가 하나의 저장 공간을 공유해서 데이터를 읽거나 쓸 수 도 있다.

따라서, Docker의 컨테이너 생명 주기와 관계없이 데이터를 영속적으로 저장할 수 있도록 Docker는 아래 2가지 옵션을 제공한다.

  1.  Volume (볼륨)
  2.  Bind Mount (바인드 마운트)

출처 : https://docs.docker.com/storage/

가장 큰 차이는 데이터가 어디에 저장되는가! 이다. 아래 내용을 살펴보자.


1. Volume (볼륨)

- Docker에서 생성/삭제 등 완전히 관리

- Docker engine을 통해 사용할 수 있는 볼륨을 생성하여 사용함 (명칭 및 폴더 지정 가능 / docker volume create 로 생성)

- 실제 생성된 볼륨은 Host의 /var/lib/docker/volumes 하위에 볼륨 이름의 경로를 생성하여 저장 (Docker Host의 디렉토리에 저장됨 -> Host와는 분리)

- 여러 컨테이너에 동시에 마운트할 수 있음

출처 : https://docs.docker.com/storage/volumes/

 

volume 생성하기

$ docker volume create myvol
myvol

 

volume 조회하기

$ docker volume ls
DRIVER    VOLUME NAME
local     myvol

 

volume 상세 정보 조회

 : Mountpoint가 /var/lib/docker/volumes 폴더 하위에 본인이 생성한 볼륨명/_data인 것을 확인할 수 있다.

$ docker volume inspect myvol
[
    {
        "CreatedAt": "2022-06-08T17:00:47+09:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvol/_data",
        "Name": "myvol",
        "Options": {},
        "Scope": "local"
    }
]

 

/var/lib/docker/volumes/myvol/_data 경로 확인하기

: 현재 아무 파일도 존재하지 않음

$ ls /var/lib/docker/volumes/myvol/_data

 

volume을 컨테이너에 마운트하기

컨테이너가 볼륨을 사용하기 위해서는 볼륨을 컨테이너에 마운트해주는 과정이 필요하다. (연결시켜준다고 이해하면 된다.)

docker run 커맨트로 컨테이너를 실행할 때 -v 옵션을 통해 mount한다. 콜론(:)을 사용하여 앞에는 마운트할 볼륨명 / 뒤에는 컨테이너 내의 경로를 명시하면 된다.

아래는 myvol 볼륨을 test 컨테이너의 /app 경로에 마운트 한 것이다.

(이런 방식으로 컨테이너명만 바꿔서 컨테이너를 생성하면, 여러 개의 컨테이너가 하나의 볼륨을 공유하게 된다.) 

$ docker run -v myvol:/app --name test busybox touch /app/test.txt
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
19d511225f94: Pull complete
Digest: sha256:3614ca5eacf0a3a1bcc361c939202a974b4902b9334ff36eb29ffe9011aaad83
Status: Downloaded newer image for busybox:latest

 

touch /app/test.txt 명령어를 통해 myvol 볼륨의 경로에 파일이 생성됐는지 확인해본다.

(* touch 명령어는 리눅스에서 파일의 생성과 갱신하는 명령어이다.)

/var/lib/docker/volumes/myvol/_data 경로 확인하기

$ ls /var/lib/docker/volumes/myvol/_data
test.txt

 

생성한 test container 상세 정보 조회

myvol 볼륨이 volume 타입으로 마운트되어있는 것을 확인할 수 있다.

$ docker inspect test

..생략
        "Mounts": [
            {
                "Type": "volume",
                "Name": "myvol",
                "Source": "/var/lib/docker/volumes/myvol/_data",
                "Destination": "/app",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],

 

volume 삭제하기

$ docker volume rm myvol
Error response from daemon: remove myvol: volume is in use - [96b4190169ad8cd341b18a39e072598db39140862f85cbcdfb706bf6f986b1c6, 7ae45fe80e112f666c3dc13d41c7ab415e41a1ea5e8b110d8f92a265a781c505]

볼륨은 바로 지워지지 않는다. 에러 내용을 보면 사용중인 볼륨이라고 뜬다.

해당 볼륨이 마운트되어있는 모든 컨테이너는 삭제하고, 볼륨을 삭제하면 정상적으로 삭제된다.

$ docker rm -f test test1
test
test1

$ docker volume rm myvol
myvol

 

마운트되어있지 않은 놀고있는 모든 volume 삭제하기

prune 은 마운트되어 있지 않은 모든 볼륨을 한 번에 삭제할 수 있다.

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

2. Bind Mount (바인드 마운트)

- Volume과 다르게 호스트 파일 시스템의 특정 경로를 컨테이너로 바로 마운트

- 사용 방법은 docker run 커맨드 실행 시, -v 옵션으로 콜론(:) 앞 부분에 마운트명 대신에 호스트의 경로를 지정해줌

- Host의 File System 디렉토리 구조에 의존적

- Docker CLI 명령어로 Bind Mount 관리 불가

출처 : https://docs.docker.com/storage/bind-mounts/

 

Bind Mount 실습에 사용될 파일 생성

: 현재 경로(/test) 에 test.txt 파일 생성

$ mkdir test # 테스트할 폴더 생성

$ cd test/	 # 기존에 빈 폴더
$ ls

$ touch test.txt	#test.txt 파일 생성
$ ls
test.txt

바인드 마운트를 통한 컨테이너 생성

: 해당 호스트 경로를 컨테이너의 /app 경로에 마운트하여 터미널로 /app 경로 확인하면 test.txt 파일이 컨테이너의 /app 경로에도 존재하는 것을 확인할 수 있다.

 

생성한 컨테이너의 /app 경로에서 파일 생성하기

/ # touch /app/test2.txt
/ # ls /app
test.txt   test2.txt
/ # exit

호스트 경로에서 파일 확인

: 컨테이너의 /app 경로상에서 생성한 test2.txt 파일이 호스트의 현재경로에도 보이는 것을 확인할 수 있음.

 

컨테이너 상세 정보 확인하기

 : 해당 컨테이너의 상세 정보 확인해보면 현재 경로("/home/loginid/test")가 bind type으로 마운트되어 있을 것을 확인 할 수 있음 

 $ docker inspect test
 ..생략
 "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/loginid/test",
                "Destination": "/app",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

Volume(볼륨) vs Bind Mount (바인드 마운트)

볼륨과 바인드 마운트의 가장 큰 차이는 Docker가 해당 마운트 포인트를 관리하는지/안하는지 이다. 볼륨의 경우 생성 및 삭제를 사용자가 해야한다는 불편함도 있지만, 이미지/컨테이너 등과 같이 관리가 가능한 이점도 있어 대부분의 상황에서는 볼륨을 사용하는 것이 권장된다. 

볼륨의 장점으로는?

  • 바인드 마운트보다 백업 또는 마이그레이션이 쉽다.
  • CLI 명령이나 Docker API를 사용해 관리할 수 있다.
  • OS에 구애받지 않는다.
  • 여러 Container간에 데이터를 안전하게 공유할 수 있다.
  • 볼륨 드라이버를 사용하면 볼륨의 내용을 암호화하거나 다른 기능을 추가할 수 있다.
  • Container의 용량을 늘리지 않고 데이터를 저장할 수 있다.

3. tmpfs mount (tmpfs 마운트)

임시 데이터이며, host의 메모리에서만 지속된다. 컨테이너가 중지되면 tmpfs 마운트가 제거되고, Memory에 작성된 파일 또한 제거된다. 또한, 컨테이너간 공유가 불가하다.

출처 : https://docs.docker.com/storage/tmpfs/


참고 사이트