Docker容器数据卷


我们知道docker容器相当于一个小型linux系统,docker容器被删除后,这个系统也就消失了,如果数据都在容器中,那么删除容器后数据就会丢失,如mysql容器中数据库表数据,docker提供了数据卷来对容器内的数据进行持久化。

数据卷挂载

作用:将容器内的文件映射(挂载)到宿主机,类似硬链接。

数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性:

  1. 数据卷可以在容器之间共享和重用。
  2. 对数据卷的更改会立即生效。
  3. 对数据卷的更新不会影响镜像。
  4. 和容器的生命周期是分离的,数据卷会一直存在,除非被清理。
  5. 数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会相互影响。

上图表示了docker挂载卷的3种方式:volume、bind mount、tmpfs mounts;

volume挂载方式

volume意思为“卷”,可在执行docker run命令时使用-v选项挂载卷,docker管理数据卷的目录一般为/var/lib/docker/volumes/

匿名挂载

命令示例:docker run -v <容器内路径> centos;此方式为匿名挂载,docker将分配一个匿名的数据卷(如上图16进制字符构成的文件夹),将容器内的路径硬链接到该卷下的_data目录。

具名挂载

命令示例:docker run -v <卷名称>:<容器内路径> centos;此方式为具名挂载,docker将分配一个有具体名称的数据卷(如上图mycentos-v文件夹),如果该名称卷已经存在则直接使用而不再创建,将容器内的路径硬链接到该卷下的_data目录。

数据卷挂载文件覆盖问题:

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

这两个规则都非常重要,灵活利用第一个规则可以帮助我们初始化数据卷中的内容。掌握第二个规则可以保证挂载数据卷后的数据总是你期望的结果。

除此之外,也可以在通过Dockerfile构建镜像时指定挂载出匿名数据卷。

bind mounts绑定挂载

绑定文件系统的文件。

命令示例:docker run -v <宿主机路径>:<容器内路径> centos ;此方式为指定路径挂载,此挂载方式,docker直接将容器内的路径硬链接到指定的宿主机目录,有以下几点值得注意:

  • 且宿主机路径必须是绝对路径
  • 无论宿主机路径还是容器内路径,路径不存在则被创建
  • 文件覆盖规则:【宿主机 -> 容器内】
  • 此种挂载方式无法通过docker volume管理卷。

只读挂载

过ro选项指定挂载的数据卷是只读的,意味着容器无法对挂载的文件进行修改,只能读,即挂载的文件只允许宿主机单向修改。rw便是可读可写,默认卷读写性质为rw。

  • 匿名挂载的只读:匿名挂载不支持只读,即使使用--read-only选项进行只读限定,也不会生效,卷读写性质依旧为rw

  • 具名挂载的只读:命令示例:docker run -v <卷名称>:<容器内路径>:ro centos

  • bind mounts挂载的只读:命令示例:docker run -v <宿主机路径>:<容器内路径>:ro centos;文件覆盖情况【宿主机 -> 容器内】且是强制覆盖,且容器无法对该目录的文件进行修改

tmpfs临时文件系统

volume挂载方式(卷挂载)和bind mounts挂载方式(绑定挂载)允许在主机和容器之间共享文件,以便即使在容器停止后也可以保留数据。Linux上运行的Docker,有第三个挂载方式选择:tmpfs,即临时的文件系统。

以tmpfs挂载方式创建容器时,容器可以在容器的可写层外创建文件。与卷和绑定挂载相反,tmpfs挂载是临时的,并且仅保留在主机内存中。当容器停止时,将tmpfs删除。这对于临时存储不希望在主机或容器可写层中保留的敏感文件很有用。

tmpfs挂载的限制:

  • 与卷和绑定挂载不同,tmpfs无法在容器之间共享
  • 只有在Linux上运行的Docker才能使用此功能

命令实例:docker run --rm -it --tmpfs /root centos

tmpfs挂载允许两个配置选项,都不是必需的。如果需要指定这些选项,则必须使用该--mount选项,因为该–tmpfs选项不支持它们:

  • tmpfs-size:tmpfs挂载的大小(单位:字节),默认无限
  • tmpfs-mode:tmpfs的文件模式,为八进制,即linux系统下的文件读写权限的数字标识,例如700或0770,默认值为1777(全局可写)

命令实例:docker run --rm -it --mount type=tmpfs,destination=/root,tmpfs-mode=1770 centos

关于--mount--tmpfs的区别:https://docs.docker.com/storage/tmpfs/#use-a-tmpfs-mount-in-a-container

数据卷管理

docker volume

作用:可以通过docker volume命令管理数据卷

常见命令格式:docker volume <option>

  • docker volume ls:查看所有数据卷
  • docker volume rm <卷名称>:删除数据卷,还有容器使用的数据卷不可被删除
  • docker volume inspect <卷名称>:查看数据卷详情
  • docker volume create <卷名称>:创建一个数据卷

数据卷容器

容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,这个挂载数据卷的“父”容器称之为数据卷容器;

因为数据卷会存在直到没有容器使用为止(除非手动强制删除),像多个数据库容器场景下,容器之间需要传递共享数据卷,使用容器维护数据卷,这就是数据卷容器。

–volumes-from

可在执行docker run命令时使用--volumes-from选项从其它容器挂载卷。

命令示例:docker run -it --volumes-from=<容器id或容器名> centos,数据覆盖情况:【卷 -> 容器内】;

我们可以把--volumes-from选项比作继承,上图中,容器X挂载出volume1、volume2,数据卷容器A和容器B继承自容器X,容器C继承容器A,容器D继承容器B,最终ABCD容器都挂载了volume1、volume2,无论哪个容器对数据卷内的文件进行修改,其它容器都能同步更新到,容器X便是数据卷容器。