Docker - Docker数据持久化

阳光穿透心脏的1/2处 2022-12-24 06:58 308阅读 0赞

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选项可以给容器添加数据卷;启动之后,到容器内部可以看到数据卷的Destinationcentos-volume(由-v选项后面的参数指定),在centos-volume中创建文件hello_kaven

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

容器是否成功挂载到数据卷,可以通过查看容器信息来获取,运行下面的命令即可。

  1. docker inspect centos.7.5

得到的信息中有下面这一段。

  1. "Mounts": [
  2. {
  3. "Type": "volume",
  4. "Name": "c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4",
  5. "Source": "/var/lib/docker/volumes/c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4/_data",
  6. "Destination": "centos-volume",
  7. "Driver": "local",
  8. "Mode": "",
  9. "RW": true,
  10. "Propagation": ""
  11. }
  12. ]

类型是volume/var/lib/docker/volumes/c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4/_data就是数据卷在宿主机中的目录路径,通过docker volume ls命令,也可以查询到数据卷名称为c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4的数据卷。

  1. [root@izoq008ryseuupz docker]# docker volume ls
  2. DRIVER VOLUME NAME
  3. local 3c1ed533ce142b49eadc15ba57b87a3bac780e89e22c06503b3e909ab69ed62f
  4. local 5b086d5fdb68b5a58593fdca6d6f0a9b3ead0ed929fd3961b7db48e3a928c24d
  5. local 6b5a0394e690c4e0e869ddecc0db24a748a0229c70a83db46e0f2f95e3314958
  6. local 8eb0f149b72711acd9618f827fc26a9afcce63ed51f1e60ac48e752344f88f22
  7. local 08b4d10ef219075ee8a283112be06e1df52729bf23d3216342da3f8b21a0c127
  8. local 31a6cbc600b3d30d0c567b3842ce5e7944495fcc12d42008385912d32facfd7a
  9. local 208ddc66938b611237d4e868cb8800a36b5390969ba7a22d2d2e65a8c173b2c8
  10. local 3285a7fb977eb7a87da83b2a5ff838c98037b15ec659eeff68c489e7004114ea
  11. local a4beb8e0e17a3369c8c9a447d777323df71d2b5e2f77ebfc69cc99af39e1077a
  12. local c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4
  13. local centos-volume
  14. local db153ec29b07b6268e7204fc2e91a32db91797bcd8f4d92c7e2637577cd1a155
  15. local dcf0505225e08c4c4d24f0e89ac83ed02a5387620734c4add6ab4f1d8196489c
  16. local f00edae7bd06b264a25329143fa2207e998491e459c24b0c30b1f78996a49369
  17. [root@izoq008ryseuupz docker]# cd volumes
  18. [root@izoq008ryseuupz volumes]# pwd
  19. /var/lib/docker/volumes
  20. [root@izoq008ryseuupz volumes]# cd c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4
  21. [root@izoq008ryseuupz c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4]# ll
  22. total 4
  23. drwxr-xr-x 3 root root 4096 Nov 25 17:39 _data
  24. [root@izoq008ryseuupz c8079a1f169f2f0d93923db7b785f1033a46bdc8cf6baf73d742ebbb3c03d6a4]# cd _data
  25. [root@izoq008ryseuupz _data]# ll
  26. total 4
  27. -rw-r--r-- 1 root root 12 Nov 25 17:39 hello_kaven
  28. [root@izoq008ryseuupz _data]# cat hello_kaven
  29. hello kaven

很显然,容器到宿主机之间的数据共享已经实现了。那宿主机到容器呢?当然也是可以的。

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

Bind Mount

将容器目录/shared_volume挂载到宿主机目录/var/lib/docker/volumes/shared_volume

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

在容器挂载目录中创建文件share,在宿主机挂载目录中也可以访问到。

  1. [root@izoq008ryseuupz volume]# cd /var/lib/docker/volumes/shared_volume
  2. [root@izoq008ryseuupz shared_volume]# pwd
  3. /var/lib/docker/volumes/shared_volume
  4. [root@izoq008ryseuupz shared_volume]# docker run -it --name centos.share1 -v /var/lib/docker/volumes/shared_volume:/shared_volume centos:7
  5. [root@1065ceefb3da /]# ls
  6. anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin shared_volume srv sys tmp usr var
  7. [root@1065ceefb3da /]# cd shared_volume
  8. [root@1065ceefb3da shared_volume]# echo "this is share" > share
  9. [root@1065ceefb3da shared_volume]# ls
  10. share
  11. [root@1065ceefb3da shared_volume]# exit
  12. exit
  13. [root@izoq008ryseuupz shared_volume]# ls
  14. share
  15. [root@izoq008ryseuupz shared_volume]# cat share
  16. this is share

当然反过来也可以。

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

查看容器信息。

  1. docker inspect centos.share1

