天天看點

Docker - Docker資料持久化

Docker - Docker資料持久化

Docker的資料持久化主要有兩種方式:

  1. Bind Mount。
  2. Volume。

Docker的資料持久化,即是資料不随着容器的結束而結束,資料存儲于主控端上,要麼存儲于主控端某個指定目錄中(使用Bind Mount),要麼存儲于Docker管理的Volume中(​

​/var/lib/docker/volumes​

​下)。

Bind Mount在Docker早期便開始使用了,用于将主控端中的目錄挂載(​

​mount​

​​)到容器中。但是當Bind Mount在不同的主控端系統時,它是不可移植的,比如Windows和Linux的目錄結構是不一樣的,Bind Mount所指向的主控端目錄也不能一樣。這也是為什麼Bind Mount不能出現在​

​Dockerfile​

​​中的原因,因為這樣​

​Dockerfile​

​就不可移植了。

Bind Mount有幾點需要注意:

  • 主控端的目錄路徑必須為全路徑(準确的說需要以​

    ​/​

    ​​或​

    ​~/​

    ​開始的路徑),不然Docker會将其當做Volume而不是Bind Mount處理。
  • 如果主控端上的目錄不存在,Docker會自動建立該目錄。
  • 如果容器中的目錄不存在,Docker會自動建立該目錄。
  • 主控端目錄無論有沒檔案,都會覆寫容器挂載的目錄。

Volume也是繞過容器的檔案系統,直接将資料存儲到主控端上,隻是Volume是被Docker管理的,Docker下所有的Volume都在主控端上的指定目錄下​

​/var/lib/docker/volumes​

​。

還有需要注意的是:

  • Bind Mount:容器挂載的目錄以主控端目錄為準,無論主控端目錄有無檔案,都會覆寫容器挂載的目錄。
  • Volume:主控端目錄有檔案時,以主控端目錄為準;主控端目錄沒有檔案時,從容器挂載的目錄複制過來,再以主控端目錄為準。

挂載資料卷(Volume)

在鏡像​

​centos:7​

​​上建立容器,并且将容器命名為​

​centos.7.5​

​​,通過​

​-v​

​​選項可以給容器添加資料卷;啟動之後,到容器内部可以看到資料卷的​

​Destination​

​​是​

​centos-volume​

​​(由​

​-v​

​​選項後面的參數指定),在​

​centos-volume​

​​中建立檔案​

​hello_kaven​

​。

[root@izoq008ryseuupz docker]# docker run -it --name centos.7.5 -v centos-volume centos:7  
[root@e2a5901b29b2 /]# ll
total 60
-rw-r--r--  1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx  1 root root     7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x  2 root root  4096 Nov 25 09:36 centos-volume
drwxr-xr-x  5 root root   360 Nov 25 09:36 dev
drwxr-xr-x  1 root root  4096 Nov 25 09:36 etc
drwxr-xr-x  2 root root  4096 Apr 11  2018 home
lrwxrwxrwx  1 root root     7 Nov 13 01:53 lib -> usr/lib
lrwxrwxrwx  1 root root     9 Nov 13 01:53 lib64 -> usr/lib64
drwxr-xr-x  2 root root  4096 Apr 11  2018 media
drwxr-xr-x  2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x  2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 92 root root     0 Nov 25 09:36 proc
dr-xr-x---  2 root root  4096 Nov 13 01:55 root
drwxr-xr-x 11 root root  4096 Nov 13 01:55 run
lrwxrwxrwx  1 root root     8 Nov 13 01:53 sbin -> usr/sbin
drwxr-xr-x  2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x 13 root root     0 Apr 11  2018 sys
drwxrwxrwt  7 root root  4096 Nov 13 01:55 tmp
drwxr-xr-x 13 root root  4096 Nov 13 01:53 usr
drwxr-xr-x 18 root root  4096 Nov 13 01:54 var
[root@e2a5901b29b2 /]# cd centos-volume
[root@e2a5901b29b2 centos-volume]# ll
total 0
[root@e2a5901b29b2 centos-volume]# echo "hello kaven" > hello_kaven
[root@e2a5901b29b2 centos-volume]# ll
total 4
-rw-r--r-- 1 root root   12 Nov 25 09:39 hello_kaven
[root@e2a5901b29b2 centos-volume]# cat hello_kaven
hello kaven      

