在 Docker 中管理数据

默认情况下,容器内创建的所有文件都存储在可写容器层上。这意味着:

  • 当该容器不再存在时,数据不会持久存在,并且如果另一个进程需要数据,则可能很难从容器中获取数据。
  • 容器的可写层与运行容器的主机紧密耦合。您无法轻松地将数据移动到其他地方。
  • 写入容器的可写层需要 存储驱动程序来管理文件系统。存储驱动程序使用 Linux 内核提供联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象会降低性能 。

Docker 有两个选项让容器在主机上存储文件,以便即使在容器停止后文件也能保留:卷和绑定挂载。

Docker 还支持容器在主机内存中存储文件。此类文件不会被保留。如果您在 Linux 上运行 Docker,tmpfs则 mount 用于将文件存储在主机的系统内存中。如果您在 Windows 上运行 Docker,则使用命名管道将文件存储在主机的系统内存中。

选择正确的安装类型

无论您选择使用哪种类型的安装,容器内的数据看起来都是相同的。它在容器的文件系统中作为目录或单个文件公开。

可视化卷、绑定挂载和挂载之间差异的一个简单方法tmpfs 是考虑数据位于 Docker 主机上的位置。

挂载类型及其在 Docker 主机上的位置
  • 卷存储在主机文件系统的一部分中,由 Docker 管理/var/lib/docker/volumes/在 Linux 上)。非 Docker 进程不应修改文件系统的这一部分。卷是在 Docker 中保存数据的最佳方式。

  • 绑定安装可以存储在主机系统上的任何位置。它们甚至可能是重要的系统文件或目录。 Docker 主机或 Docker 容器上的非 Docker 进程可以随时修改它们。

  • tmpfs安装仅存储在主机系统的内存中,并且永远不会写入主机系统的文件系统。

-v绑定挂载和卷都可以使用or 标志挂载到容器中--volume,但各自的语法略有不同。对于tmpfs 坐骑,您可以使用--tmpfs旗帜。我们建议--mount对容器和服务、绑定挂载、卷或tmpfs挂载使用该标志,因为语法更清晰。

卷由 Docker 创建和管理。您可以使用命令显式创建卷docker volume create,或者 Docker 可以在容器或服务创建期间创建卷。

创建卷时,它存储在 Docker 主机上的目录中。当您将卷装载到容器中时,该目录就是装载到容器中的目录。这与绑定挂载的工作方式类似,只不过卷由 Docker 管理并与主机的核心功能隔离。

给定的卷可以同时安装到多个容器中。当没有正在运行的容器使用某个卷时,该卷仍然可供 Docker 使用,并且不会自动删除。您可以使用删除未使用的卷docker volume prune

当您安装卷时,它可能是命名的或匿名的。匿名卷被赋予一个随机名称,该名称保证在给定的 Docker 主机中是唯一的。就像命名卷一样,即使您删除使用匿名卷的容器,匿名卷也会持续存在,除非您--rm在创建容器时使用该标志,在这种情况下,匿名卷将被销毁。请参阅 删除匿名卷。如果您相继创建多个使用匿名卷的容器,则每个容器都会创建自己的卷。匿名卷不会在容器之间自动重用或共享。要在两个或多个容器之间共享匿名卷,您必须使用随机卷 ID 挂载匿名卷。

卷还支持使用卷驱动程序,它允许您将数据存储在远程主机或云提供商上,以及其他可能性。

绑定坐骑

与卷相比,绑定安装的功能有限。使用绑定挂载时,主机上的文件或目录将挂载到容器中。文件或目录由其在主机上的完整路径引用。该文件或目录不需要已存在于 Docker 主机上。如果尚不存在,则会根据需要创建它。绑定安装速度很快,但它们依赖于具有可用的特定目录结构的主机文件系统。如果您正在开发新的 Docker 应用程序,请考虑使用命名卷。您无法使用 Docker CLI 命令直接管理绑定安装。

重要的

默认情况下,绑定挂载允许对主机上的文件进行写访问。

使用绑定挂载的一个副作用是,您可以通过容器中运行的进程来更改主机文件系统,包括创建、修改或删除重要的系统文件或目录。这是一项强大的功能,可能会产生安全隐患,包括影响主机系统上的非 Docker 进程。

