欢迎光临
我们一直在努力

Docker存储卷深度剖析:从创建到实战,解锁容器数据持久化的终极奥秘

文章目录

  • 本篇摘要
  • 一.存储卷相关概念
  • 二.为什么需要存储卷
  • 三.存储卷分类
  • 四.存储卷使用之管理卷
    • `Volume`命令操作
      • `1·docker volume create`
      • `2·docker volume inspect`
      • `3·docker volume ls`
      • `4·docker volume rm`
      • `5·docker volume prune`
    • `-v` 或者`–mount` 指定
      • `-v`模式
      • `–mount` 模式
    • Dockerfile 匿名卷
    • 管理卷之宿主机与容器之间同步
    • 管理卷的生命周期验证
    • 管理卷共享验证
  • 五.存储卷使用之绑定卷
    • `-v 创建`
    • `–mount创建`
    • 验证对应的宿主机绑定目录不存在以及对应目录下两个内容相同,以宿主机为主还是容器?
      • `–mount` 模式
      • `-v` 模式
  • 六.存储卷使用之临时卷
      • **1.创建卷 – 方式一:指定–tmpfs创建**:
      • **2.创建卷 – 方式二:`–mount`指定参数创建**
    • 验证创建容器中已经存在目录的临时卷情景以及填充内容后重启后效果
    • 验证–mount选项创建临时卷使用tmpfs-size
    • 验证对容器内文件操作及对应容器内临时卷里内容操作是否能被宿主机
  • 七.MySQL容器基于绑定卷后销毁进行数据恢复测试
  • 八.对应的卷使用的常见问题
    • 使用场景
    • 使用时候常见问题
  • 九.本篇小结

在这里插入图片描述

本篇摘要

本文围绕 Docker 存储卷展开,介绍创建、查看、删除等命令,详述 -v 与 –mount 模式。涵盖管理卷、绑定卷、临时卷的使用与特性,通过 MySQL 测试数据恢复,还指出常见使用问题。

一.存储卷相关概念

在这里插入图片描述

