Docker Volume

Table of contents

  1. 컨테이너의 기본 UpperDir 위치 확인하기
  2. 도커 마운트 타입
    1. bind mount
    2. volume
      1. 볼륨 자동 생성
      2. named volume 생성
      3. 볼륨 컨테이너 사용하기
    3. tmpfs

컨테이너 내에서 생성 또는 변경된 모든 파일은 Read-Write 가능한 Container Layer 에 저장된다. 도커는 Copy-on-write (CoW) 방식으로 파일을 관리한다.
컨테이너가 삭제되면, 데이터가 영구적으로 유지되지 않기 때문에 다른 프로세스나 컨테이너가 해당 데이터를 필요로 하는 경우 사용할 수 없게 된다. 이 때문에 Volume 즉, 영구적인 저장소가 필요하다.

컨테이너의 기본 UpperDir 위치 확인하기

// testos 컨테이너 생성
root@docker1:~# docker container run -itd --name=testos centos
6f415171cba166d01d5bcfb918d2c2e19829424960507e3dd7930ba3761e1718
root@docker1:~#

// grep 조회
root@docker1:~# docker container inspect testos | grep -C2 UpperDir
                "LowerDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af8                        1-init/diff:/var/lib/docker/overlay2/94606eea6540dbe5a3f3a03aa3fe4977ac7fcdf1aeba8e1a346cc88209df2bc5/diff",
                "MergedDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af                        81/merged",
                "UpperDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af8                        1/diff",
                "WorkDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81                        /work"
            },
root@docker1:~# docker container inspect testos | grep -C2 UpperDir
                "LowerDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81-init/diff:/var/lib/docker/overlay2/94606eea6540dbe5a3f3a03aa3fe4977ac7fcdf1aeba8e1a346cc88209df2bc5/diff",
                "MergedDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/merged",
                "UpperDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/diff",
                "WorkDir": "/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/work"
            },
root@docker1:~#

//  호스트에서 UpperDir 경로 조회 및 파일 생성
root@docker1:~# cd /var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/diff
root@docker1:/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/diff# touch containerfile
root@docker1:/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/diff# ll
total 8
drwxr-xr-x 2 root root 4096 Jan  8 12:57 ./
drwx--x--- 5 root root 4096 Jan  8 12:56 ../
-rw-r--r-- 1 root root    0 Jan  8 12:57 containerfile
root@docker1:/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f

// testos 컨테이너에서 파일 생성 확인
root@docker1:/var/lib/docker/overlay2/180352a45d8b916b4c541a2cbd908ff372e9bb4ab3e0c880b476f43fd429af81/diff# docker container exec testos /bin/ls -l containerfile
-rw-r--r-- 1 root root 0 Jan  8 12:57 containerfile

도커 마운트 타입

[Docker Mount Type]

bind mount

도커 초기에 사용하던 방식이며, 호스트 싯스템의 전체 경로를 통해 참조됨에 따라 호스트 시스템의 File System 디렉터리 구조에 의존적이다.

root@docker1:~# mkdir /tmp/hostdir
root@docker1:~# mkdir /tmp/readonly
root@docker1:~# echo writable > /tmp/hostdir/file1
root@docker1:~# echo readonly > /tmp/readonly/file2

// container_dir 는 기본, read_dir 는 read only 로 설정한다.
root@docker1:~# docker container run -it -v /tmp/hostdir:/container_dir -v /tmp/readonly:/read_dir:ro --name test01 centos

// 컨테이너에 바인딩 확인
[root@9dc954f8a1fa /]# cat /container_dir/file1
writable
[root@9dc954f8a1fa /]# cat /read_dir/file2
readonly

// 컨테이너 내 container_dir 폴더에 쓰기 가능
[root@9dc954f8a1fa /]# echo Hello, file1 > /container_dir/file1
[root@9dc954f8a1fa /]# cat /container_dir/file1
Hello, file1

// 컨테이너 내 read_dir 폴더에 쓰기 불가
[root@9dc954f8a1fa /]# echo Hello, file2 > /read_dir/file2
bash: /read_dir/file2: Read-only file system
[root@9dc954f8a1fa /]# echo Hello, file3 > /read_dir/file3
bash: /read_dir/file3: Read-only file system
[root@9dc954f8a1fa /]# echo Hello, file3 > /container_dir/file3
[root@9dc954f8a1fa /]# echo Hello, file4 > /file4
[root@9dc954f8a1fa /]# exit
exit
root@docker1:~# docker container rm test01
test01

// 컨테이너에서 작성한 file3 바인딩 확인
root@docker1:~# ls /tmp/hostdir
file1  file3
root@docker1:~# ls /tmp/readonly
file2

컨테이너의 바인딩 정보는 docker container inspect 에서 Mounts 키워드로 확인할 수 있다.

