数据卷
默认情况下,在容器内创建的所有文件都存储在可写容器层上。这就存在下面的问题
- 当容器不再存在时,数据不会持久存在,而且如果另一个进程需要数据,则很难从容器中获取数据。
- 容器的可写层与容器运行的主机紧密耦合。您不能轻易地将数据移动到其他地方。
- 向容器的可写层写入需要存储驱动程序来管理文件系统。存储驱动程序提供使用 Linux 内核的联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能。
Docker 有两个选项可以让容器在主机上存储文件,这样即使在容器停止后,文件也会被持久化:卷和绑定挂载。如果在 Linux 上运行 Docker,也可以使用 tmpfs 挂载。如果你在 Windows 上运行 Docker,你也可以使用命名管道。
可视化卷、绑定装载和 tmpfs 装载之间差异的一种简单方法是考虑数据在 Docker 主机上的位置
- 卷存储在由 Docker (Linux 上的/var/lib/ Docker /卷)管理的主机文件系统的一部分中。非 docker 进程不应该修改文件系统的这一部分。卷是 Docker 中保存数据的最佳方式。
- 绑定挂载可以存储在主机系统的任何位置。它们甚至可能是重要的系统文件或目录。Docker 主机或 Docker 容器上的非 Docker 进程可以在任何时候修改它们。
- tmpfs 挂载只存储在主机系统的内存中,并且从不写到主机系统的文件系统中。
使用案例
卷是在 Docker 容器和服务中保存数据的首选方式。
- 在多个运行的容器之间共享数据。如果您没有显式地创建卷,那么卷将在第一次挂载到容器中时创建。当容器停止或被删除时,该卷仍然存在。多个容器可以同时挂载相同的卷,无论是读写还是只读。卷只有在显式删除时才会删除。
- 当 Docker 主机不能保证具有给定的目录或文件结构时。卷帮助您从容器运行时解耦 Docker 主机的配置。
- 当您希望在远程主机或云提供商(而不是本地)上存储容器数据时。
- 当需要将数据从一台 Docker 主机备份、恢复或迁移到另一台 Docker 主机时,卷是更好的选择。可以使用该卷停止容器,然后备份该卷的目录(例如/var/lib/docker/volumes/)。
通常,您应该尽可能使用卷。绑定挂载适用于以下用例类型:
- 从主机到容器共享配置文件。通过将/etc/resolv.conf 从主机挂载到每个容器中,Docker 默认为容器提供 DNS 解析。
- 在 Docker 主机和容器上的开发环境之间共享源代码或构建工件。例如,您可以将一个 Maven 目标/目录挂载到一个容器中,每次在 Docker 主机上构建 Maven 项目时,容器就可以访问重新构建的工件。如果以这种方式使用 Docker 进行开发,那么生产 Dockerfile 将直接将生产准备好的工件复制到映像中,而不是依赖于绑定挂载。
- 当 Docker 主机的文件或目录结构保证与容器需要的绑定安装一致时。
tmpfs 挂载最适合于不希望在主机上或容器中持久保存数据的情况。这可能是出于安全原因,或者是为了在应用程序需要编写大量非持久性状态数据时保护容器的性能。
注意项
如果将空卷装入容器中存在文件或目录的目录中,这些文件或目录将传播(复制)到该卷中。类似地,如果您启动了一个容器并指定了一个不存在的卷,那么将为您创建一个空卷。这是预填充另一个容器需要的数据的好方法。
如果你挂载一个绑定挂载或非空卷成目录的容器一些文件或目录存在,这些文件或目录被挂载,就像如果你保存文件到/ mnt Linux 主机上然后 u 盘挂载到/ mnt。mnt 的内容会被 USB 驱动器的内容所掩盖,直到 USB 驱动器被卸载。被隐藏的文件不会被删除或修改,但是在绑定挂载或卷挂载时无法访问。
数据卷
数据卷是保存 Docker 容器生成和使用的数据的首选机制。绑定挂载依赖于主机的目录结构,卷完全由 Docker 管理。
卷与绑定挂载相比有几个优势:
- 卷比绑定挂载更容易备份或迁移。
- 可以使用 Docker CLI 命令或 Docker API 来管理卷。
- 卷可以在 Linux 和 Windows 容器上工作。
- 卷可以更安全地在多个容器之间共享。
- 卷驱动程序允许您在远程主机或云提供商上存储卷、加密卷的内容或添加其他功能。
- 新卷的内容可以由容器预先填充。
与将数据持久化到容器的可写层相比,卷通常是更好的选择,因为卷不会增加使用它的容器的大小,而且卷的内容存在于给定容器的生命周期之外。

如果容器生成非持久性状态数据,请考虑使用 tmpfs 挂载以避免将数据永久存储在任何位置,并通过避免写入容器的可写入层来提高容器的性能。