-
[Docker] 데이터 볼륨Docker 2019. 4. 3. 15:51
도커 컨테이너는 동일한 이미지를 기반으로 복수로 생성될 수 있는 장점이 있지만, docker commit 해서 이미지를 생성하지 않는 한 컨테이너가 종료되면 컨테이너 레이어Writable Layer의 데이터가 사라진다. 도커는 데이터를 보존하거나 컨테이너간에 데이터를 공유하기 위해 파일 시스템을 공유하는 기능을 제공한다.
호스트의 파일 시스템을 공유하는 방법
docker run 으로 컨테이너를 실행할 때 -v {HOST_DIRECTORY}:{CONTAINER_DIRECTORY} 옵션을 주면 된다. 이때 존재하지 않는 디렉토리는 자동으로 생성된다.
$ docker run -itd -v /tmp/c1:/tmp --name c1 centos 83a4c3153311e040797c82758917433630b85d3bb49bbd6b61836df446a50eea $ docker exec c1 touch /tmp/file1 $ ls /tmp/c1 file1
특정 컨테이너는 읽기 전용으로 호스트 파일 시스템에 접근하도록 할 수 있다. 동시에 여러 컨테이너의 쓰기 작업으로 인한 충돌을 방지한다. -v 옵션의 마지막에 :ro 를 추가한다.
$ docker run -itd -v /tmp/c1/:/tmp:ro --name c1-ro centos 1bbccfdb151884a537ee58c06124ed5ea0c2edef8c65a36ddddb7ca4a795cee0 $ docker exec c1-ro touch /tmp/file2 touch: cannot touch '/tmp/file2': Read-only file system
이 작업은 도커 볼륨이 자동으로 생성되는 것이 아니다.
$ docker volume ls DRIVER VOLUME NAME
컨테이너 레이어Writable Layer에 변경이 발생하지 않은 것을 확인할 수 있다.
$ docker diff c1
Type: bind 방식으로 마운트되었으며, Source(Host), Destination(Container)을 확인할 수 있다.
$ docker inspect c1 [ { ... "HostConfig": { "Binds": [ "/tmp/c1:/tmp" ], ... }, "Mounts": [ { "Type": "bind", "Source": "/tmp/c1", "Destination": "/tmp", "Mode": "", "RW": true, "Propagation": "rprivate" } ], ...
컨테이너의 /tmp 디렉토리가 호스트의 파일시스템인 것을 확인할 수 있다.
$ docker exec c1 df -h Filesystem Size Used Avail Use% Mounted on overlay 8.0G 4.4G 3.7G 55% / tmpfs 64M 0 64M 0% /dev tmpfs 241M 0 241M 0% /sys/fs/cgroup /dev/xvda1 8.0G 4.4G 3.7G 55% /tmp shm 64M 0 64M 0% /dev/shm tmpfs 241M 0 241M 0% /proc/acpi tmpfs 241M 0 241M 0% /proc/scsi tmpfs 241M 0 241M 0% /sys/firmware
호스트의 파일 시스템을 공유하는 방법은 컨테이너에서 파일이 존재하는 디렉토리를 지정한다면 호스트 디렉토리를 우선하여 컨테이너의 기존 디렉토리 파일에 접근할 수 없게 되므로 주의해야 한다.
도커 볼륨을 생성하여 공유하는 방법
마찬가지로 docker run으로 컨테이너를 실행할 때 -v {VLUME_NAME}:{CONTAINER_DIRECTORY} 옵션을 주면 된다. 이때는 해당 도커 볼륨이 존재하지 않으면 자동으로 볼륨이 생성된다.
$ docker run -itd -v vol1:/tmp --name c2 centos c5630a5d896a39e06713d973ec10409bbf6a6cf8bcd300cfda6d720f7ecb3890 $ docker exec c2 touch /tmp/file1 $ docker volume ls DRIVER VOLUME NAME local vol1 $ docker inspect vol1 [ { "CreatedAt": "2019-04-04T12:36:32Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/vol1/_data", "Name": "vol1", "Options": null, "Scope": "local" } ] $ ls /var/lib/docker/volumes/vol1/_data file1 ks-script-eC059Y yum.log
호스트의 파일 시스템을 공유하는 방법과는 반대로 컨테이너의 파일 시스템을 보존하면서 외부로 공유하게 된다. 위 작업에서 생성하지 않은 파일이 포함되어있는 것을 확인할 수 있다. 도커 볼륨이 생성되면서 컨테이너 이미지 레이어의 데이터를 그대로 도커 볼륨으로 복사한 것이다.
컨테이너 레이어Writable Layer에 변경이 작용하지 않았음을 알 수 있다.
$ docker diff c2
Type: volume 방식으로 마운트되었으며, Source(Host), Destination(Container)을 알 수 있다.
$ docker inspect c2 [ { ... "HostConfig": { "Binds": [ "vol1:/tmp" ], ... }, "Mounts": [ { "Type": "volume", "Name": "vol1", "Source": "/var/lib/docker/volumes/vol1/_data", "Destination": "/tmp", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ], ...
컨테이너의 /tmp 디렉토리가 호스트의 파일시스템인 것을 확인할 수 있다.
$ docker exec c2 df -h Filesystem Size Used Avail Use% Mounted on overlay 8.0G 4.4G 3.7G 55% / tmpfs 64M 0 64M 0% /dev tmpfs 241M 0 241M 0% /sys/fs/cgroup /dev/xvda1 8.0G 4.4G 3.7G 55% /tmp shm 64M 0 64M 0% /dev/shm tmpfs 241M 0 241M 0% /proc/acpi tmpfs 241M 0 241M 0% /proc/scsi tmpfs 241M 0 241M 0% /sys/firmware
데이터 볼륨이 자동으로 생성되는 경우
mysql 같은 데이터베이스 이미지의 경우 기본적으로 데이터 볼륨을 사용하도록 설정되어있다.
$ docker inspect mysql [ { ... "ContainerConfig": { "Volumes": { "/var/lib/mysql": {} }, ... }, "Config": { "Volumes": { "/var/lib/mysql": {} }, }, ...
자동으로 랜덤한 이름으로 볼륨이 생성된다.
$ docker run -d --name db1 -e MYSQL_ROOT_PASSWORD=1234 --name db1 mysql 03938158f03e8247d6b73d2fd97c8ef8e20d80a6f9274306cb0666e09ac38ff3 $ docker volume ls DRIVER VOLUME NAME local e4e70630a62b86a7acfd655f513ac6bf6f65589e17459fb116839021ff851b58 local vol1 $ docker inspect e4e70630a62b86a7acfd655f513ac6bf6f65589e17459fb116839021ff851b58 [ { "CreatedAt": "2019-04-04T14:16:52Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/e4e70630a62b86a7acfd655f513ac6bf6f65589e17459fb116839021ff851b58/_data", "Name": "e4e70630a62b86a7acfd655f513ac6bf6f65589e17459fb116839021ff851b58", "Options": null, "Scope": "local" } ]
'Docker' 카테고리의 다른 글
[Docker] 자체 네트워크 드라이버 (0) 2019.04.08 [Docker] Dockerfile (1) 2019.04.04 [Docker] 이미지 아카이브 (1) 2019.04.02 [Docker] 컨테이너의 구조 (1) 2019.04.02