通过下面的信息可以知道容器已经成功挂载了宿主机目录。

  1. "Mounts": [
  2. {
  3. "Type": "bind",
  4. "Source": "/var/lib/docker/volumes/shared_volume",
  5. "Destination": "/shared_volume",
  6. "Mode": "",
  7. "RW": true,
  8. "Propagation": "rslave"
  9. }
  10. ]

类型是bind

挂载指定数据卷(Volume)

不需要自己去创建数据卷,通过下面这条命令可以让Docker去创建数据卷kaven_volume

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

容器kaven成功运行起来了。

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

查看容器信息。

  1. docker inspect kaven

通过下面的信息可以知道容器已经成功挂载了数据卷。

  1. "Mounts": [
  2. {
  3. "Type": "volume",
  4. "Name": "kaven_volume",
  5. "Source": "/var/lib/docker/volumes/kaven_volume/_data",
  6. "Destination": "/kaven/volume",
  7. "Driver": "local",
  8. "Mode": "z",
  9. "RW": true,
  10. "Propagation": ""
  11. }
  12. ]

类型是volume

挂载其他容器的数据卷

比如挂载容器kaven的数据卷。

  1. docker inspect kaven
  2. "Mounts": [
  3. {
  4. "Type": "volume",
  5. "Name": "kaven_volume",
  6. "Source": "/var/lib/docker/volumes/kaven_volume/_data",
  7. "Destination": "/kaven/volume",
  8. "Driver": "local",
  9. "Mode": "z",
  10. "RW": true,
  11. "Propagation": ""
  12. }
  13. ]

通过docker run命令的--volumes-from选项,可以让容器挂载其他容器的数据卷。

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

成功挂载了容器kaven的数据卷。

  1. docker inspect centos.kaven
  2. "Mounts": [
  3. {
  4. "Type": "volume",
  5. "Name": "kaven_volume",
  6. "Source": "/var/lib/docker/volumes/kaven_volume/_data",
  7. "Destination": "/kaven/volume",
  8. "Driver": "local",
  9. "Mode": "",
  10. "RW": true,
  11. "Propagation": ""
  12. }
  13. ]

类型也是volume

挂载多个数据卷

可以通过多个-v选项来给容器挂载多个数据卷。

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

通过查询容器信息,可以知道多个数据卷是否全部挂载成功。

  1. docker inspect centos.kaven.blog
  2. "Mounts": [
  3. {
  4. "Type": "volume",
  5. "Name": "a64fce3680730956d0f0935ef1b5e3695ca5605ef1c6d621cdc6f5d26636bca2",
  6. "Source": "/var/lib/docker/volumes/a64fce3680730956d0f0935ef1b5e3695ca5605ef1c6d621cdc6f5d26636bca2/_data",
  7. "Destination": "one",
  8. "Driver": "local",
  9. "Mode": "",
  10. "RW": true,
  11. "Propagation": ""
  12. },
  13. {
  14. "Type": "volume",
  15. "Name": "6960782eb9ef3472bbce7489f6371fb72c6c0c4107baaf79042ef33dc91fe0f1",
  16. "Source": "/var/lib/docker/volumes/6960782eb9ef3472bbce7489f6371fb72c6c0c4107baaf79042ef33dc91fe0f1/_data",
  17. "Destination": "two",
  18. "Driver": "local",
  19. "Mode": "",
  20. "RW": true,
  21. "Propagation": ""
  22. }
  23. ]

类型也都是volume

很显然都挂载成功了。
在这里插入图片描述

数据卷只读权限

通过:ro可以让容器对数据卷的权限变成只读。

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

可以看到在容器中不能在只读权限数据卷挂载的目录中创建文件夹(其他任何写操作也不可以)。

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

通过下面这条命令可以查询到数据卷的挂载情况。

  1. docker inspect centos.ro
  2. "Mounts": [
  3. {
  4. "Type": "volume",
  5. "Name": "volume_ro",
  6. "Source": "/var/lib/docker/volumes/volume_ro/_data",
  7. "Destination": "/volume_ro_kaven",
  8. "Driver": "local",
  9. "Mode": "ro",
  10. "RW": false,
  11. "Propagation": ""
  12. }
  13. ]

类型也是volume,宿主机中的目录路径"Source": "/var/lib/docker/volumes/volume_ro/_data",容器中的目录路径"Destination": "/volume_ro_kaven",并且通过"RW": false"Mode": "ro"这些信息,说明数据卷只读权限设置成功了。

这些挂载数据卷的方法,对Bind Mount方式进行Docker数据持久化也适用,这里就不介绍了。

Docker数据持久化就介绍到这里。

写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!

发表评论

表情:
评论列表 (有 0 条评论,308人围观)

还没有评论,来说两句吧...

相关阅读

    相关 docker数据卷区别——持久

    容器数据卷——持久化 上面说到容器是一个简易版的linux系统和运行在其中的应用程序,那我们的应用程序产生的数据(比如操作日志、异常日志、数据)也是在容器内的系统中存放的