可以理解成上图中对应的Docker daemon 里面存在对应的存储卷。

  • 存储卷定义:将宿主机本地文件系统中的某个目录,与容器内部文件系统上的某一目录建立绑定关系。
  • 数据写入原理:在容器对应目录写入数据时,内容直接写入宿主机上与之绑定的目录。
  • 存储卷本质:是存在于宿主机上的文件或目录,可绕过默认联合文件系统,直接以文件或目录形式存在。
  • 在这里插入图片描述

    如宿主机的/data目录与容器的/container/data目录绑定,容器进程向该目录写数据直接写在宿主机目录上,绕过容器文件系统建立关联,实现宿主机和容器内共享数据内容,二者数据读写同步。

    因此,如果容器销毁了,那么对应的存储卷还是存在的,也就是对应的数据还在。

    二.为什么需要存储卷

  • 数据丢失问题:容器分无状态(数据无需持久化)和有状态(数据需持久化)两类,容器更擅长无状态应用,因未持久化数据的容器根目录生命周期同容器,删除容器读写层消失。但实际有数据持久化需求,故Docker提出卷(Volume)概念。
  • 性能问题:UnionFS(联合文件系统) 对修改删除等操作效率低,对 I/O 要求高的应用(如 redis),底层存储时性能要求高(比如需要找某个文件就需要从顶层往底层找,耗性能)。
  • 宿主机和容器互访不方便:宿主机与容器互访需通过 docker cp 完成,操作困难。
  • 容器和容器共享不方便。
  • 因此 Docker Volume的出现正是为了解决上面的四大核心问题。

    三.存储卷分类

    首先可以理解为挂载就是给一个设备提供一个入口,而这个入口可以认为是对应的目录,如:磁盘挂载到设备上;也可以理解成新建了一个快捷方式,两者对对应的目录下的内容是一起操作的(同时维护的是一个内容),有一个同步过程。

    在这里插入图片描述

  • Volume(Docker 管理卷):
    • 默认映射到宿主机的 /var/lib/docker/volumes 目录。
    • 用户只需指定容器内的挂载点,宿主机下的目录由容器引擎 daemon 自行创建或使用已有目录。
    • 解耦用户与存储目录的耦合关系,适合临时存储,但用户无法指定宿主机目录(比如两容器不想共用同一个对应的存储目录)。
  • Bind Mount(绑定数据卷):
    • 映射到宿主机指定路径,在宿主机和容器中都需指定特定路径建立关联。
    • 宿主机路径需人工指定(优缺点与上面相反,需要自己手动判断对应目录是否有其他东西需要移除)。
  • Tmpfs Mount(临时数据卷):
    • 映射到宿主机内存中,容器停止后,tmpfs mounts 被移除,数据丢失。
    • 用于高性能的临时数据存储(快,安全)。

    总结下:

    对应的所有的volumes的操作:比如 docker volume ls /var/lib/docker/volumes -v 这些只是对管理卷(命名卷 匿名卷的操作);而绑定卷 临时卷 都是无效的,也就是上面的那些操作指令,看不了对应的绑定卷 临时卷的信息;要想看就inspect 容器进行mount 挂载查看。

    四.存储卷使用之管理卷

    Volume命令操作

    1·docker volume create

  • 功能:创建存储卷。
  • 语法:docker volume create [OPTIONS] [VOLUME]。
  • 关键参数:
    • -d, –driver:指定驱动,默认是 local。
    • –label:指定元数据。

    使用如下:

    不起名字,系统自动默认:

    在这里插入图片描述

    指定对应名字:

    在这里插入图片描述

    下面看下详情:

    在这里插入图片描述 在这里插入图片描述

    • 发现里面没有东西。

    也可以指定标签进行创建:

    在这里插入图片描述

    在这里插入图片描述

    2·docker volume inspect

  • 功能:查看 Docker 卷的详细信息。
  • 语法:docker volume inspect [OPTIONS] VOLUME [VOLUME…]
  • 关键参数:
    • -f:指定输出格式,如 JSON 格式。

    使用如下:

    在这里插入图片描述

    3·docker volume ls

  • 功能:列出卷。
  • 语法:docker volume ls [OPTIONS]。
  • 关键参数:
    • –format:指定格式,如json、table。
    • –filter,-f:过滤。
    • -q:仅显示名称。

    使用如下:

    json格式查看:

    在这里插入图片描述

    过滤查询与只显示名字:

    在这里插入图片描述 在这里插入图片描述

    • 这可以联合其他命令进行批量操作。

    4·docker volume rm

  • 功能:删除 Docker 卷,要求卷未被容器使用。
  • 语法:docker volume rm [OPTIONS] VOLUME [VOLUME…](Shell 环境下)。
  • 关键参数:
    • -f, –force:强制删除卷。

    使用如下:

    在这里插入图片描述

    • 成功给没有容器使用的卷写入数据。

    在这里插入图片描述

    • 成功清除容器不使用的卷。

    5·docker volume prune

  • 命令:docker volume prune
  • 功能:删除不使用的本地卷(匿名卷)
  • 语法:docker volume prune [OPTIONS]
  • 关键参数:
    • –filter:过滤
    • -f, –force:不提示是否删除

    使用如下:

    在这里插入图片描述

    • 这里只会删除不使用的匿名卷,如果是命名卷就需要rm来操作。

    下面总结下这些命令:

    命令别名功能备注
    docker volume create 创建存储卷
    docker volume inspect 显示存储卷详细信息
    docker volume ls docker volume list 列出存储卷
    docker volume prune 清理所有无用数据卷
    docker volume rm 删除卷,使用中的无法删除

    -v 或者–mount 指定

    -v模式

  • 功能:完成目录映射(默认读写方式)。
  • 语法:docker run -v name:directory[:options] ……..
  • 参数:
    • 第一个参数:卷名称
    • 第二个参数:卷映射到容器的目录(指定容器目录)
    • 第三个参数:选项,如 ro 表示 readonly
  • 说明:-v 和 –mount 都可以完成管理卷的创建。
  • 下面以nginx容器来测试下无选项模式:

    映射对应容器目录到系统默认位置的n2v对应下面(手动指定了卷名):

    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    • 发现映射成功。

    下面手动删除容器对应的目录文件:

    在这里插入图片描述

    • 发现删除后对应的卷下文件也没有了。

    下面再加上ro选项试试:

    在这里插入图片描述

    • read only模式:说明对应的映射后,对应卷内容不能删,映射前的容器对应位置也就不能删除。

    –mount 模式

  • 功能:完成目录映射。
  • 语法:在 Shell 中使用 –mount '<key>=<value>,<key>=<value>' 的格式。
  • 关键参数:
    • type:类型表示为 bind、volume 或 tmpfs。
    • source / src:对于命名卷,这是卷的名称;对于匿名卷,省略此字段。
    • destination / dst / target:文件或目录挂载在容器中的路径。
    • ro / readonly:以只读方式挂载。

    下面测试下:

    在这里插入图片描述

    • 指定卷名+映射的容器的目录。

    在这里插入图片描述 在这里插入图片描述

    • 发现容器内删除,对应的卷内也就没了。

    在这里插入图片描述

    • 使用匿名卷,效果也是一样的。

    在这里插入图片描述

    • 指定对应的ro,只读形式,对应映射内容就无法删除了。

    在这里插入图片描述

    在这里插入图片描述

    • 查看容器信息可以看到对应的挂载信息。

    Dockerfile 匿名卷

    简单介绍下:

    通过 Dockerfile 的 VOLUME 可创建 docker 管理卷, dockerfile 的 VOLUME 指令在镜像中创建 Data Volume,用该镜像创建的容器会有挂载点,但是 VOLUME 指令创建的挂载点,无法指定主机对应目录,由 docker 随机生成。

    管理卷之宿主机与容器之间同步

    1.下面验证下当容器与宿主机绑定管理卷的时候,宿主机改变对应内容,容器会进行同步修改。

    在这里插入图片描述

    • 创建管理卷,然后进行对应容器启动绑定。

    在这里插入图片描述

    • 发现看到的还是这个节界面。

    下面修改下宿主机对应管理卷位置映射的容器对应html:

    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    • 发现确实改变了。

    因此可以得到,进行容器管理卷映射后,宿主机和容器相当于看到同一份资源,修改是同步的(容器没有使用ro选项)。

    2.验证当开启了ro模式映射的时候,容器修改文件是否可以是否可以同步,然后再试试宿主机能否通过管理卷位置进行文件修改是否可以,是否可以同步?

    在这里插入图片描述

    • 启动ro模式容器。

    在这里插入图片描述

    • ro模式容器内部不能修改。

    在这里插入图片描述

    在这里插入图片描述

    • 在宿主机对应存储卷位置可以进行修改。 在这里插入图片描述

    在这里插入图片描述

    • 发现容器内也成功被修改了。

    因此,如果开了ro模式,对应的容器对应映射位置的目录及文件是只能读取的,但是宿主机可以根据管理卷位置进行修改。

    对应的–mount的效果和-v对应的效果一样,就不演示了。

    管理卷的生命周期验证

    在这里插入图片描述

    • 进行容器与管理卷绑定。

    在这里插入图片描述 在这里插入图片描述

    • 停止并删除容器,发现管理卷内容保存下来了。

    在这里插入图片描述

    • 只有删除管理卷,对应的内容才会没有。

    因此,当管理卷与容器绑定后,删除容器,管理卷对应映射内容不会消失,只有删除管理卷后才会消失。

    管理卷共享验证

    下面创建三个容器分别绑定同一个宿主机的管理卷(ro模式不影响):

    在这里插入图片描述

    然后修改宿主机的对应映射文件:

    在这里插入图片描述 在这里插入图片描述

    • 发现三个容器对应的内容全部同步变化。

    总结,绑定同一个宿主机的管理卷的容器们都是共享这个宿主机的管理卷内容的。

    五.存储卷使用之绑定卷

    这里可以使用-v或者–mount都可以创建绑定卷。

    -v 创建

  • 功能:完成卷映射。
  • 语法:docker run -v name:directory[:options] …
  • 参数:
    • 第一个参数:宿主机目录(和管理卷不一样,但是是听宿主机的,宿主机对应目录为空,容器自动同步空,与管理卷不同;比如nginx就是这样,但是如mysql必须有自带初始化数据,此时就会听mysql对应目录下的内容同步到宿主机绑定目录里,因此此时对应宿主机要绑定的目录就不能存在,等待挂载的时候自动创建,然后完成所有mysql数据同步到宿主机对应创建的目录里。)。
    • 第二个参数:卷映射到容器的目录。
    • 第三个参数:选项,如 ro 表示 readonly。

    演示下:

    在这里插入图片描述 在这里插入图片描述

    • 进入容器发现,被宿主机目录同步过来了,是空的,然后进行容器写,看宿主机是否能收到。

    在这里插入图片描述

    • 发现是同步的。

    –mount创建

  • 功能:完成目录映射。
  • 语法:在Shell中使用 –mount '<key>=<value>,<key>=<value>' 格式。
  • 关键参数:
    • type:表示类型,可以是bind、volume或tmpfs(默认是volume,但是其这里必须声明是bind)。
    • source、src:宿主机目录(与管理卷不同)。
    • destination、dst、target:文件或目录在容器中的挂载路径。
    • ro、readonly:以只读方式挂载。

    演示下:

    在这里插入图片描述 在这里插入图片描述

    • 进行mount模式绑定容器,inspect容器后看到对应绑定信息。

    在这里插入图片描述

    • 成功同步,容器内对应映射目录是空的。

    在这里插入图片描述

    • 容器修改对应目录内容,宿主机成功收到。

    总结下,对应的绑定卷的时候,是宿主机为主,如果宿主机对应目录没内容,就会同步到容器,发生类似覆盖等效果(变空)。

    验证对应的宿主机绑定目录不存在以及对应目录下两个内容相同,以宿主机为主还是容器?

    –mount 模式

    在这里插入图片描述

    • 这里如果对应的宿主机目录不存在就会提示失败。

    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    • 下面拷贝一份改过的index.html文件到绑定的宿主机目录中,然后成功绑定。

    在这里插入图片描述

    • 发现容器对应的也修改了,说明同名文件还是以宿主机对应为主。

    -v 模式

    在这里插入图片描述

    • 这里发现对应的-v方式,如果宿主机指定目录不存在会自己创建。

    在这里插入图片描述

    • 这里看出来,之前的bind目录下有被改过的index.html;然后新容器绑定启动后,发现也被宿主机的给同步了。

    总结下,对于绑定卷创建:-v模式如果对应的宿主目录不存在会自动生成,但是–mount不会,直接报错;然后两者都会进行以宿主机目录为主同步(比如宿主机和容器对应绑定目录文件有相同的)。

    也就是说如果是-v 模式,如果如果宿主机对应目录存在就以宿主机为主,不存在就在构建容器时候自动创建,从容器中同步过来;但是- -mount的话,宿主机不存在就报错,存在还是以宿主机为主。

    其次就是同样绑定卷也是多容器共享的,这里就不演示了。

    六.存储卷使用之临时卷

    • 临时卷tmpfs:数据存于内存(存储在容器所运行的宿主机的内存中),在容器(不在对文件系统内)和宿主机之外。
    • tmpfs局限性: 无法在容器间共享挂载; 仅在Linux上运行Docker时可用。
    • 可见性: tmpfs只在容器的命名空间内有效,宿主机默认感知不到它的存在,自然也没法直接往里面写文件。
    • 重点: 容器停止或重启时,对应容器对应的那块内存中的数据会被操作系统自动清除

    1.创建卷 – 方式一:指定–tmpfs创建:

    • 功能:完成临时卷映射;
    • 语法:run的时候使用–tmpfs /app。

    演示下:

    在这里插入图片描述

    • 在容器内部创建临时卷目录,对应的内容还是在内存中。

    下面inspect看下容器详情:

    在这里插入图片描述 在这里插入图片描述

    • 发现对应的临时卷在容器对应位置,因为这里采取的是–tmfs方式创建的临时卷,故mounts这里看不到(只有-v –mount方式才能看到)。

    在这里插入图片描述

    • 进入容器对挂载内存的目录,进去写东西,然后重启容器,发现就没了,因此,可以看出对应的容器那个目录是挂载到了内存中,与内存是同步的。

    2.创建卷 – 方式二:–mount指定参数创建

    • 功能:完成目录映射
    • 语法:–mount '<key>=<value>,<key>=<value>'
    • 关键参数:
      • type:类型为bind、volume或tmpfs
      • destination、dst、target:挂载在容器中的路径
      • tmpfs-size:tmpfs挂载大小(字节为单位),默认无限制
      • tmpfs-mode:tmpfs的八进制文件模式,如700或0770,默认为1777或全局可写。

    演示下:

    在这里插入图片描述

    • 进行对应的临时卷创建。

    在这里插入图片描述

    • 同样,重启容器后映射在内存的数据就没了。

    总结下:

    都是进行对应的目录(必须是绝对目录,因为输入目录是从容器视角来看的)的挂载于内存中,然后容器中创建对应临时卷,内容是映射到了内存中(由容器和内存共同维护,一个变化整体变化),因此会看到如果容器断开 重启之类,那么对应的容器对应的在宿主机的那块内存就会情况,因此同步到容器对应的临时卷,对应内容也就没了。

    验证创建容器中已经存在目录的临时卷情景以及填充内容后重启后效果

    在这里插入图片描述

    • 首先把对应容器的html那个主页作为临时卷,发现映射到内存后就被覆盖掉成空了。

    在这里插入图片描述

    在这里插入图片描述

    • 重新写入后,对应浏览器能访问到。

    然后重启容器:

    在这里插入图片描述 在这里插入图片描述

    • 内容消失,无法访问。

    总结下:

    对应开始绑定容器的临时卷的时候,以内存为主,如果对应容器目录有东西就被内存覆盖(空内存),之后就是两者同时进行内容操作(也就是写的时候主要还是容器,重启等就是内存进行同步了)。

    在这里插入图片描述

    验证–mount选项创建临时卷使用tmpfs-size

    在这里插入图片描述

    • 这里设置成对应挂载目录容量最大为1m。

    下面inspect查看容器信息:

    在这里插入图片描述

    • 从容器角度可以看到对应的大小,以及挂载目录等。

    在这里插入图片描述

    • 从宿主机视角看到对应的挂载信息(这里源目录是内存故看到是空)。

    在这里插入图片描述

    • 最后发现,超过了对应目录最大内存限制,无法拷贝。

    验证对容器内文件操作及对应容器内临时卷里内容操作是否能被宿主机

    在这里插入图片描述

    • 启动对应的容器,并在里面执行bash。

    在这里插入图片描述 在这里插入图片描述

    • merged:容器里最终看到的“合并后”文件。

    • diff:该层自己新增/改/删的文件(只存当前层独有的改动)。

    • 也就是diff 是当前层自己改了啥,merged 是把这些改动和其他层合起来给你看的结果。

    • 这里能看到对应的容器内文件操作(除了临时卷外)都是能被宿主机看到的。

    下面看下操作临时卷情况:

    在这里插入图片描述 在这里插入图片描述

    • 发现此时就无法查到(因为是基于内存的操作,宿主机查硬盘,自然无法查到)。

    总结下:

    对于临时卷的话,是基于内存的,如果容器进行对应临时卷内容修改,是也会在内存中进行的修改,因此宿主机默认是看不到的(查磁盘),也很难看到,但是对于管理卷 绑定卷 都是同步可见的。

    七.MySQL容器基于绑定卷后销毁进行数据恢复测试

    在这里插入图片描述

    进入Docker hub对应的mysql主页找到对应位置:

    在这里插入图片描述

    进行基于绑定卷来启动msyql容器:

    在这里插入图片描述

    • 这里对应的宿主机绑定的目录可以使用相对,因为宿主机会自动识别。

    在这里插入图片描述

    • inspect可以查看到对应绑定关系。

    下面进行连接mysql,然后模拟数据:

    在这里插入图片描述

    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    • 数据成功被插入,说明这个mysql是有数据的。

    在这里插入图片描述

    • 删除mysql这个容器,然后去宿主机对应的绑定卷位置发现是存在对应数据的。

    在这里插入图片描述

    • 起一个新的mysql容器,绑定之前mysql的那个绑定卷。

    在这里插入图片描述

    • 发现对应的数据复原了。

    因此总结下:

    一般对应数据库这种存储数据启动的容器,就可以采用这种管理卷 绑定卷的模式进行挂载,这样容器销毁,数据还在。

    八.对应的卷使用的常见问题

    使用场景

  • volume:是Docker宿主机文件系统一部分,适用于无需规划具体目录的场景(如测试环境)。
  • bind:完全依赖主机的目录结构和操作系统,适用于需提前规划目录的情况(如MySQL需大空间且其他服务不占用时,用volume不合适)。
  • tmpfs:用于敏感文件存储,文件不存储在宿主机和容器的可写层中(如隐私信息,敏感信息)。
  • 使用时候常见问题

  • 跨主机使用:Docker存储卷基于宿主机本地文件系统,无法直接跨主机共享,需运维搭建NFS等共享存储,未来应用趋向存储与数据分离,采用分布式存储(比如那些有状态的服务,需要记录那些状态变化)。
  • 启动参数未知:容器启动选项多,重启易遗忘参数,需文件保存启动配置,容器编排工具可批量操作容器,如开源K8s及云厂商企业版编排软件。
  • 复杂场景仍然需要运维:有状态集群化组件(如MySQL主从)部署维护依赖运维知识和经验,复杂场景难以依靠工具,仍需人力。
  • 九.本篇小结

    本文全面介绍 Docker 存储卷,包括各类命令用法、不同卷模式特点及应用场景,通过实例演示操作,最后点明使用中常见问题,助于掌握 Docker 存储卷知识。

    赞(0)
    未经允许不得转载:171主机测评 » Docker存储卷深度剖析:从创建到实战,解锁容器数据持久化的终极奥秘
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址