..

【翻译】Docker应用数据存储

容器内应用创建的数据默认在是容器内部的临时可写入层,这意味着一下问题:

  • 当成容器不在不在运行状态时候,这部分数据不会持久化,数据会被丢失。也不方便和其他容器共享数据。
  • 数据被写入到容器的临时可写入层,这导致数据迁移困难。
  • 数据写入容器临时读写层,这需要操作系统内核提供数据写入驱动,这个额外的抽象,会牺牲一部分写入的性能。

数据保存在宿主机上,意味着你不需要担心容器生命周期结束以后数据会丢失,他会一直保存在宿主的磁盘上。对于在宿主机上存储文件,Docker提供能了两种方式。这两种方式分别是,挂载文件夹和挂载数据卷,当然你在Linux上运行Docker的时候,你也可以使用tmpfs挂载节点。

选择正确的挂载方式

无论你使用哪种挂载方式,被挂载的文件在容器中表现形式就好像他们正在存在容器中一样,在容器表现出来的形式为文件夹或者是文件。

用一张图来说说明上面介绍到的三种挂载方式之间的区别 20181107

  • 容器卷: 数据存在宿主机上的一个特定目录(在Linux上: /var/lib/docker/volumes/),除了Docker自身进程,其他的进程不应该修改这个目录。挂载数据卷也是目前容器存储数据的最佳方式。
  • 挂载目录: 能够保存在宿主机的任何目录,可能保存在一个非常重要的目录中,任何时候这个目录能够其他任何进程读写和修改。
  • tmpfs: 只会讲数据保存在宿主机的内存中,永远不会将数据保存宿主的磁盘上。

几种挂载方式的详细说明

  • 容器卷:由Docker创建并且管理,你也可以手动使用docker volume create命令创建一个容器卷,或者是在服务启动的时候自动创建。

当你创建好了容器卷以后,就会在宿主机上创建某个目录,这个目录有Docker进程来管理,你可以将这个容器卷挂载到容器中,这有点类似于文件挂载的方式,只不过这个目录是由Docker管理,并且与宿主机器上的其他服务隔绝开来。

当你挂载一个容器的时候,这个容器可能是有名字的,也可能是匿名的,匿名的容器被分配了一个随机的以为的名字,匿名容器和有名字的容器在使用方式和表现形式上是一样的。 一个容器卷能够被挂载在躲着容器的内部,当应用容器都停止以后,容器卷还是存在,它不会自动删除,除非你使用docker volume prune命令来删除它。

容器卷支持给定一个容器卷驱动,他支持将数据保存在远程主机或者是云服务上。

  • 文件挂载: 在Docker早期,文件挂载非常有用,所有宿主机上的进程都能读取这个文件。相比于挂载容器卷,文件挂载以后有一些功能上的限制。当你在使用一个被从宿主机器上挂载进来的文件以后,这个文件都是直接引用的在宿主机器上文件的绝对地址。如果文件宿主机中不存在,Docker进程会自动的创建它,文件挂载的性能不错,但是它依赖宿主上的特定文件系统以及目录存储结构。如果你正在开发一个Docker的应用,请考虑使用容器卷来替代挂载文件的方式。

文件挂载后的隐私问题,这有利有弊,它给了你更大的权利,容器中的应用能够删除,修改,读取被挂载进来的目录,这只能会影响其他的进程服务。你必须权衡利弊。

对于挂载容器卷或者挂载文件,他们的命令行都是一样的,使用--volume或者-v选项,对于tmpfs挂载稍有不同,它使用--tmpfs选项。然而在17.06 以及更新的版本里面,我们推荐使用--mount来挂载容器卷或者文件。

容器卷最佳实践

容器卷是我们推荐的容器持久化方式,在使用过程中你需要注意如下事项:

  • 多个容器之间可以共享一个容器卷。如果在第一次挂载容器卷的时候,容器卷不存在,那么这个容器就会被自动创建,无论应用容器是否在运行或者停止,容器卷都不会被自动删除,除非你明确的手动删除他。
  • 当时宿主机器无法提供存储空间的时候,容器卷配置会失效。
  • 当你想存储文件在远程服务器或者云盘上时候,使用容器卷是非常好的选择。
  • 当你需要备份,转存,迁移数据的时候,容器卷也是非常好的选择。先关闭使用这个容器卷的容器,然后在再备份容器卷的文件加,类似于(/var/lib/docker/volumes/)。

文件挂载最佳实践

如果你真的需要挂载文件,你需要注意如下事项:

  • 容器与宿主机之间共享文件,挂载/etc/resolv.conf能够让宿主机和容器有相同的DNS配置。
  • 挂载源代码到编译的容器中,例如,你可以挂载源码和maven的target目录到容器,这样编译后的文件其他程序也能访问到。

tmpfs最佳实践

你当你不需要持久化文件的时候你才能选择这个方案,可能是应为安全原因,你需要写入机密数据到宿主机的内存中,你可以使用这个选项。

使用容器卷和文件挂载的技巧

  • 如果你挂载了一个空的容器卷到某个有文件的目录,那么这个目录中的文件会被拷贝中容器卷中。如果你如果你挂载某个不存在的容器卷,那么这个容器卷会被自动创建。初始化数据和容器卷的时候能够使用这样的方法。
  • 如果你挂载了某个有数据的容器卷到某个空目录,那么容器卷的文件也会被映射到目录中。你甚至可以将/mnt挂载到容器中,容器就能读取到usb存储器上的数据。

原文地址: https://docs.docker.com/storage/