Manage data in Docker

预计阅读时间:9分钟

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

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

Docker 有两个选项让容器在主机上存储文件,以便即使在容器停止后文件也能持久保存: volumesbind mounts .

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

继续阅读有关持久化数据或利用内存文件的更多信息.

Choose the right type of mount

无论您选择使用哪种类型的挂载,容器内的数据看起来都是一样的. 它以目录或容器文件系统中的单个文件的形式公开.

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

types of mounts and where they live on the Docker host

  • 存储在由 Docker 管理的主机文件系统的一部分(Linux 上的/var/lib/docker/volumes/ ). 非 Docker 进程不应修改文件系统的这一部分. 卷是在 Docker 中持久化数据的最佳方式.

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

  • tmpfs挂载仅存储在主机系统的内存中,永远不会写入主机系统的文件系统.

More details about mount types

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

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

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

    当你挂载一个卷时,它可能是命名的或匿名的. 匿名卷在首次挂载到容器时没有明确的名称,因此 Docker 为它们提供了一个随机名称,该名称保证在给定的 Docker 主机中是唯一的. 除了名称之外,命名卷和匿名卷的行为方式相同.

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

  • 绑定挂载:从 Docker 早期就可用. 与卷相比,绑定挂载的功能有限. 当您使用绑定挂载时,主机上的文件或目录会挂载到容器中. 文件或目录由其在主机上的完整路径引用. 该文件或目录不需要已经存在于 Docker 主机上. 如果它尚不存在,则按需创建. 绑定挂载非常高效,但它们依赖于具有特定目录结构的主机文件系统. 如果您正在开发新的 Docker 应用程序,请考虑改用命名卷. 您不能使用 Docker CLI 命令直接管理绑定挂载.

    绑定挂载允许访问敏感文件

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

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

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

绑定挂载和卷都可以使用-v--volume标志挂载到容器中,但每个的语法略有不同. 对于tmpfs挂载,您可以使用--tmpfs标志. 我们建议对容器和服务使用--mount标志,用于绑定挂载、卷或tmpfs挂载,因为语法更清晰.

Good use cases for volumes

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

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

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

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

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

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

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

Good use cases for bind mounts

通常,您应该尽可能使用卷. 绑定安装适用于以下类型的用例:

  • 从主机共享配置文件到容器. 这就是 Docker 默认情况下通过将/etc/resolv.conf从主机安装到每个容器中来为容器提供 DNS 解析的方式.

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

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

  • When the file or directory structure of the Docker host is guaranteed to be consistent with the bind mounts the containers require.

Good use cases for tmpfs mounts

tmpfs挂载最适用于您不希望数据保留在主机或容器中的情况. 这可能是出于安全原因或当您的应用程序需要写入大量非持久状态数据时保护容器的性能.

Tips for using bind mounts or volumes

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

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

  • 如果您将绑定挂载或非空卷挂载到容器中存在某些文件或目录的目录中,则这些文件或目录会被挂载遮盖,就像您将文件保存到 Linux 主机上的/mnt中,然后将 USB 驱动器安装到/mnt中. /mnt的内容将被 USB 驱动器的内容所掩盖,直到卸载 USB 驱动器. 隐藏的文件不会被删除或更改,但在挂载绑定挂载或卷时无法访问.

Next steps

  • 了解有关的更多信息.
  • 了解有关绑定安装的更多信息.
  • 了解有关tmpfs 挂载的更多信息.
  • 了解有关存储驱动程序的更多信息,它们与绑定挂载或卷无关,但允许您将数据存储在容器的可写层中.
storage, persistence, 数据持久化, volumes, mounts, 绑定坐骑

by  icopy.site