Docker-Volume数据卷详讲

打印 上一主题 下一主题

主题 2300|帖子 2300|积分 6900

Docker数据卷-Volume

一:Volume是什么,用来做什么的

当删除docker容器时,容器内部的文件就会跟随容器所销毁,在生产情况中我们需要将数据持久化生存,就催生了将容器内部的数据生存在宿主机的需求,volume 就是被筹划用于解决容器与主机之间、容器与容器之间共享文件,容器中数据的持久化,容器中的数据备份、迁移、规复。

二:Volume怎样利用

在实行 docker run 命令的时候,利用-v参数用于指定命据卷,可以完成数据卷挂载。数据卷卷可以是命名的,也可以是匿名的。匿名卷被赋予一个随机名称,该名称保证在给定的 Docker 主机内是唯一的。与命名卷一样,纵然您删除利用它们的容器,匿名卷也会保留下来,除非您--rm在创建容器时利用该标志,在这种情况下与容器关联的匿名卷将被销毁。
匿名数据卷的利用

在启动容器的时候只指定容器内部的路径,不写宿主机路径。如下:
  1. lemon@DockerVolume:~$ docker run -d -p 8888:80 -v /usr/share/nginx/html --name nginx-volume nginx:latest
  2. 37d8c80f337d3a98d3470855fba5009625285e742acd268b42bbe3f969cd25a8
  3. lemon@DockerVolume:~$
复制代码
该命令将创建一个名称为nginx-volume的Nginx容器,其中 -v 仅写了容器内的路径,并未提供卷名,利用命令 docker inspect nginx-volume | grep -A 11 “Mounts” 检察其挂载信息。
  1. lemon@DockerVolume:~$ docker inspect nginx-volume | grep -A 11 "Mounts"
  2.         "Mounts": [
  3.             {
  4.                 "Type": "volume",
  5.                 "Name": "538688015ecc44b37c36861c07bff24f7330b06a2d8dd396d4980a9594de461d",
  6.                 "Source": "/var/lib/docker/volumes/538688015ecc44b37c36861c07bff24f7330b06a2d8dd396d4980a9594de461d/_data",
  7.                 "Destination": "/usr/share/nginx/html",
  8.                 "Driver": "local",
  9.                 "Mode": "",
  10.                 "RW": true,
  11.                 "Propagation": ""
  12.             }
  13.         ],
  14. lemon@DockerVolume:~$
复制代码
通过查询挂载信息可知,该容器挂载了一个名称为一段哈希串的volume类型的,其在宿主的存储位置在:/var/lib/docker/volumes/538688015ecc44b37c36861c07bff24f7330b06a2d8dd396d4980a9594de461d/_data 目录下,挂载的是容器内的路径:/usr/share/nginx/html
命名数据卷的利用

在启动容器的时候指定卷名,并绑定容器内部的路径。如下:
  1. lemon@DockerVolume:~$ docker run -d -p 8800:80 -v nginx_dir:/usr/share/nginx/html --name nginx-volume2 nginx:latest
  2. 2501c7eeab6484acf05dbc0de901fec2472835e1bc947af046a711352e153e0b
  3. lemon@DockerVolume:~$
复制代码
该命令将创建一个名称为nginx-volume2的Nginx容器,其中 -v 提供了卷名和容器内的路径映射关系,利用命令 docker inspect nginx-volume2 | grep -A 11 “Mounts” 检察其挂载信息。
  1. lemon@DockerVolume:~$ docker inspect nginx-volume2 | grep -A 11 "Mounts"
  2.         "Mounts": [
  3.             {
  4.                 "Type": "volume",
  5.                 "Name": "nginx_dir",
  6.                 "Source": "/var/lib/docker/volumes/nginx_dir/_data",
  7.                 "Destination": "/usr/share/nginx/html",
  8.                 "Driver": "local",
  9.                 "Mode": "z",
  10.                 "RW": true,
  11.                 "Propagation": ""
  12.             }
  13.         ],
  14. lemon@DockerVolume:~$
复制代码
通过查询挂载信息可知,该容器挂载了一个名称为 nginx_dir 的volume类型的,其在宿主的存储位置在:/var/lib/docker/volumes/nginx_dir/_data 目录下,挂载的是容器内的路径:/usr/share/nginx/html
通过这两个示例发现不管是命名数据卷还是匿名数据卷,其存储位置都在 /var/lib/docker/volumes/<数据卷名称>/_data 目录下,且挂载类型均为 volume ,那尚有没有其他的类型的数据卷挂载吗,或者说我想指定存储到宿主机的其他位置呢,比如,我希望将容器nginx-volume3 的目录指定到/home/lemon/docker_nginx_data/ 目录之下,我的/var/lib/docker目录存储在 / 根分区下,其存储空间太小,希望将数据挪动到更大的目录 /home/ 分区下。
下面我未来介绍其他的两种类型文件绑定方式
三:docker存储的三种类型

