Docker 容器数据卷(八)

首页 / 🐋Docker / 正文

一、容器数据卷简述

  数据卷(Data Volumes)是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进容器。

  使用docker容器的时候,会产生一系列的数据文件,这些数据文件在删除docker容器时是会消失的,但是其中产生的部分内容是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,程序员希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。

  一般地来说,docker 容器数据卷可以看成常用的u盘,它存在于一个或多个的容器中,由 docker 挂载到容器,但不属于联合文件系统,Docker 不会在容器删除时删除其挂载的数据卷。

二、数据卷特点

  • 数据卷可以在容器之间共享或重用数据
  • 数据卷中的更改可以立即生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷默认会一直存在,即使容器被删除
  • 数据卷的生命周期一直持续到没有容器使用它为止

三、数据卷注意事项

  • 挂载数据卷,最好是通过run而非 create/start 创建启动容器,create/start命令创建启动容器 后,再挂载数据卷相当麻烦,要修改很多配置文件,但并非不可以。
  • docker官网推荐尽量进行目录挂载,不要进行文件挂载。

四、数据卷类型

docker_volume

1、bind mount(绑定挂载)

  bind mounts : 容器内的数据被存放到宿主机文件系统的任意位置,甚至存放到一些重要的系统目录或 文件中。除了docker之外的进程也可以任意对他们进行修改。

  当使用bind mounts时,宿主机的目录或文件被挂载到容器中。容器将按照挂载目录或文件的绝对路径 来使用或修改宿主机的数据。宿主机中的目录或文件不需要预先存在,在需要的使用会自动创建。

  使用bind mounts在性能上是非常好的,但这依赖于宿主机有一个目录妥善结构化的文件系统。

  使用bind mounts的容器可以在通过容器内部的进程对主机文件系统进行修改,包括创建,修改和删除 重要的系统文件和目录,这个功能虽然很强大,但显然也会造成安全方面的影响,包括影响到宿主机上 Docker以外的进程。

注意事项

  • 如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中。
  • 如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录会显示数据卷中的数据。如果原来容器中的目录有数据,那么原始数据会被隐藏掉。

示例:创建 nginx 容器,并进行 bind mount 挂载。

docker run -it --mount type=bind,source=/usr/local/data,destination=/data --name nginx01 nginx /bin/bash
docker run -it -v /usr/local/data:/data --name nginx01 nginx /bin/bash

查看容器挂载细节

docker inspect nginx01
"Mounts": [
            {
                "Type": "bind",
                "Source": "/usr/local/data",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

2、volume mount(数据卷挂载)

  当我们创建一个数据卷时,它存储在 Docker 主机上的一个目录中。数据卷由 Docker 管理,并与主机的核心功能隔离。

  给定的数据卷可以同时安装到多个容器中。当没有正在运行的容器使用数据卷时,数据卷仍然可供 Docker 使用,并且不会自动删除。

  当我们挂载一个数据卷时,它可能是命名的或匿名的。匿名数据卷在首次挂载到容器时没有明确的名称,因此 Docker 给它们一个随机名称,保证在给定的 Docker 主机中是唯一的。除了名称之外,命名卷和匿名卷的行为方式相同。

示例:创建 nginx 容器,并进行 volume 挂载。

docker run -it --mount type=volume,source=my-data2,destination=/data --name nginx02 nginx /bin/bash

查看挂载细节

docker inspect nginx02
"Mounts": [
            {
                "Type": "volume",
                "Name": "my-data1",
                "Source": "/var/lib/docker/volumes/my-data1/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],

3、tmpfs mount(临时挂载)

  tmpfs 挂载只存储在宿主机系统的内存中,从不写入宿主机系统的文件系统。它不会保存在磁盘上,无论是在 Docker 主机上还是在容器内。

  tmpfs mount 可以在容器的生命周期内用于存储非持久状态或敏感信息。

示例:创建 nginx 容器,并进行tmpfs 挂载。

docker run -it --mount type=tmpfs,destination=/data --name nginx03 nginx /bin/bash

查看挂载细节

docker inspect nginx03
"Mounts": [
            {
                "Type": "tmpfs",
                "Source": "",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

五、数据卷挂载命令

--volume (简写 -v)--mount 参数用于数据卷挂载。

1、创建 bind mount 和挂载 volume 的比较

对比项bind mountvolume
Source位置用户指定/var/lib/docker/volumes/
Source为空覆盖dest为空保留dest内容
Source非空覆盖dest内容覆盖dest内容
Source种类文件或目录只能是目录
可移植性一般(自行维护)强(docker托管)
宿主直接访问容易(仅需chown)受限(需登陆root用户)*

2、创建 bind mount 时使用--volume--mount的比较

对比项--volume-v--mount type=bind
如果主机路径不存在自动创建命令报错

六、匿名数据卷

匿名数据卷:不指定本地挂载路径,只指定容器内挂载路径,本地挂载路径在 /var/lib/docker 自动生成。

示例:

docker run -it -v /data --name nginx05 nginx /bin/bash

查看容器内部细节:

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

七、只读和读写

  容器数据卷的只读和读写需要通过参数 rorw 来进行控制。

  • ro :read only
  • rw :read write

语法格式:

docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
docker run -it -v /宿主机绝对路径目录:/容器内目录:rw 镜像名

示例:

docker run -d -P --name nginx05 -v nginx1:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v nginx2:/etc/nginx:rw nginx

注意:只要看到 ro 就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

八、数据卷继承与共享

  命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器,容器之间的数据卷可以通过 --volumes-form 参数共享数据。

img

1、环境准备

(1)创建启动 c3 数据卷容器,使用 –v 参数 设置数据卷。

docker run -it --name=c3 -v /test:/data centos:7 /bin/bash

(2)创建启动 c1 容器,使用 --volumes-from 参数设置数据卷继承 c3 数据卷。

docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash

(3)创建启动 c2 容器,使用 --volumes-from 参数设置数据卷继承 c3 数据卷。

docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash

2、分别连接三个容器和主机

  通过下图查看数据卷,可以发现三个容器的挂载点 /data 和主机 /test 目录均为空。

image-20220804143151879

3、在本机创建文件,其他三台容器是否可以查看到此文件?

image-20220804143006744

结论:在主机创建文件,容器中可以查看到。

4、在容器数据卷中创建文件,在主机是否可以查看呢?

image-20220804143415467

结论:在容器内创建文件,在主机也可查看。

5、停止容器 c3 ,继承容器 c3 的容器 c1 、 c2 和主机之间数据还可以共享吗?

image-20220804143856452

结论:

  • 容器之间配置信息的传递,存储在本机的文件则会一直保留!
  • 数据卷的生命周期一直持续到没有容器使用它为止。
  • 一旦持久化到了本地,本地的数据是不会删除的!

九、参考文档

全网最详细的docker数据卷教程 - 掘金 (juejin.cn)

Docker数据卷挂载命令volume(-v)与mount的区别

Docker数据卷及网络详细讲解

Docker 数据卷和Dockerfile (icode9.com)

打赏
文章目录