ocwokocw 2023. 6. 11. 22:23

출처: 시작하세요! 도커/쿠버네티스 - 도커 볼륨

 

Docker volume은 왜 필요한가?

mysql image로 container를 하나 생성했다고 가정해보자. 이 container는 Web 서버의 요청을 받아 새로운 정보를 계속 축적해나갈것이다. 즉 읽기 전용인 docker image를 기반으로 변경분이 docker container layer에 기록된다.

그런데 container를 재시작하면 어떻게 될까? 이전에 예제를 통해 확인해봐서 알겠지만 container layer의 정보는 초기화된다. 이렇게 되면 축적된 정보가 날아가게 된다. 이를 방지하기 위해 필요한것이 volume 이다.


Host volume 공유

~ % docker run -d \
--name wordpressdb_hostvolume \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
-v /Users/user/Documents/Study/docker/volume/wordpress_db:/var/lib/mysql \
arm64v8/mysql:8

~ % docker run -d \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=password \
--name wordpress_hostvolume \
--link wordpressdb_hostvolume:mysql \
-p 80 wordpress

이전과 다르게 -v option이 추가되었다. -v option은 [host directory]:[container directory] 형식이다. /var/lib/mysql은 MYSQL이 데이터베이스의 데이터를 저장하는 기본 directory이다. container를 생성하고 나면 host의 directory에 mysql 관련 파일들이 생겨난것을 확인할 수 있다.

wordpress_db % pwd
/Users/user/Documents/Study/docker/volume/wordpress_db

wordpress_db % ls -l
total 199680
-rw-r-----@   1 user  staff    196608  6 11 21:38 #ib_16384_0.dblwr
-rw-r-----@   1 user  staff   8585216  6 11 21:19 #ib_16384_1.dblwr
drwxr-x---@  34 user  staff      1088  6 11 21:36 #innodb_redo
drwxr-x---@  12 user  staff       384  6 11 21:36 #innodb_temp
...
drwxr-x---@   2 user  staff        64  6 11 21:19 wordpress

host volume 공유를 하면 container <-> host directory간에 동기화되는것이 아니라 같은 directory가 된다.


Volume container

2번째로 volume 사용 container를 다른 container와 공유하는 방법이 있다. --volumes-from [container명] option으로 생성하면 -v option을 적용한 container의 volume directory를 공유할 수 있다.

wordpress_db % docker run -d \
--name volumes_container \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
-v /Users/user/Documents/Study/docker/volume/volume_container:/var/lib/mysql \
arm64v8/mysql:8

wordpress_db % docker run -it \
--name volumes_from_container \
--volumes-from volumes_container \
ubuntu:14.04

root@3f7cfceb5c6e:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

root@3f7cfceb5c6e:/# cd var/lib/mysql/

root@3f7cfceb5c6e:/var/lib/mysql# pwd
/var/lib/mysql

root@3f7cfceb5c6e:/var/lib/mysql# ls -l
total 99828
-rw-r-----   1  999  999   196608 Jun 11 12:55 #ib_16384_0.dblwr
-rw-r-----   1  999  999  8585216 Jun 11 12:52 #ib_16384_1.dblwr
drwxr-x---  34  999  999     1088 Jun 11 12:53 #innodb_redo
drwxr-x---  12  999  999      384 Jun 11 12:53 #innodb_temp
...
drwxr-x---   2  999  999       64 Jun 11 12:52 wordpress

 

하나뿐만 아니라 여러 container가 volume container를 바라보게 할 수 있다. 이를 응용하면 특별한 역할은 하지 않고 volume 공유 역할만하는 volume container를 생성하고, --volumes-from 옵션을 생성된 container들은 간접적으로 데이터를 공유받을 수 있다.


Docker volume

3번째 방법은 docker 자체에서 제공하는 volume 기능인 docker volume 명령어를 이용하는 방법이다. docker create를 통해 myvolume volume을 생성해준다.

wordpress_db % docker volume

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.

wordpress_db % docker volume create --name myvolume
myvolume

wordpress_db % docker volume ls
DRIVER    VOLUME NAME
...
local     myvolume

docker volume을 통해 공유하려면 host volume을 사용했을때 형식과는 달리 [volume 이름]:[cotainer directory]로 사용해야 한다.

wordpress_db % docker run -it --name myvolume_1 \
> -v myvolume:/root/ \
> ubuntu:14.04

root@34329abf71c8:/# echo hello, volume! >> /root/volume

root@34329abf71c8:/# %

wordpress_db % docker run -it --name myvolume_2 \
> -v myvolume:/root/ \
> ubuntu:14.04

root@73f859dbad9e:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

root@73f859dbad9e:/# cd root

root@73f859dbad9e:~# ls
volume

root@73f859dbad9e:~# cat volume
hello, volume!

myvolme_1 container에서는 -v option에 myvolume 을 이용하였고 hello, volume! 내용의 파일을 /root/volume 파일에 썼다. 그후 동일하게 myvolume volume을 이용하여 myvolume_2 container를 생성하였다. 아무런 작업을 하지 않았는데 myvolume_1 container에서 생성한 /root/volume 파일이 존재한다.

그렇다면 myvolume은 실제로 host에서 어떤 경로에 저장되는것일까?

wordpress_db % docker inspect myvolume
[
    {
        "CreatedAt": "2023-06-11T13:15:26Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
        "Name": "myvolume",
        "Options": {},
        "Scope": "local"
    }
]
wordpress_db % ls /var/lib/docker/volumes/myvolume/_data
ls: /var/lib/docker/volumes/myvolume/_data: No such file or directory

원래 Mountpoint에 파일이 있어야 하는데 Mac은 Docker를 바로 실행시키지 않고 VM을 띄운 후 실행시키기 때문에 실제 경로는 없다. 하지만 사용자가 Mountpoint를 굳이 알 필요는 없다.