도커 이미지로 컨테이너를 생성하면 이미지는 Read-Only 가 되며 컨테이너의 변경사항만 별도로 저장해서 각 컨테이너 정보를 보존합니다.
즉, 이미 생성된 이미지는 어떠한 경우로도 변경되지 않으며 컨테이너 계층에다가 원래 이미지에서 변경 된 파일시스템 등을 저장합니다.
만약 A라는 컨테이너를 삭제하면 컨테이너 계층에 저장돼있던 정보도 삭제됩니다.
도커 컨테이너는 생성/삭제가 매우 간단하므로 컨테이너 삭제 시 데이터를 복구할 수 없게 됩니다.
이를 방지하기 위해 컨테이너의 데이터를 영속적(Persistent) 데이터로 활용할 수 있는 방법이 몇 가지 있습니다.
1. 호스트 볼륨 공유
[root@localhost test1]# docker run -d --name hostvol_test -e MYSQL_ROOT_PASSWORD=test -e MYSQL_DATABASE=test -v /home/test1:/var/lib/mysql mysql:5.7
7e0a030d01622a2dd81ade50252cae8e2f012f2a78779e031d21c143861fc9e4
[root@localhost test1]# ll /home/test1/
합계 122944
-rw-r-----. 1 polkitd input 56 5월 24 09:56 auto.cnf
-rw-------. 1 polkitd input 1676 5월 24 09:56 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 ca.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 client-cert.pem
-rw-------. 1 polkitd input 1680 5월 24 09:56 client-key.pem
-rw-r-----. 1 polkitd input 50331648 5월 24 09:56 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 5월 24 09:56 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 5월 24 09:56 ibdata1
-rw-r-----. 1 polkitd input 12582912 5월 24 09:56 ibtmp1
drwxr-x---. 2 polkitd input 4096 5월 24 09:56 mysql
drwxr-x---. 2 polkitd input 8192 5월 24 09:56 performance_schema
-rw-------. 1 polkitd input 1680 5월 24 09:56 private_key.pem
-rw-r--r--. 1 polkitd input 452 5월 24 09:56 public_key.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 server-cert.pem
-rw-------. 1 polkitd input 1680 5월 24 09:56 server-key.pem
drwxr-x---. 2 polkitd input 8192 5월 24 09:56 sys
[root@localhost test1]# docker stop hostvol_test
hostvol_test
[root@localhost test1]# docker rm hostvol_test
hostvol_test
[root@localhost test1]# ll /home/test1/
합계 176196
-rw-r-----. 1 polkitd input 56 5월 24 09:56 auto.cnf
-rw-------. 1 polkitd input 1676 5월 24 09:56 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 ca.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 client-cert.pem
-rw-------. 1 polkitd input 1680 5월 24 09:56 client-key.pem
-rw-r-----. 1 polkitd input 694 5월 24 09:57 ib_buffer_pool
-rw-r-----. 1 polkitd input 50331648 5월 24 09:57 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 5월 24 09:56 ib_logfile1
-rw-r-----. 1 polkitd input 79691776 5월 24 09:57 ibdata1
drwxr-x---. 2 polkitd input 4096 5월 24 09:56 mysql
drwxr-x---. 2 polkitd input 8192 5월 24 09:56 performance_schema
-rw-------. 1 polkitd input 1680 5월 24 09:56 private_key.pem
-rw-r--r--. 1 polkitd input 452 5월 24 09:56 public_key.pem
-rw-r--r--. 1 polkitd input 1112 5월 24 09:56 server-cert.pem
-rw-------. 1 polkitd input 1680 5월 24 09:56 server-key.pem
drwxr-x---. 2 polkitd input 8192 5월 24 09:56 sys
drwxr-x---. 2 polkitd input 20 5월 24 09:56 test
-v 옵션을 주어 호스트의 /home/test1 디렉토리와 컨테이너의 /var/lib/mysql 을 연결, 즉 공유설정 하였습니다.
위 예시의 경우 호스트에는 /home/test1 디렉토리가 존재하지 않았으나 -v 옵션으로 공유설정 후에 디렉토리가 생성됐고 이 디렉토리에 파일이 공유되었습니다.(컨테이너의 파일이 호스트로 복사)
이후 컨테이너를 삭제한 후 호스트의 /home/test1 디렉토리 확인해보니 컨테이너는 삭제됐지만 데이터는 그대로 남아있는것을 확인할 수 있습니다.
이것은 디렉토리 끼리 동기화가 되는 것이 아닌 완전히 같은 디렉토리가 되는 것 입니다.
디렉토리 단위의 공유 뿐 아니라 단일 파일 단위의 공유도 가능하며, 동시에 여러 -v 옵션을 쓸 수 있습니다.
만약 호스트에 이미 디렉토리와 파일이 존재하고 컨테이너에도 존재할 때 두 디렉토리를 공유한다면 컨테이너의 디렉토리 자체가 덮어씌워집니다.(이미지에 원래 존재하던 파일이 없어지고 호스트에서 공유된 파일이 존재하게 됨)
즉, 호스트의 디렉토리가 컨테이너의 디렉토리에 마운트 되는 개념입니다.
2. 볼륨 컨테이너
컨테이너 생성 시 --volumes-from 옵션을 설정하면 -v 나 --volume 옵션을 적용한 컨테이너의 볼륨 디렉토리를 공유할 수 있습니다. ( 직접 볼륨을 공유하는 것이 아닌 -v 옵션을 적용한 컨테이너를 통해 공유하는 것 )
[root@localhost ~]# docker run -t -i --name test --volumes-from test1 ubuntu:18.04
위 예시는 test1 이라는 컨테이너의 볼륨 디렉토리를 공유하는 것 입니다.
3. 도커 볼륨
[root@localhost ~]# docker volume create --name myvolume
myvolume
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local myvolume
위와 같이 myvolume 이라는 볼륨을 생성하였으며 생성된 볼륨을 확인하였습니다.
[root@localhost ~]# docker run -t -i --name myvolume_1 -v myvolume:/root/ ubuntu:18.04
root@409f23977ef2:/# echo hello >> /root/volume
[root@localhost ~]# docker run -t -i --name myvolume_2 -v myvolume:/root/ ubuntu:18.04
root@fecc14532a0e:/# cd /root/
root@fecc14532a0e:~# ll
total 16
drwx------. 2 root root 72 May 24 01:38 ./
drwxr-xr-x. 1 root root 6 May 24 01:38 ../
-rw-------. 1 root root 42 May 24 01:38 .bash_history
-rw-r--r--. 1 root root 3106 Apr 9 2018 .bashrc
-rw-r--r--. 1 root root 148 Aug 17 2015 .profile
-rw-r--r--. 1 root root 6 May 24 01:38 volume
myvolume을 /root 디렉토리에 마운트했으며 /root/volume 이라는 파일이 myvolume 이라는 볼륨에 저장됩니다.
이후 myvolume_2 라는 컨테이너를 myvolume 이라는 볼륨을 써서 생성한 후 root 디렉토리 확인 시 위에서 생성했던 /root/volume 파일을 확인할 수 있습니다.
도커 볼륨도 호스트 볼륨과 마찬가지로 호스트에 저장함으로써 데이터를 보존합니다.
[root@localhost ~]# docker inspect --type volume myvolume
[
{
"CreatedAt": "2021-05-24T10:38:37+09:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
"Name": "myvolume",
"Options": {},
"Scope": "local"
}
]
위 명령으로 myvolume 이라는 볼륨이 호스트의 어느위치에 마운트 되었는지 확인할 수 있습니다.
--mount type=volume,source=myvolume,target=/root
-v 옵션을 위와같이 사용할 수도 있습니다.
--mount type=bind,source=/home/test,target=/home/test1
볼륨이 아닌 호스트의 특정 디렉토리를 컨테이너 내부에 마운트하는 경우에는 type을 bind로 하여 설정할 수 있습니다.
* stateless : 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계
* stateful : 컨테이너가 데이터를 저장하고 있는 상태
'docker' 카테고리의 다른 글
도커 컨테이너 다루기(5) - 컨테이너 로깅 (0) | 2021.05.28 |
---|---|
도커 컨테이너 다루기(4) - 도커 네트워크 (0) | 2021.05.26 |
도커 컨테이너 다루기(2) - 컨테이너 외부 노출 (0) | 2021.05.24 |
도커 컨테이너 다루기(1) - 생성/진입/삭제 (0) | 2021.04.19 |
CentOS 7 + 도커 설치 (0) | 2021.04.16 |