在Docker中管理数据
预计阅读时间:9分钟
默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:
- 当该容器不再存在时,数据将不会持久保存,并且如果另一个进程需要它,则可能很难从容器中取出数据。
- 容器的可写层与运行容器的主机紧密耦合。您不能轻易地将数据移动到其他地方。
- 写入容器的可写层需要 存储驱动程序来管理文件系统。存储驱动程序使用Linux内核提供联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能 。
Docker为容器提供了两个选项来将文件存储在主机中,以便即使容器停止后文件也可以持久存储:卷和 绑定安装。如果您在Linux上运行Docker,则还可以使用tmpfs挂载。如果您在Windows上运行Docker,则还可以使用命名管道。
继续阅读有关这两种持久数据方式的更多信息。
选择正确的安装类型
无论您选择使用哪种类型的安装,容器中的数据看起来都是相同的。它在容器的文件系统中显示为目录或单个文件。
可视化卷,绑定挂载和tmpfs
挂载之间差异的一种简单方法是考虑数据在Docker主机上的位置。
-
卷存储在主机文件系统的一部分中,该文件系统由Docker管理(
/var/lib/docker/volumes/
在Linux上)。非Docker进程不应修改文件系统的这一部分。卷是在Docker中持久存储数据的最佳方法。 -
绑定挂载可以存储在主机系统上的任何位置。它们甚至可能是重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时对其进行修改。
-
tmpfs
挂载仅存储在主机系统的内存中,并且永远不会写入主机系统的文件系统中。
有关安装类型的更多详细信息
-
卷:由Docker创建和管理。您可以使用
docker volume create
命令显式创建卷,或者Docker可以在容器或服务创建期间创建卷。创建卷时,它存储在Docker主机上的目录中。将卷装入容器时,此目录就是装入容器的目录。这类似于绑定挂载的工作方式,除了卷由Docker管理并且与主机的核心功能隔离。
给定的体积可以同时安装到多个容器中。当没有正在运行的容器使用卷时,该卷仍可用于Docker,并且不会自动删除。您可以使用删除未使用的卷
docker volume prune
。挂载卷时,它可以命名为或匿名。匿名卷首次安装到容器中时,不会为其指定明确的名称,因此Docker为它们提供一个随机名称,该名称在给定的Docker主机中保证是唯一的。除了名称之外,命名卷和匿名卷的行为也相同。
卷还支持使用卷驱动程序,该驱动程序使您可以将数据存储在远程主机或云提供商上,以及其他可能性。
-
绑定挂载:自Docker早期以来可用。与卷相比,绑定安装的功能有限。使用绑定安装时,主机上的文件或目录将安装到容器中。文件或目录由主机上的完整路径引用。该文件或目录不需要在Docker主机上已经存在。如果尚不存在,则按需创建。绑定挂载性能很高,但是它们依赖于主机的文件系统,该文件系统具有可用的特定目录结构。如果要开发新的Docker应用程序,请考虑使用命名卷。您不能使用Docker CLI命令直接管理绑定安装。
绑定安装允许访问敏感文件
使用绑定挂载的好与坏的一个副作用是,您可以通过容器中运行的进程来更改主机文件系统 ,包括创建,修改或删除重要的系统文件或目录。这是一项强大的功能,可能会带来安全隐患,包括影响主机系统上的非Docker进程。
-
tmpfs mounts:
tmpfs
挂载不会持久化在磁盘上,无论是在Docker主机上还是在容器内。容器在其生存期内可以使用它来存储非持久状态或敏感信息。例如,在内部,群集服务使用tmpfs
安装将机密安装到服务的容器中。 -
命名管道:
npipe
挂载可用于Docker主机与容器之间的通信。常见用例是在容器内运行第三方工具,并使用命名管道连接到Docker Engine API。
绑定安装和卷都可以使用-v
或
--volume
标志安装到容器中,但是两者的语法略有不同。对于tmpfs
安装,您可以使用该--tmpfs
标志。我们建议--mount
对容器和服务,绑定安装,卷或tmpfs
安装使用该标志,因为语法更清晰。
卷的好用例
卷是将数据持久存储在Docker容器和服务中的首选方法。卷的一些用例包括:
-
在多个运行中的容器之间共享数据。如果未显式创建卷,则在首次将卷安装到容器中时将创建该卷。当该容器停止或卸下时,该卷仍然存在。多个容器可以同时装载相同的卷(读写或只读)。仅当您显式删除卷时,才删除它们。
-
不保证Docker主机具有给定的目录或文件结构时。卷可帮助您将Docker主机的配置与容器运行时解耦。
-
当您要将容器的数据存储在远程主机或云提供商上时,而不是在本地。
-
当您需要将数据从一台Docker主机备份,还原或迁移到另一台Docker主机时,卷是一个更好的选择。您可以停止使用该卷的容器,然后备份该卷的目录(例如
/var/lib/docker/volumes/<volume-name>
)。 -
当您的应用程序需要Docker Desktop上的高性能I / O时。卷存储在Linux VM中而不是主机中,这意味着读和写操作的等待时间短得多,吞吐量更高。
-
当您的应用程序需要完全本地文件系统在Docker桌面上的行为时。例如,数据库引擎需要对磁盘刷新进行精确控制,以确保事务持久性。卷存储在Linux VM中,可以保证这些安全,而绑定安装远程到文件系统的行为稍有不同的macOS或Windows。
绑定安装的良好用例
通常,应尽可能使用卷。绑定安装适用于以下类型的用例:
-
将配置文件从主机共享到容器。默认情况下,这就是Docker通过
/etc/resolv.conf
从主机安装到每个容器的方式为容器提供DNS解析的方式 。 -
在Docker主机上的开发环境和容器之间共享源代码或构建工件。例如,您可以将Maven
target/
目录安装到容器中,并且每次在Docker主机上构建Maven项目时,该容器都可以访问重建的工件。如果您以这种方式使用Docker进行开发,那么您的生产Dockerfile会将生产就绪的工件直接复制到映像中,而不是依赖于绑定挂载。
-
当确保Docker主机的文件或目录结构与容器所需的绑定安装一致时。
tmpfs挂载的好用例
tmpfs
当您不希望数据在主机上或容器内持久存在时,最好使用挂载。这可能是出于安全原因,或者是在您的应用程序需要写入大量非持久状态数据时保护容器的性能。
使用绑定安装或卷的提示
如果您使用绑定安装或卷,请牢记以下几点:
-
如果将空卷安装到存在文件或目录的容器中的目录中,则这些文件或目录将传播(复制)到该卷中。同样,如果启动一个容器并指定一个尚不存在的卷,则会为您创建一个空卷。这是预填充另一个容器所需数据的好方法。
-
如果将绑定安装或非空卷安装到存在某些文件或目录的容器中的目录中,则这些文件或目录会被安装遮盖,就像您将文件保存到
/mnt
Linux主机上然后再安装时一样。 USB驱动器插入/mnt
。的内容/mnt
将由USB驱动器,直至USB驱动器的内容被遮蔽被卸载。被遮盖的文件不会被删除或更改,但是在安装绑定安装或卷时将无法访问。