root@docker1:~# docker container run -it -v /tmp/hostdir:/container_dir -v /tmp/readonly:/read_dir:ro --name test01 centos
[root@6c8284413747 /]# root@docker1:~#
root@docker1:~# docker container inspect test01 | grep -A 20 Mounts
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/tmp/hostdir",
                "Destination": "/container_dir",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/tmp/readonly",
                "Destination": "/read_dir",
                "Mode": "ro", // read-only
                "RW": false,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "6c8284413747",
            "Domainname": "",

volume

docker voulme create 명령을 통해서 미리 생성되거나 컨테이너가 생성될 때 생성된 볼륨을 컨테이너에 마운트해서 사용가능하다.
볼륨의 기본 경로는 /var/lib/docker/volumns/ 에 위치하며 컨테이너가 삭제/정지 되더라도 지워지지 않는다. 삭제시에는 docker volume rm 을 통해 삭제 가능하다.
volume 마운트 타입 구성 방법에는 아래와 같이 3가지가 있다.

볼륨 자동 생성

-v 옵션으로 컨테이너 생성 시 자동 생성되면 이름이 길어 식별하기 어렵다.

root@docker1:~# docker container run -it -v /volume --name test02 centos

 // 컨테이너 /volume 에 passwd 파일 붙여넣기
[root@3d88f4ab4eaa /]# ls /volume/
[root@3d88f4ab4eaa /]# cp /etc/passwd /volume
[root@3d88f4ab4eaa /]# ls /volume/
passwd
[root@3d88f4ab4eaa /]#

// detach 모드로 전환
[root@3d88f4ab4eaa /]# root@docker1:~#

// volume 정보 조회
root@docker1:~# docker volume ls
DRIVER    VOLUME NAME
local     fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d
root@docker1:~#

// volume 상세 정보 조회
root@docker1:~# docker volume inspect fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d
[
    {
        "CreatedAt": "2023-01-08T13:39:29Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d/_data",
        "Name": "fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d",
        "Options": null,
        "Scope": "local"
    }
]

// 호스트에서의 volume 데이터 확인
root@docker1:~# ls /var/lib/docker/volumes/fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d/_data
passwd

// 컨테이너 마운트 정보 조회
root@docker1:~# docker container inspect test02 | grep -A 10 Mounts
        "Mounts": [
            {
                "Type": "volume",
                "Name": "fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d",
                "Source": "/var/lib/docker/volumes/fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d/_data",
                "Destination": "/volume",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }

named volume 생성

여러 컨테이너 간에 볼륨을 보다 안전하게 공유할 수 있으며 암호화 가능하다. 컨텐츠를 사전에 채워 놓을 수 있다.

root@docker1:~# docker volume ls
DRIVER    VOLUME NAME
local     fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d
root@docker1:~#

// persistvol 볼륨 생성
volume  create persistvol
persistvol
root@docker1:~# docker volume ls
DRIVER    VOLUME NAME
local     fba67fc43867c48a032bd2f778857feeb48cf3f79e8d2b1ff15b83edda28853d
local     persistvol

// persistvol 볼륨 상세 조회
root@docker1:~# docker volume inspect persistvol
[
    {
        "CreatedAt": "2023-01-08T13:52:07Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/persistvol/_data",
        "Name": "persistvol",
        "Options": {},
        "Scope": "local"
    }
]

// persistvol 볼륨을 참조하는 vol_container 컨테이너 생성
root@docker1:~# docker container run -it --name vol_container -v persistvol:/container  centos
[root@7ccd49ed19a5 /]# ls /container
[root@7ccd49ed19a5 /]# echo Hello, a > /container/a
[root@7ccd49ed19a5 /]# ls /container
a
[root@7ccd49ed19a5 /]# root@docker1:~#
root@docker1:~#

볼륨 컨테이너 사용하기

-v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유할 수 있다. 컨테이너 생성 시 --volumes-from 옵션을 설정하면 -v 옵션을 적용한 컨테이너의 볼륨 디렉토리를 공유할 수 있다. 또한 볼륨 컨테이너가 꺼져 있어도 사용할 수 있다.

// vol_container 컨테이너의 볼륨을 참조하는 data_container 컨테이너 생성 
root@docker1:~# docker container run -it --volumes-from vol_container --name data_container centos

// 동일 데이터 확인
[root@41f2f04a995d /]# cat /container/a
Hello, a
[root@41f2f04a995d /]# echo Hello, yumi > /container/a
[root@41f2f04a995d /]# cat /container/a
Hello, yumi
[root@41f2f04a995d /]# root@docker1:~#

// data_container 가 참조하는 볼륨 상세 조회
root@docker1:~# docker container inspect data_container | grep -A 10 Mounts
        "Mounts": [
            {
                "Type": "volume",
                "Name": "persistvol",
                "Source": "/var/lib/docker/volumes/persistvol/_data",
                "Destination": "/container",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
root@docker1:~#

tmpfs

호스트의 메모리 공간에 저장되기 때문에 컨테이너 정지 시 삭제되나, 빠른 I/O 목적으로 할 경우에는 장점이 된다.