容器是否成功挂載到資料卷,可以通過檢視容器資訊來擷取,運作下面的指令即可。

docker inspect centos.7.5      

得到的資訊中有下面這一段。

"Mounts": [
            {
                "Type": "volume",
                "Name": "c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4",
                "Source": "/var/lib/docker/volumes/c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4/_data",
                "Destination": "centos-volume",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]      

類型是​

​volume​

​​,​

​/var/lib/docker/volumes/c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4/_data​

​​就是資料卷在主控端中的目錄路徑,通過​

​docker volume ls​

​​指令,也可以查詢到資料卷名稱為​

​c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4​

​的資料卷。

[root@izoq008ryseuupz docker]# docker volume ls
DRIVER              VOLUME NAME
local               3c1ed533ce142b49eadc15ba57b87a3bac780e89e22c06503b3e909ab69ed62f
local               5b086d5fdb68b5a58593fdca6d6f0a9b3ead0ed929fd3961b7db48e3a928c24d
local               6b5a0394e690c4e0e869ddecc0db24a748a0229c70a83db46e0f2f95e3314958
local               8eb0f149b72711acd9618f827fc26a9afcce63ed51f1e60ac48e752344f88f22
local               08b4d10ef219075ee8a283112be06e1df52729bf23d3216342da3f8b21a0c127
local               31a6cbc600b3d30d0c567b3842ce5e7944495fcc12d42008385912d32facfd7a
local               208ddc66938b611237d4e868cb8800a36b5390969ba7a22d2d2e65a8c173b2c8
local               3285a7fb977eb7a87da83b2a5ff838c98037b15ec659eeff68c489e7004114ea
local               a4beb8e0e17a3369c8c9a447d777323df71d2b5e2f77ebfc69cc99af39e1077a
local               c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4
local               centos-volume
local               db153ec29b07b6268e7204fc2e91a32db91797bcd8f4d92c7e2637577cd1a155
local               dcf0505225e08c4c4d24f0e89ac83ed02a5387620734c4add6ab4f1d8196489c
local               f00edae7bd06b264a25329143fa2207e998491e459c24b0c30b1f78996a49369
[root@izoq008ryseuupz docker]# cd volumes
[root@izoq008ryseuupz volumes]# pwd
/var/lib/docker/volumes
[root@izoq008ryseuupz volumes]# cd c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4
[root@izoq008ryseuupz c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4]# ll
total 4
drwxr-xr-x 3 root root 4096 Nov 25 17:39 _data
[root@izoq008ryseuupz c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4]# cd _data
[root@izoq008ryseuupz _data]# ll
total 4
-rw-r--r-- 1 root root   12 Nov 25 17:39 hello_kaven
[root@izoq008ryseuupz _data]# cat hello_kaven
hello kaven      

很顯然,容器到主控端之間的資料共享已經實作了。那主控端到容器呢?當然也是可以的。

[root@izoq008ryseuupz _data]# echo "this is new file" > newFile
[root@izoq008ryseuupz _data]# ll
total 8
-rw-r--r-- 1 root root   12 Nov 25 17:39 hello_kaven
-rw-r--r-- 1 root root   17 Nov 25 18:08 newFile
[root@izoq008ryseuupz _data]# docker start -i centos.7.5
[root@e2a5901b29b2 /]# cd centos-volume
[root@e2a5901b29b2 centos-volume]# ll
total 8
-rw-r--r-- 1 root root   12 Nov 25 09:39 hello_kaven
-rw-r--r-- 1 root root   17 Nov 25 10:08 newFile
[root@e2a5901b29b2 centos-volume]# cat newFile
this is new file      

Bind Mount

将容器目錄​

​/shared_volume​

​​挂載到主控端目錄​

​/var/lib/docker/volumes/shared_volume​

​。

docker run -it --name centos.share1 -v /var/lib/docker/volumes/shared_volume:/shared_volume  centos:7      

在容器挂載目錄中建立檔案​

​share​

​,在主控端挂載目錄中也可以通路到。

[root@izoq008ryseuupz volume]# cd /var/lib/docker/volumes/shared_volume
[root@izoq008ryseuupz shared_volume]# pwd
/var/lib/docker/volumes/shared_volume
[root@izoq008ryseuupz shared_volume]# docker run -it --name centos.share1 -v /var/lib/docker/volumes/shared_volume:/shared_volume  centos:7
[root@1065ceefb3da /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  shared_volume  srv  sys  tmp  usr  var
[root@1065ceefb3da /]# cd shared_volume 
[root@1065ceefb3da shared_volume]# echo "this is share" > share 
[root@1065ceefb3da shared_volume]# ls
share
[root@1065ceefb3da shared_volume]# exit
exit
[root@izoq008ryseuupz shared_volume]# ls
share
[root@izoq008ryseuupz shared_volume]# cat share
this is share      

當然反過來也可以。

[root@izoq008ryseuupz ~]# cd /var/lib/docker/volumes/shared_volume
[root@izoq008ryseuupz shared_volume]# ll
total 4
-rw-r--r-- 1 root root   14 Nov 25 21:19 share
[root@izoq008ryseuupz shared_volume]# mkdir share2
[root@izoq008ryseuupz shared_volume]# ll
total 8
-rw-r--r-- 1 root root   14 Nov 25 21:19 share
drwxr-xr-x 2 root root 4096 Nov 27 12:26 share2
[root@izoq008ryseuupz shared_volume]# docker start -i centos.share1
[root@1065ceefb3da /]# cd shared_volume
[root@1065ceefb3da shared_volume]# ll
total 8
-rw-r--r-- 1 root root   14 Nov 25 13:19 share
drwxr-xr-x 2 root root 4096 Nov 27 04:26 share2      

檢視容器資訊。

docker inspect centos.share1      

通過下面的資訊可以知道容器已經成功挂載了主控端目錄。

"Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/docker/volumes/shared_volume",
                "Destination": "/shared_volume",
                "Mode": "",
                "RW": true,
                "Propagation": "rslave"
            }
        ]      