如果希望将容器nginx-volume3 的目录/usr/share/nginx/html 指定到/home/lemon/docker_nginx_data/ 目录之下,就需要需用到如下的方式去指定挂载:
-v /home/lemon/docker_nginx_data:/usr/share/nginx/html
示例如下:
  1. lemon@DockerVolume:~$ docker run -d -p 8801:80 -v /home/lemon/docker_nginx_data:/usr/share/nginx/html --name nginx-volume3 nginx:latest
  2. 016a57e9a5f419647b87fc603d966357644f12a71b0265f2b3d2eb12e1453877
  3. lemon@DockerVolume:~$
复制代码
利用命令 docker inspect nginx-volume3 | grep -A 11 “Mounts” 检察其挂载信息。
  1. lemon@DockerVolume:~$ docker inspect nginx-volume3 | grep -A 11 "Mounts"
  2.         "Mounts": [
  3.             {
  4.                 "Type": "bind",
  5.                 "Source": "/home/lemon/docker_nginx_data",
  6.                 "Destination": "/usr/share/nginx/html",
  7.                 "Mode": "",
  8.                 "RW": true,
  9.                 "Propagation": "rprivate"
  10.             }
  11.         ],
  12.         "Config": {
  13.             "Hostname": "016a57e9a5f4",
  14. lemon@DockerVolume:~$
复制代码
通过查询挂载信息可知,该容器将宿主机的/home/lemon/docker_nginx_data目录与容器的/usr/share/nginx/html挂载了起来。与上面的两个类型相比较,我们发现其Type 参数类型为 bind,与上面的两种方式的 volume 类型不同。
此处我们来看一下volume与bind两种类型优缺点:
对比项Volume(卷)Bind (绑定挂载)存储位置Docker 同一管理,默认存放在 /var/lib/docker/volumes/直接利用宿主机上的指定目录创建方式通过 docker volume create 创建,Docker 负责管理需要手动指定宿主机路径适用场景保举用于持久化存储,如数据库、日志等适用于开辟情况,可直接访问宿主机文件容器间共享容易共享,多个容器可以挂载同一个 Volume手动管理,需要确保宿主机目录存在安全性更安全,容器无法直接访问宿主机风险较高,容器可能影响宿主机数据性能一般更快,Docker 举行了优化可能受文件系统性能影响跨平台可以跨主机(NFS 等),便于迁移和备份仅限本地,受宿主机文件系统影响 此处之外的区别,bind类型会存在空挂载的问题,比如上面的容器nginx-volume3我们在浏览器中访问一下

会发现该容器无法访问Nginx的接待页,具体原由就出现在空挂载上,如果bind类型挂载的宿主机路径为空,则会将容器内的挂载路径变为空,该特性适用于将宿主机上的配置文件替换容器内部的配置文件,也在一定程度上适用与容器文件迁移或者文件备份,但是条件条件迁移的目标地址最好是雷同的宿主机系统,例如Linux系统迁移至Linux,Windows系统迁移至Windows。跨系统迁移会在一定程度上可能导致文件不能利用。
除了bind类型以外,尚有一个不太常用的tmpfs类型,用于将容器内的路径指定到宿主机的内存上,通常用于一些高性能的文件读写情况下,例如将MySQL的数据库指定到内存当中,以增加缓存刷盘速度,或者用于创建一个高速写入的缓存路径。
示例如下:
  1. lemon@DockerVolume:~$ docker run -d -p 8802:80 --mount type=tmpfs,destination=/app --name nginx-volume4 nginx:latest
  2. 44354dea5bcbc588d44e795e60fc44200f7edcff20f289c7fb8a7efae2227c4e
  3. lemon@DockerVolume:~$
  4. lemon@DockerVolume:~$ docker inspect nginx-volume4 | grep -A 11 "Mounts"
  5.             "Mounts": [
  6.                 {
  7.                     "Type": "tmpfs",
  8.                     "Target": "/app"
  9.                 }
  10.             ],
  11.             "MaskedPaths": [
  12.                 "/proc/asound",
  13.                 "/proc/acpi",
  14.                 "/proc/kcore",
  15.                 "/proc/keys",
  16.                 "/proc/latency_stats",
  17. --
  18.         "Mounts": [
  19.             {
  20.                 "Type": "tmpfs",
  21.                 "Source": "",
  22.                 "Destination": "/app",
  23.                 "Mode": "",
  24.                 "RW": true,
  25.                 "Propagation": ""
  26.             }
  27.         ]
  28. lemon@DockerVolume:~$
复制代码
通过查询挂载信息可以发现,tmpfs类型没有在宿主机上指定路径,是由于我们指定到了内存当中。
三种类型挂载的的位置


三种类型其本质是,挂载的宿主机文件系统的位置不同。
四:-v与--mount参数的区别

-v 只能挂载2种形式 bind,volume
–mount 可以挂载3种形式 bind,volume,tmpfs
两者在功能上是等效的,但–mount更为灵活,适用于更复杂的挂载需求,利用哪种方式紧张取决与具体的利用场景。如果你只需要简单的将主机上的目录挂载到容器内,-v参数充足简便,如果需要更多挂载选项,保举利用–mount参数。
五:docker -v的四种用法

1. 不利用-v参数

示例:
  1. lemon@DockerVolume:~/myfile$ docker run -d -p 8803:80 --name nginx-volume5 nginx:latest
  2. bbecec9a49e86319ea239bed3227b54ae00ef514964ed70b9f4e4464cb547ac2
  3. lemon@DockerVolume:~/myfile$ docker inspect nginx-volume5 | grep "Mounts"
  4.         "Mounts": [],
  5. lemon@DockerVolume:~/myfile$
复制代码
当不利用-v参数时,容器也不会在宿主机上创建volume,此时当容器删除,数据也会跟随删除。
2. -v <容器内路径>

示例:
  1. lemon@DockerVolume:~/myfile$ docker run -d -p 8804:80 -v /usr/share/nginx/html --name nginx-volume6 nginx:latest
  2. aa30246d69a549c21343b8ef4e7cf94f20c9e4e2a2dbcd3fa3af174b7c39dc7c
  3. lemon@DockerVolume:~/myfile$ docker inspect nginx-volume6 | grep -A 15 "Mounts"
  4.         "Mounts": [
  5.             {
  6.                 "Type": "volume",
  7.                 "Name": "61e5198338d2fffafafe9f1bad51c67c2570506d63124c62355bc4e0e6bea5ef",
  8.                 "Source": "/var/lib/docker/volumes/61e5198338d2fffafafe9f1bad51c67c2570506d63124c62355bc4e0e6bea5ef/_data",
  9.                 "Destination": "/usr/share/nginx/html",
  10.                 "Driver": "local",
  11.                 "Mode": "",
  12.                 "RW": true,
  13.                 "Propagation": ""
  14.             }
  15.         ],
  16.         "Config": {
  17.             "Hostname": "aa30246d69a5",
  18.             "Domainname": "",
  19.             "User": "",
  20. lemon@DockerVolume:~/myfile$
复制代码
当 -v 参数仅指定容器内的路径时,将创建一个匿名类型的volume,用于存储容器的数据。
3. -v < Volume 名称>:/<容器内路径>

示例:
  1. lemon@DockerVolume:~$ docker run -d -p 8805:80 -v NginxVolume7_VolumeName:/usr/share/nginx/html --name nginx-volume7 nginx:latest
  2. d74098d3c4ec7af671e2ab6cd50f9bae51b33fa9fc4100f5adaa380463a062b5
  3. lemon@DockerVolume:~$ docker inspect nginx-volume7 | grep -A 15 "Mounts"
  4.         "Mounts": [
  5.             {
  6.                 "Type": "volume",
  7.                 "Name": "NginxVolume7_VolumeName",
  8.                 "Source": "/var/lib/docker/volumes/NginxVolume7_VolumeName/_data",
  9.                 "Destination": "/usr/share/nginx/html",
  10.                 "Driver": "local",
  11.                 "Mode": "z",
  12.                 "RW": true,
  13.                 "Propagation": ""
  14.             }
  15.         ],
  16.         "Config": {
  17.             "Hostname": "d74098d3c4ec",
  18.             "Domainname": "",
  19.             "User": "",
  20. lemon@DockerVolume:~$
复制代码
当 -v 参数指定一个不存在volume时,在创建容器时,docker会自动创建该volume,这两种类型的 -v 指定挂载方式,不会存在空挂载现象。
4. -v <宿主机路径>:<容器内路径>

示例:
  1. lemon@DockerVolume:~$ docker run -d -p 8806:80 -v /home/lemon/nginx_volume8_dir:/usr/share/nginx/html --name nginx-volume8 nginx:latest
  2. df36b3ee868d2e4573b4cb7dd1a1abfafbff4052f102417169b84b152c010c44
  3. lemon@DockerVolume:~$ docker inspect nginx-volume8 | grep -A 15 "Mounts"
  4.         "Mounts": [
  5.             {
  6.                 "Type": "bind",
  7.                 "Source": "/home/lemon/nginx_volume8_dir",
  8.                 "Destination": "/usr/share/nginx/html",
  9.                 "Mode": "",
  10.                 "RW": true,
  11.                 "Propagation": "rprivate"
  12.             }
  13.         ],
  14.         "Config": {
  15.             "Hostname": "df36b3ee868d",
  16.             "Domainname": "",
  17.             "User": "",
  18.             "AttachStdin": false,
  19.             "AttachStdout": false,
  20. lemon@DockerVolume:~$
复制代码
当 -v 参数将宿主机的目录和容器内的目录关联起来时,默认会用宿主机的目录替换容器内部的目录数据,利用该种方式,需要注意空挂载现象。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立聪堂德州十三局店

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表