Skip to content

Docker 实验室(三):Docker 的数据管理。

发布于: at 16:05

之前说到 Docker 的所有容器都是隔离的,也就带来了几个新问题:

1.容器内的数据如何持久化?

2.多个数据容器如何共享数据?

存储类型

Docker 提供了一下三种常用的存储类型接口。

tmpfs 挂载

tmpfs 的特点在于数据存储在内存中,容器重启后数据也就被直接销毁了。对于临时性的日志,类似日志、构建缓存、一次性生成文件就非常的合适。

Docker 在启动容器的时候指定临时挂载目录有两种方式: 1.—tmpfs <目录> 直接指定挂载目录。

docker run --tmpfs /test <some image>

Docker 挂载 Tmpfs 文件目录 这里在执行之后查了下容器信息,可以看到 Tmpfs 下面有 /test 目录了。

Bind mounts 绑定挂载

直接把宿主机上的目录绑定到容器内部,映射到本地的内容就相当于是可以自己定义的了。这种方式应该才是大家最熟悉以及最常用的一场方式,从 Docker 最开始持久化数据一般就是这种。

Docker bind mounts 有两个挂载命令: 1.-v <宿主机目录>:<容器目录>[:] 直接指定挂载目录,最后一个 selinux label 配置是可以省略的。通常有三个配置:ro:可读可写、z:私有,容器可共享、Z:私有、容器不可共享。

2.—mount type=bind,source=<宿主机目录>,target=<容器目录>[,readonly] 与上面的 -v 一样,只是这里是使用 —mount 来指定挂载。readonly 是可选的,用来指定目录为只读的。

volume 卷挂载

volume 是 Docker 现在最推荐使用的一种挂载方式。tmpfs 以及 bind mounts 都是基于宿主机目录来进行映射以及绑定,但是 volume 有了数据来源驱动,也就是说数据不仅仅局限于宿主机了。

先看下使用 volume 的基本语法,和 bind mounts 一样,还是有两个挂载命令。 1.-v <Docker volume 名称>:<容器目录>[:] 直接指定挂载目录,最后一个 selinux label 配置是可以省略的。通常有三个配置:ro:可读可写、z:私有,容器可共享、Z:私有、容器不可共享。在挂载的时候需要直接指定 volume 的名称,所以需要先创建 volume。

2.—mount type=volume,source=<Docker volume 名称>,target=<容器目录>[,readonly][,volume-opt] 和上面 bind mounts 一直,但是多了 volume-opt 选项,用来指定 volume 的一些配置。

这里我们列举比较常见的几种外挂存储的使用方式:

这里外部地址为 10.0.0.10 的 nfs 远程存储。当然,在实际使用的时候需要使用自己的 nfs 地址。这里配置了饿 volume-opt 选项,加起来就是一个完整的 nfs 配置信息。

docker run -d \
  --mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10' \
  hello-world

直接挂载本地磁盘到容器内部目录,Docker 在实现本地磁盘挂载的时候完全遵循 mount 命令的挂载配置,并没有特殊配置所以这里的 volume-opt 可以直接参考 mount 使用方式进行配置。这里挂载的是 /dev/loop5 磁盘到 /external-drive 目录。

docker run -d \
  --mount 'type=volume,dst=/external-drive,volume-driver=local,volume-opt=device=/dev/loop5,volume-opt=type=ext4' \
  hello-world

除了支持外部的挂载以外,volume 提供了 volumes-from 支持直接从一个容器内进行挂载。

Docker volumes-from 示例

上述示例做了以下步骤:

1.启动了一个新容器,并且挂载了 /test 临时目录。

2./test 目录下新建了 test1.txt、test2.txt 两个文件。

3./opt 目录下新建了 test3.txt、test4.txt 文件。

4.启动了一个新容器,并且使用 —volumes-from 指定第一个容器来挂载。

这个时候可以看到,手动挂载绑定的目录共享了,但是容器内部自己的目录并没有共享。基于这个原理完全可以进行在其他容器内部备份、恢复数据。