類型是​

​bind​

​。

挂載指定資料卷(Volume)

不需要自己去建立資料卷,通過下面這條指令可以讓Docker去建立資料卷​

​kaven_volume​

​。

docker run -itd --name kaven -v kaven_volume:/kaven/volume centos:7      

容器​

​kaven​

​成功運作起來了。

[root@izoq008ryseuupz ~]# docker run -itd --name kaven -v kaven_volume:/kaven/volume centos:7
97bff81a64bfd63d12e931705ae3bbb8266f6f53a8612fe965f37e0ce53d6c96
[root@izoq008ryseuupz ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
97bff81a64bf        centos:7            "/bin/bash"         3 seconds ago       Up 3 seconds                                 kaven      

檢視容器資訊。

docker inspect kaven      

通過下面的資訊可以知道容器已經成功挂載了資料卷。

"Mounts": [
            {
                "Type": "volume",
                "Name": "kaven_volume",
                "Source": "/var/lib/docker/volumes/kaven_volume/_data",
                "Destination": "/kaven/volume",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ]      

類型是​

​volume​

​。

挂載其他容器的資料卷

比如挂載容器​

​kaven​

​的資料卷。

docker inspect kaven      
"Mounts": [
            {
                "Type": "volume",
                "Name": "kaven_volume",
                "Source": "/var/lib/docker/volumes/kaven_volume/_data",
                "Destination": "/kaven/volume",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ]      

通過​

​docker run​

​​指令的​

​--volumes-from​

​選項,可以讓容器挂載其他容器的資料卷。

docker run -it --name centos.kaven --volumes-from kaven centos:7      
[root@izoq008ryseuupz shared_volume]# docker run -it --name centos.kaven --volumes-from kaven centos:7
[root@5fc01525a699 /]# ll
total 60
-rw-r--r--   1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx   1 root root     7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x   5 root root   360 Nov 27 04:33 dev
drwxr-xr-x   1 root root  4096 Nov 27 04:33 etc
drwxr-xr-x   2 root root  4096 Apr 11  2018 home
drwxr-xr-x   3 root root  4096 Nov 27 04:33 kaven
lrwxrwxrwx   1 root root     7 Nov 13 01:53 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Nov 13 01:53 lib64 -> usr/lib64
drwxr-xr-x   2 root root  4096 Apr 11  2018 media
drwxr-xr-x   2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x   2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 104 root root     0 Nov 27 04:33 proc
dr-xr-x---   2 root root  4096 Nov 13 01:55 root
drwxr-xr-x  11 root root  4096 Nov 13 01:55 run
lrwxrwxrwx   1 root root     8 Nov 13 01:53 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x  13 root root     0 Apr 11  2018 sys
drwxrwxrwt   7 root root  4096 Nov 13 01:55 tmp
drwxr-xr-x  13 root root  4096 Nov 13 01:53 usr
drwxr-xr-x  18 root root  4096 Nov 13 01:54 var
[root@5fc01525a699 /]# cd kaven
[root@5fc01525a699 kaven]# ll
total 4
drwxr-xr-x 2 root root 4096 Nov 27 01:24 volume
[root@5fc01525a699 kaven]# cd volume
[root@5fc01525a699 volume]# ll
total 0
[root@5fc01525a699 volume]# exit
exit      

成功挂載了容器​

​kaven​

​的資料卷。

docker inspect centos.kaven      
"Mounts": [
            {
                "Type": "volume",
                "Name": "kaven_volume",
                "Source": "/var/lib/docker/volumes/kaven_volume/_data",
                "Destination": "/kaven/volume",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]      

類型也是​

​volume​

​。

挂載多個資料卷

可以通過多個​

​-v​

​選項來給容器挂載多個資料卷。

[root@izoq008ryseuupz ~]# docker run -it --name centos.kaven.blog -v one -v two centos:7
[root@7a2ff8ab22f8 /]# ll
total 64
-rw-r--r--  1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx  1 root root     7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x  5 root root   360 Nov 25 11:36 dev
drwxr-xr-x  1 root root  4096 Nov 25 11:36 etc
drwxr-xr-x  2 root root  4096 Apr 11  2018 home
lrwxrwxrwx  1 root root     7 Nov 13 01:53 lib -> usr/lib
lrwxrwxrwx  1 root root     9 Nov 13 01:53 lib64 -> usr/lib64
drwxr-xr-x  2 root root  4096 Apr 11  2018 media
drwxr-xr-x  2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x  2 root root  4096 Nov 25 11:36 one
drwxr-xr-x  2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 96 root root     0 Nov 25 11:36 proc
dr-xr-x---  2 root root  4096 Nov 13 01:55 root
drwxr-xr-x 11 root root  4096 Nov 13 01:55 run
lrwxrwxrwx  1 root root     8 Nov 13 01:53 sbin -> usr/sbin
drwxr-xr-x  2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x 13 root root     0 Apr 11  2018 sys
drwxrwxrwt  7 root root  4096 Nov 13 01:55 tmp
drwxr-xr-x  2 root root  4096 Nov 25 11:36 two
drwxr-xr-x 13 root root  4096 Nov 13 01:53 usr
drwxr-xr-x 18 root root  4096 Nov 13 01:54 var      

通過查詢容器資訊,可以知道多個資料卷是否全部挂載成功。

docker inspect centos.kaven.blog      
"Mounts": [
            {
                "Type": "volume",
                "Name": "a64fce3680730956d0f0935ef1b5e3695ca5605ef1c6d621cdc6f5d26636bca2",
                "Source": "/var/lib/docker/volumes/a64fce3680730956d0f0935ef1b5e3695ca5605ef1c6d621cdc6f5d26636bca2/_data",
                "Destination": "one",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "6960782eb9ef3472bbce7489f6371fb72c6c0c4107baaf79042ef33dc91fe0f1",
                "Source": "/var/lib/docker/volumes/6960782eb9ef3472bbce7489f6371fb72c6c0c4107baaf79042ef33dc91fe0f1/_data",
                "Destination": "two",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]      

類型也都是​

​volume​

​。

很顯然都挂載成功了。

Docker - Docker資料持久化

資料卷隻讀權限

通過​

​:ro​

​可以讓容器對資料卷的權限變成隻讀。

docker run -it --name centos.ro -v volume_ro:/volume_ro_kaven:ro centos:7      

可以看到在容器中不能在隻讀權限資料卷挂載的目錄中建立檔案夾(其他任何寫操作也不可以)。

[root@izoq008ryseuupz shared_volume]# docker run -it --name centos.ro -v volume_ro:/volume_ro_kaven:ro centos:7
[root@3a9b0efd3732 /]# ll
total 60
-rw-r--r--   1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx   1 root root     7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x   5 root root   360 Nov 27 04:41 dev
drwxr-xr-x   1 root root  4096 Nov 27 04:41 etc
drwxr-xr-x   2 root root  4096 Apr 11  2018 home
lrwxrwxrwx   1 root root     7 Nov 13 01:53 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Nov 13 01:53 lib64 -> usr/lib64
drwxr-xr-x   2 root root  4096 Apr 11  2018 media
drwxr-xr-x   2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x   2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 106 root root     0 Nov 27 04:41 proc
dr-xr-x---   2 root root  4096 Nov 13 01:55 root
drwxr-xr-x  11 root root  4096 Nov 13 01:55 run
lrwxrwxrwx   1 root root     8 Nov 13 01:53 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x  13 root root     0 Apr 11  2018 sys
drwxrwxrwt   7 root root  4096 Nov 13 01:55 tmp
drwxr-xr-x  13 root root  4096 Nov 13 01:53 usr
drwxr-xr-x  18 root root  4096 Nov 13 01:54 var
drwxr-xr-x   2 root root  4096 Nov 27 04:41 volume_ro_kaven
[root@3a9b0efd3732 /]# cd volume_ro_kaven
[root@3a9b0efd3732 volume_ro_kaven]# mkdir kaven
mkdir: cannot create directory 'kaven': Read-only file system
[root@3a9b0efd3732 volume_ro_kaven]# exit
exit
[root@izoq008ryseuupz shared_volume]# cd /var/lib/docker/volumes/volume_ro/_data
[root@izoq008ryseuupz _data]# mkdir kaven
[root@izoq008ryseuupz _data]# docker start -i centos.ro
[root@3a9b0efd3732 /]# cd volume_ro_kaven
[root@3a9b0efd3732 volume_ro_kaven]# ll
total 4
drwxr-xr-x 2 root root 4096 Nov 27 04:44 kaven      

通過下面這條指令可以查詢到資料卷的挂載情況。

docker inspect centos.ro      
"Mounts": [
            {
                "Type": "volume",
                "Name": "volume_ro",
                "Source": "/var/lib/docker/volumes/volume_ro/_data",
                "Destination": "/volume_ro_kaven",
                "Driver": "local",
                "Mode": "ro",
                "RW": false,
                "Propagation": ""
            }
        ]      

類型也是​

​volume​

​​,主控端中的目錄路徑​

​"Source": "/var/lib/docker/volumes/volume_ro/_data"​

​​,容器中的目錄路徑​

​"Destination": "/volume_ro_kaven"​

​​,并且通過​

​"RW": false​

​​、​

​"Mode": "ro"​

​這些資訊,說明資料卷隻讀權限設定成功了。

這些挂載資料卷的方法,對Bind Mount方式進行Docker資料持久化也适用,這裡就不介紹了。

繼續閱讀