type
status
date
slug
summary
tags
category
icon
password
1、概述
Docker 提供了两种存放数据的方式:
- 由 storage driver 管理的镜像层和容器层:并将数据存储在容器的可写层中,存于主机文件系统中的指定区域。容器的可写层在容器被删除后不会持久化,适合存储运行时产生的临时数据。
- Data Volume:Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。Volumes 可以持久保存数据,独立于容器的生命周期。 因此,当删除容器时,Docker 不会自动删除 Volumes。
2、storage driver
storage driver 维护的数据不会做持久化操作,当容器被销毁后,storage driver 的数据也会随之销毁。对于某些容器,直接将数据放在由 storage driver 维护的层中是很好的选择,比如那些无状态的应用。无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。
Docker storage driver 实现了镜像的分层结构,Docker 支持多种 storage driver,有 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS 等。Docker 安装时会根据当前系统的配置选择默认的 driver。默认 driver 具有最好的稳定性,因为默认 driver 在发行版上经过了严格的测试。
可以通过 docker info 命令来查看 Docker 当前的 storage driver。
3、Docker volumes
在 Docker 中,要想实现数据的持久化,即数据不随着 Container 的结束而结束,需要将数据从宿主机挂载到容器中。Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。
Data Volume 有以下特点:
- Data Volume是目录或文件,而非没有格式化的磁盘(块设备)。
- 容器可以读写 volume 中的数据。
- volume 数据可以被永久地保存,即使使用它的容器已经销毁。
因为 volume 实际上是 docker host 文件系统的一部分,所以 volume 的容量取决于文件系统当前未使用的空间,目前还没有方法设置 volume 的容量。
在具体的使用上,docker 提供了两种类型的 volume
- bind mount
- docker managed volume
3.1 bind mount
bind mount 是将 host 上已存在的目录或文件mount到容器。bind mount 的方式会隐藏掉容器被挂载目录里面的内容(如果非空的话)。bind mount 有两种语法:
1、docker run 使用参数
-v
或者--volume
,语法为:例如 docker host上有目录 $HOME/htdocs,通过 -v 将其 mount 到 httpd 容器,该目录可读可写(默认是可读可写)。
2、Docker 17.06 之后,docker run 可以使用参数
--mount
,由一组键值对组成,用逗号进行分割。语法为:-v
和–-mount
的区别:
- 使用
-v
的时候,如果在 Docker Host 不存在要挂载的文件或者目录,Docker 将会自动进行创建,通常是一个目录。
- 使用
–-mount
的时候,如果在 Docker Host 不存在要挂载的文件或者目录,Docker 不会自动创建目录,并生成一个错误。
使用注意:
- bind mount 可以执行目录,也可以单独指定一个文件。指定单独文件时 host 中的源文件必须要存在,不然会当作一个新目录 bind mount 给容器。
- bind mount 需要指定host文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他 host,而该 host 没有要 mount 的数据或者数据不在相同的路径时,操作会失败。
3.2 docker managed volume
docker managed volume 与 bind mount 在使用上的最大区别是不需要指定 mount 源,指明 mount point 就行了。volume 由 Docker 来进行管理,在打包的时候可以把 volume 的内容一起打包,所以有良好的迁移性。
volume 的默认目录为
/var/lib/docker/volumes
,所有 volume 的数据内容都保存在该目录下,每一个目录对应一个 volume。在创建 volume 的时候如果没有指定名称,docker 就会生成一个随机字符串命名。3.2.1 创建volume
我们可以通过下面命令来创建一个 valume,会在
/var/lib/docker/volumes
下生成一个指定 volume 命名的目录。如果没有指定 volume 的名称,docker 就会生成一个随机字符串作为命名。3.2.2 挂载volume
我们也可以不用手动创建 volume,在
docker run
中使用 -v
或者 --mount
参数挂载卷,如果卷不存在的话就会自动创建。挂载 volume 使用
-v
或者 –mount
参数,用法和 bind mount 类似。如果没有指定 volume 的名称,docker 就会生成一个随机字符串作为命名。例如把容器的
/usr/share/nginx/html/
目录挂载到宿主机上一个名为 test 的卷,然后在 /var/lib/docker/volumes
目录下会生成一个 test 的目录。如果 mount point 指向的是已有目录,原有数据会被复制到 volume 中。
3.2.3 查看volume
目前,docker volume 只能查看 docker managed volume,还看不到 bind mount;同时也无法知道 volume 对应的容器,这些信息还得靠 docker inspect。
3.2.4 删除volume
volume 是被设计用来持久化数据的,它的生命周期独立于容器。所以 Docker 不会在容器被删除后自动删除 volume,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。我们需要手动删除数据卷。
如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用
docker rm -v
这个命令。- Author:mcbilla
- URL:http://mcbilla.com/article/0ff85c7d-7c1d-80a4-b730-eb2c35d8221b
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts