Docker - Docker数据持久化
Docker - Docker数据持久化
Docker的数据持久化主要有两种方式:
- Bind Mount。
- 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
。
很显然都挂载成功了。
数据卷只读权限
通过: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数据持久化也适用,这里就不介绍了。
Docker数据持久化就介绍到这里。
写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!
还没有评论,来说两句吧...