提示

使用大型存储库或单一存储库,或者使用不再随代码库扩展的虚拟文件系统?查看 同步文件共享。它通过使用同步文件系统缓存增强绑定安装性能,从而提供快速、灵活的主机到虚拟机文件共享。

临时文件系统

挂载tmpfs不会持久保存在磁盘上,无论是在 Docker 主机上还是在容器内。容器可以在容器的生命周期内使用它来存储非持久状态或敏感信息。例如,在内部,Swarm 服务使用tmpfs挂载将 机密挂载到服务的容器中。

命名管道

命名管道 可用于 Docker 主机和容器之间的通信。常见用例是在容器内运行第三方工具并使用命名管道连接到 Docker 引擎 API。

卷的良好用例

卷是在 Docker 容器和服务中保存数据的首选方式。卷的一些用例包括:

  • 在多个运行的容器之间共享数据。如果您没有显式创建它,则会在第一次将其挂载到容器中时创建一个卷。当该容器停止或被删除时,该卷仍然存在。多个容器可以同时挂载同一卷,无论是读写还是只读。仅当您明确删除卷时,卷才会被删除。

  • 当不保证 Docker 主机具有给定的目录或文件结构时。卷可帮助您将 Docker 主机的配置与容器运行时解耦。

  • 当您想要将容器的数据存储在远程主机或云提供商上,而不是本地时。

  • 当您需要将数据从一台 Docker 主机备份、恢复或迁移到另一台时,卷是更好的选择。您可以停止使用该卷的容器,然后备份该卷的目录(例如/var/lib/docker/volumes/<volume-name>)。

  • 当您的应用程序需要 Docker Desktop 上的高性能 I/O 时。卷存储在 Linux VM 中而不是主机中,这意味着读取和写入具有更低的延迟和更高的吞吐量。

  • 当您的应用程序需要 Docker Desktop 上完全本机文件系统行为时。例如,数据库引擎需要精确控制磁盘刷新以保证事务的持久性。卷存储在 Linux VM 中,可以做出这些保证,而绑定安装则远程到 macOS 或 Windows,其中文件系统的行为略有不同。

绑定安装的良好用例

一般来说,您应该尽可能使用卷。绑定安装适用于以下类型的用例:

  • 将配置文件从主机共享到容器。这就是 Docker 默认为容器提供 DNS 解析的方式,即 /etc/resolv.conf从主机挂载到每个容器中。

  • 在 Docker 主机上的开发环境和容器之间共享源代码或构建工件。例如,您可以将 Maventarget/ 目录挂载到容器中,每次在 Docker 主机上构建 Maven 项目时,容器都可以访问重建的工件。

    如果您以这种方式使用 Docker 进行开发,您的生产 Dockerfile 会将生产就绪工件直接复制到映像中,而不是依赖于绑定安装。

  • 当保证Docker主机的文件或目录结构与容器所需的绑定挂载一致时。

tmpfs 挂载的良好用例

tmpfs当您不希望数据保留在主机上或容器内时,最好使用挂载。这可能是出于安全原因,或者是为了在应用程序需要写入大量非持久状态数据时保护容器的性能。

使用绑定安装或卷的提示

如果您使用绑定安装或卷,请记住以下几点:

  • 如果将空卷装载到容器中存在文件或目录的目录中,则这些文件或目录将传播(复制)到该卷中。同样,如果您启动一个容器并指定一个尚不存在的卷,则会为您创建一个空卷。这是预填充另一个容器所需的数据的好方法。

  • 如果将绑定挂载或非空卷挂载到容器中存在某些文件或目录的目录中,这些文件或目录会被挂载遮盖,就像您将文件保存到/mntLinux 主机上然后挂载USB 驱动器插入/mnt.在卸载 USB 驱动器之前,的内容/mnt将被 USB 驱动器的内容遮盖。被遮挡的文件不会被删除或更改,但在挂载绑定挂载或卷时无法访问。

下一步

  • 了解有关 卷的更多信息。
  • 了解有关 绑定安装的更多信息。
  • 了解有关 tmpfs 安装的更多信息。
  • 了解有关 存储驱动程序的更多信息,这些驱动程序与绑定安装或卷无关,但允许您将数据存储在容器的可写层中。