볼륨(volume) 마운트란?
만약 도커로 데이터베이스 컨테이너를 실행해 애플리케이션을 구동한다 했을 때 해당 데이터베이스 컨테이너가 삭제된다면 데이터도 삭제가 되고 복구할 수 없게 된다.
이런 경우에 데이터를 유지를 위한 몇 가지 방법이 있는데 그중 가장 활용하기 쉬운 방법이 볼륨이다.
불륨 마운트란, 도커가 생성하고 관리하는 방식이다. 볼륨을 생성하면 자동으로 아래의 경로에 볼륨이 마운트 되어진다.
(즉, 볼륨 마운트는 아래의 경로에 볼륨이 생성되고 해당 볼륨을 도커와 연결시켜 관리하는 것이다.)
/var/lib/docker/volumes/
볼륨 생성 및 조회
docker volume create [볼륨 이름] 으로 볼륨을 하나 생성합니다.
$ docker volume create our-vol
our-vol
또는, 컨테이너 생성 시, -v [docker volume 이름]:[컨테이너 내부에서 사용할 경로] 를 통해 컨테이너 생성과 동시에 볼륨을 생성및 할당을 해줄 수 있다.
$ IMAGE=centos
$ CONT=myvol01
$ docker container run -it --name $CONT -v docker_vol:/cont_vol $IMAGE
Ctrl + P, Ctrl + Q를 사용하여 컨테이너를 빠져 나간 후, docker volume ls 를 통해 생성된 볼륨을 확인할 수 있다.
$ docker volume ls
DRIVER VOLUME NAME
local our-vol
docker volume inspect [볼륨] 를 통해 볼륨의 좀 더 상세한 정보를 확인할 수 있다.
$ docker volume inspect our-vol
[
{
"CreatedAt": "2020-05-09T17:03:46Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/our-vol/_data",
"Name": "our-vol",
"Options": {},
"Scope": "local"
}
]
Mountpoint를 보면 해당 볼륨이 컴퓨터의 어느 경로에 생성되었는지 알 수 있다.
볼륨을 컨테이너에 마운트 하기
컨테이너가 볼륨을 사용하기 위해서는 볼륨을 컨테이너에 마운트(mount)해줘야 한다.
docker run 커맨드로 컨테이너를 실행할 때 -v 옵션을 사용하면 된다.
콜론(:)을 구분자로 [마운트할 볼륨명]:[컨테이너 내의 경로]로 명시해주면 된다.
예를 들어, our-vol 볼륨을 one 컨테이너의 /app 경로에 마운트를 해보자.
$ docker run -v our-vol:/app --name one busybox touch /app/test.txt
touch /app/test.txt 커맨드를 실행하였기 때문에, test.txt 파일이 our-vol 볼륨의 경로에도 남아있을 것이다.
$ ls /var/lib/docker/volumes/our-vol/_data
test.txt
docker inspect 커맨드로 컨테이너의 상세 정보를 확인해보면 our-vol 볼륨이 volume 타입으로 마운트되어 있는 것을 확인할 수 있다.
$ docker inspect one
(...생략...)
"Mounts": [
{
"Type": "volume",
"Name": "our-vol",
"Source": "/var/lib/docker/volumes/our-vol/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
(...생략...)
볼륨을 다른 컨테이너에도 마운트 하기
같은 our-vol 볼륨을 two 컨테이너의 /app 경로에 마운트를 해보자.
ls /app 커맨드를 실행해보니, one 컨테이너가 볼륨에 생성해놓은 파일이 그대로 보이는 것을 알 수 있다.
$ docker run -v our-vol:/app --name two busybox ls /app
test.txt
이렇게 여러 개의 컨테이너가 하나의 볼륨에 접근할 수 있기 때문에 컨테이너 간 데이터 공유가 가능한 것이다.
다시 말해, 어떤 볼륨에 데이터를 저장해두고, 여러 컨테이너에 마운트만 해주면 해당 데이터를 모든 컨테이너에서 접근할 수 있게 된다.
볼륨 삭제
마지막으로 docker volume rm [볼륨] 을 사용하여 our-vol 볼륨을 제거해보자.
$ docker volume rm our-vol
Error response from daemon: remove our-vol: volume is in use - [f73130c9dad14644ac46b89fe4018e561a7bcbfa4118d637949642d0d5d742e4, 666dda54f6be8ca852f3150b9741a9cab5a4659fa2e83fe6ca339550072c861ex]
제거하려는 볼륨이 마운트되어 있는 컨테이너가 있을 때는 해당 볼륨이 제거가 되지가 않는다.
그럴 때는 해당 볼륨이 마운트되어 있는 모든 컨테이너를 먼저 삭제하고, 볼륨을 삭제해야 한다.
$ docker rm -f one two
one
two
$ docker volume rm our-vol
our-vol
볼륨 청소
docker 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
볼륨 이외의 마운트 방법
바인드 마운트
바인드 마운트의 경우 호스트의 로컬경로를 직접 지정하여 볼륨을 마운트하는 방식이다. 해당 방식은 도커가 아니기 때문에, 도커프로세스와 non-도커프로세스 간의 차이가 발생할 수 있기 때문에 권장하지 않는 방식이다.
바인드 마운트를 사용하는 방법은 docker run 커맨드를 실행할 때, -v 옵션의 콜론(:) 앞 부분에 마운트명 대신에 호스트의 경로를 지정해주는 것이다.
예를 들어, 현재 경로에 test.txt 파일을 생성하고, 해당 호스트 경로를 컨테이너의 /app 경로에 마운트해보자. 컨테이너에 터미널을 붙여서 ls /app 커맨드를 실행해보면 test.txt 파일이 컨테이너의 /app 경로에도 존재하는 것을 확인할 수 있다.
$ touch test.txt
$ docker run -v `pwd`:/app -it --name one busybox /bin/sh
/ # ls /app
test.txt
반대로 컨테이너의 /app 경로 상에서 test2.txt 파일을 실행해보면 호스트의 현재 경로에도 해당 파일이 보이는 것을 알 수 있다.
/ # touch /app/test2.txt
/ # exit
[node1] (local) root@192.168.0.18 ~
$ ls
test.txt test2.txt
docker inspect 커맨드로 해당 컨테이너의 상세 정보를 확인해보면 현재 경로(/root)가 bind 타입으로 마운트되어 있는 것을 확인할 수 있다.
$ docker inspect one
(...생략...)
"Mounts": [
{
"Type": "bind",
"Source": "/root",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
(...생략...)
tmfs 마운트
파일시스템 대신 메모리에 데이터를 저장하는 방식을 의미한다.(해당 방식은 리눅스 환경에서만 가능하다.)
보통 보안을 위해 비영구적으로 관리해야 하는 데이터에 많이 쓰이는 방법이다.