docker 管理 应用数据(一) 存储 overview 概述

在Docker中管理数据

默认 所有被容器创建的文件都被存储在容器中的可写layer中,这就意味着

  • 当容器不再存在的时候数据也不会持久化,因此如果有其它进程也想用它的时候很难获取到容器中的数据。
  • 当容器运行时,容器的可写层会紧紧和宿主机进行绑定,不能将数据轻易地移动到别的地方去。
  • 对容器的可写层进行写操作时,需要存储引擎来管理文件系统,这个存储引擎提供了联合文件系统,使用了Linux的内核。这层额外的抽象和使用数据volume相比会减少性能,因为后者直接写在宿主机的文件系统中。

Docker 为容器提供了两种将文件存储进宿主机的方式,即使容器被停止也可以通过这种方式将数据持久化->volumes, and bind mounts. 如果在Linux中也可以使用tmpfs mount。Windows 不谈。

选择正确的挂载类型

不管你使用哪一种挂载方式,容器内部的数据都是一样的。会被作为容器文件系统中的文件夹或者单独的文件暴露出来。

一个简单而又形象地区别volumes, bind mounts, and tmpfs mounts 的方式就是 看数据存储在Docker 宿主机哪里。
docker 管理 应用数据(一) 存储 overview 概述_第1张图片

  • Volumes 被存储在宿主机文件系统中,它被Docker管理,目录在/var/lib/docker/volumes/ 下,给Docker进行不可以修改这个目录,Volumes 是Docker持久化数据的最好的方法。
  • Bind mounts 会被存储在宿主机系统的任意位置,这些位置也有可能是系统文件或者文件夹。非Docker进程能够随意对它进行修改。
  • tmpfs 挂载进内存当中,永远不会被刷进宿主机的系统文件当中。

更多关于挂载类型的细节

  • Volumes 被Docker 创建管理。你能够显示地使用docker volume create 命令来创建一个volume, 或者docker能够在容器创建或者service创建的时候来创建一个volume

    当创建一个volume的时候,它会被存储进Docker 宿主机当中。当你挂载volume的时候,响应的文件夹会被挂载进容器之中。这和bind mount相似,区别在于 volumes被docker管理,并且和宿主机中的其它核心功能隔离开。

    一个已有的volume能够同时被挂载进多个容器当中,即使没有运行中的容器使用这个volume,它仍然可以被Docker获取,不会自动被移除。你可以使用docker volume prune 来移除这个volume。

    当你挂载volume的时候,可以命名也可以匿名。匿名的volume第一次被挂载进容器的时候不会有一个明确的名字,所以Docker会随机命名来保证它在Docker宿主机中的唯一性。除了名字区别,其它并没有什么区别。

    volumes 同样支持volumes引擎使用,就像普通的一样可以在远端机器上存数据。

  • Bind mounts 早期Docker就有了。和volumes 相比 Bind mouints 有限制。当你使用bind mount的时候,宿主机的某一个文件或者文件夹会被挂载进容器。 文件或者目录会以完整路径的形式来被引用。文件或者目录不需要存在于宿主机中,不存在的话会被立刻建立起来。bind mounts 性能十分好,但是它们依赖于宿主机的文件系统,这个文件系统有特殊的目录结构。如果你正在开发一个新的docker应用,考虑使用named volumes 来代替。你不能使用Docker CLI 命令直接管理 bidn mounts。

bind mounts 能够访问敏感文件
bind mounts 可以通过container中的进程来改变宿主机的文件系统,包括创建修改删除重要的文件或者文件夹。这个能力很牛逼,它可能带来安全隐患,包括影响宿主机上的非docker进程。

  • tmfs mounts 临时的不会持久化进磁盘中,不管是在docker宿主机中还是container中。在容器的运行声明周期中能够被使用,来存储非持久化状态和敏感信息。比如 内部的swarm 服务就用的它。

  • named pipes

volumes几个好的利用案例

Volumes是持久化数据的首选方法。

  • 多容器共享数据。If you don’t explicitly create it, a volume is created the first time it is mounted into a container. When that container stops or is removed, the volume still exists. Multiple containers can mount the same volume simultaneously, either read-write or read-only. Volumes are only removed when you explicitly remove them.

  • When the Docker host is not guaranteed to have a given directory or file structure. Volumes help you decouple the configuration of the Docker host from the container runtime.

  • When you want to store your container’s data on a remote host or a cloud provider, rather than locally.

  • When you need to back up, restore, or migrate data from one Docker host to another, volumes are a better choice. You can stop containers using the volume, then back up the volume’s directory (such as /var/lib/docker/volumes/).

---------
多个容器间需要共享数据。如果volume没有手动被创建,它将会在首次挂载到某个容器之前被自动创建,当容器被停止或删除时,这个volume不会随之被删除。多个容器可以同时以rw或ro的方式挂载这个volume。只有手动指定删除volume,它才会被删除。

当宿主机并没有专用于Docker的文件系统结构时。使用volume可以使宿主机的配置与容器的运行解耦。

当你希望将数据保存到远程主机或云上。

当你希望在不同的宿主机直接备份/恢复/迁移数据时,volume是一个很好的选择。你可以停止运行使用volume的容器,然后直接备份volume所在的目录即可,如/var/lib/docker/volumes/
(from http://www.voidcn.com/article/p-kgpnrzfo-bxe.html)
----------

bind mounts的几个好的使用(最佳实践)

  • 宿主机和容器配置文件共享
  • 宿主机和容器共享开发源代码,比如maven的target目录,宿主机进行build的时候,容器也会自动获取build的代码。
    如果是docker项目,你的生产Dockerfile 要把生产的artifacts直接copy进image中,而不是依赖于bind mount。
  • 当你可以确定宿主机的文件系统结构应该与容器内部完全一致时。

bind mounts 和 volumes的小提示

  • 如果你把一个空的volume挂载进了容器文件夹中,并且容器中的文件夹有文件,这些容器中的文件会被copy进这个空的volume中。相似的,如果你启动了一个容器,这个volume不存在也会自动给你创建一个空的volume。这是一个备份数据的好方法。
  • 如果你挂载了非空的目录进了容器,不管是bind mount还是volume,并且这个目录在容器中已经存在了,都会被隐藏起来。这些被隐藏的文件不会被移除或者修改,但是在挂在期间是无法被访问的。

----------------心得区------------------
由此我们可以小小总结一下,volume和bind mounts的简单区别

  1. 文件位置,volume有一个特定的地方存储,而bind mounts是任意的。
  2. 安全控制,volume非docker进程无法进行修改,而bind mounts则是能被其它进程所修改的。
  3. 使用场景:volume有利于数据迁移,以及多容器共享数据。在remote 上也有益处。bind mounts就是 在本地 配置共享,项目上用用。

你可能感兴趣的:(docker)