Docker - 数据存储
出于设计原因,数据通常不应直接持久化存储在 Docker container 中,有以下几个原因。首先,container 始终被设计为临时的。换句话说,它们可以随时停止、启动,或者理论上被销毁。存储在 container 内部的数据因此会在每次 container 停止存在时丢失。这样做会使数据持久化和数据恢复变得困难。
其次,container 的可写层与其运行的宿主机紧密协调,通常难以将其移动到另一台机器或提取数据。此外,该层的写入通常使用 storage driver 和 union file system 执行,与宿主机文件系统的写入相比,可能造成性能开销。
数据也可以存储在 container 内。这会导致扩展和共享问题,因为多个 container 可能需要访问相同的数据,使得管理和保持数据同步变得复杂。因此,最好使用 Docker volumes 或 bind mounts 将数据存储在 container 外部,这将提供持久性、可移植性和易访问性。
在本章中,我们将讨论如何使用 volumes 和 bind mounts 在 Docker container 中持久化数据。
在 Docker Container 中持久化数据的不同方式
无论使用 volume、bind mount 还是 tmpfs mount 类型,container 内的数据都会以 container 文件系统中的目录或文件形式呈现。这里有关键区别:持久化数据在 Docker 宿主机上的位置。
Volumes 位于 Docker 管理的宿主机文件系统部分,通常在 Linux 上为 /var/lib/docker/volumes/。该区域无法被原生运行的 Docker 进程访问,因此 volumes 是 Docker 中持久化存储数据唯一适用的机制。
另一方面,bind mounts 可以位于宿主机系统的任何位置,甚至包括一些关键系统文件,因此可以被非 Docker 管理的进程更改。这使它们更灵活但隔离性更差。最后,tmpfs mounts 仅存在于宿主机系统的内存中,从不接触底层文件系统——非常适合临时、非持久化数据。
-v 或 --volume 标志允许指定 volumes 或 bind mounts 的挂载点。语法略有不同:tmpfs mounts 使用 --tmpfs 标志。但为了最大可读性和清晰度,只要可能,就使用 --mount,将所有选项合并并嵌套在其中。
Docker Volumes
Volumes 是持久化 Docker 容器生成和使用的数据的首选方式。Docker 管理它们,与主机文件系统无关。相比其他存储策略(如 bind mounts),使用它们还有多项优势。
Docker Volumes 的主要特性
- 持久性 − 存储在 volumes 中的数据将存活于停止、删除或替换的容器的生命周期之外。
- 可移植性 − 使用 volumes 很容易备份、迁移或在多个容器之间共享。
- 管理性 − 可以使用 Docker CLI 命令或通过 Docker API 来控制和管理 Docker volumes。
- 跨平台兼容性 − 在 Linux 和 Windows 容器上运行,具有惊人的稳定性。
- 性能 − 在 Mac 和 Windows 主机上,与 Docker Desktop 配合使用时,volumes 的性能比 bind mounts 更优。
创建 Volume
这是创建名为 "my-vol" 的新 volume 的基本命令。
$ docker volume create my-vol
将 Volume 挂载到容器
下面的命令将 "my-vol" volume 挂载到容器内的 "/app/data" 目录。如果向该目录写入任何数据,它将持久地存储在 volume 中。
$ docker run -d --name my-container -v my-vol:/app/data my-image
列出 Volumes
此命令列出 Docker 环境中所有可用的 volumes。
$ docker volume ls
检查 Volume
此命令提供 volume 的详细信息,包括挂载点、驱动程序和其他细节。
$ docker volume inspect my-vol
删除 Volume
此命令删除 "my-vol" volume。警告:volume 中的数据将被不可逆地销毁。
$ docker volume rm my-vol
Docker Volumes 的实际用例
- 数据库 − 数据库文件应存储在 volume 中,以确保在所有容器重启时保持持久性。
- Web 服务器内容 − 将网站文件或用户上传内容存储在 volume 中,即使 web 服务器容器被替换,它们仍然可访问。
- 应用日志 − 将日志存储在 volume 中,便于分析和持久化。
Docker volumes 为容器化应用中的持久数据提供了强大且灵活的管理。即使在动态容器环境中利用 volumes,数据仍然保持安全和可访问。
Bind Mounts
Docker 中的 Bind mounting 是一种将主机上的文件或目录直接共享到 Docker 应用中的方式。Bind mounts 将主机上的文件或目录直接关联到容器中的路径;与 volumes 不同,它们无需管理,因为 Docker 会管理它们。
Bind Mount 的主要特性
- 直接访问 − 对主机上的文件所做的任何更改都会立即反映在容器中,反之亦然。
- 灵活性 − 您可以挂载主机系统上的任何位置,包括系统文件、配置文件或项目源代码。
- 开发工作流程 − 在开发中,bind mounts 对您大有裨益,因为您可以在主机驱动器上编辑代码,而运行容器中的更改几乎立即可见。
挂载主机目录
以下命令将机器上的当前目录挂载到容器的 '/app' 目录中。当前目录内文件的任何更改都会反映在容器中,反之亦然。
$ docker run -d --name my-container -v $(pwd):/app my-image
挂载单个文件
这会将主机文件 "file.txt" 挂载到容器中的路径 "/etc/config.txt"。
$ docker run -d --name my-container -v /path/to/file.txt:/etc/config.txt my-image
使用 --mount 标志
--mount 标志允许对 bind mount 进行更详细的指定,明确声明其类型、源和目标。
$ docker run -d --name my-container --mount type=bind,source="$(pwd)",target=/app my-image
Docker 中 Bind Mounts 的实际应用
- 开发环境 − 使包含源代码的目录可挂载,以便源代码更改可以实时更新。
- 配置文件 − 将主机的配置文件挂载到容器中,以自定义其行为。
- 共享主机资源 − 挂载容器需要访问的文件或目录 - 例如,日志文件和数据文件。
Named Pipes 和 TMPFS
在 Docker 中,您可以使用 tmpfs mounts 和 named pipes 将数据存储在主机系统内存中,尽管它们在不同操作系统中的实现方式不同。
tmpfs Mounts (Linux)
在 Linux 上使用 Docker 时,tmpfs mount 用于创建保存在内存中的临时文件系统。这意味着写入 tmpfs mount 中的文件不会持久化到磁盘,因此非常适合存储敏感信息或临时数据,这些数据无需在 Container 停止后继续存在。
tmpfs 从内存运行;因此,其读写速度比传统的基于磁盘的存储方法快得多。然而,tmpfs 中的数据是易失的,如果主机系统重启或容器停止,数据将丢失。
Named Pipes (Windows)
在 Windows 中,named pipes 的工作方式与 tmpfs mounts 类似,用于将数据存储在内存中。它们使进程能够相互通信,并可以将数据存储在容器的临时内存中。
与 tmpfs 类似,named pipes 的内容不会写入磁盘,一旦容器停止,它们就会丢失。Named pipes 是 Windows 中进程间通信的基本机制之一,Docker 利用其功能在 Windows 主机上提供内存存储能力。
tmpfs mounts 和 named pipes 都设计用于性能至关重要而非数据持久性的使用场景。它们非常适合存储临时文件、缓存或不应写入磁盘的敏感信息。
何时使用 Docker Volumes 和 Bind Mounts?
Volumes 是 Docker 中处理持久存储的最佳方式。它非常适合在容器之间共享数据(无法保证主机的文件结构)、远程存储数据、需要备份、恢复或迁移数据的情况,以及更多场景。此外,volumes 性能更高,并在 Docker Desktop 上为 I/O 密集型应用原生提供文件系统行为。
相比之下,bind mounts 将主机上的文件/目录直接链接到容器的路径。通常,它们通过允许用户在主机和容器之间共享配置文件或源代码来提供帮助,尤其是在开发环境中。但在使用 bind mounts 处理敏感数据时要谨慎,因为容器中的更改会直接影响主机。
Tmpfs mounts 完全基于内存且临时,非常适合非持久数据,如缓存或敏感信息。它们注重速度和安全性,因此不关注数据持久性。
结论
就是这样。你已经掌握了 Docker 存储选项:volumes、bind mounts 和 tmpfs mounts,用于优化容器化应用中的数据管理。了解它们的差异将让你能够明智地选择数据存储的位置和方式。
Volumes 提供持久性、可移植性和隔离性,使其适合存储比单个容器存活时间更长的宝贵数据。Bind mounts 更加灵活,可以提供对主机文件的实时访问;它们在开发和特定资源共享方面非常有用。Tmpfs 可以挂载,优先考虑速度和安全性;它为敏感或临时数据提供内存中的临时存储。
很大程度上取决于具体需求和使用场景,你需要合适的存储机制。通过考虑数据持久性、访问模式和性能需求等因素,Docker 的存储选项使你能够构建高效、可靠且安全的容器化应用。
Docker 数据存储常见问题解答
Q 1. 当 Docker container 停止或被移除时,我的数据会怎样?
直接在 container 可写层中创建的数据会在 container 停止或移除时丢失。这是因为 container 被设计为临时创建的。
为了确保存储数据的持久性,会使用 Docker volume 和 bind mount 等数据存储机制,这些机制将数据存储在主机文件系统外部或使用 Docker 管理的存储,并链接到 container。
Q 2. Docker 中的 Volumes 和 Bind Mounts 有什么区别?
Volumes 是 Docker 首选的持久存储方式。由 Docker 自身管理,它们独立于任何单个 container 存在,但某些平台为它们提供了出色的生命周期功能,如可移植性、易备份和更好的性能。
Bind mounts 是从 container 到主机目录或文件的直接链接。这种方式用于直接与 container 共享文件,实际上在这一用途上优于 volumes:在大多数方面更安全,并且肯定更具可移植性。
Q 3. Docker 中的 tmpfs mount 是什么,何时应该使用它们?
Tmpfs mounts 是仅驻留在主机系统内存中的临时文件系统。因此,它们是非持久化的,非常适合确保敏感数据或临时文件不会超过 container 的生命周期。
尽管 tmpfs mounts 支持读写操作,但它们是易失的:主机重启或 container 停止时数据会丢失。
Q 4. 我可以在 Docker 中使用 AWS S3 或 Azure Blob 存储解决方案吗?
在与 Docker 协作时,您仍然可以使用任何云存储解决方案。不过,这更多是关于通过云提供商的 SDK 或 API 进行接口交互,而不是直接将云存储挂载到 volume 中。这允许用户从云端存储和检索数据;该解决方案几乎具有无限的可扩展性和持久性。
Q 5. 如何保护 Docker volumes 中存储的数据?
保护 Docker volumes 中数据的潜在措施包括:使用适当的权限隔离对 volumes 的访问,避免不加辨别地共享 volumes,为 volumes 建立适当的备份机制,通过定期备份到外部存储进行灾难恢复,加密 volume 的内容(如果存储敏感数据),或加密主机的整个文件系统,最后,始终保持与 Docker 的最新安全更新和最佳实践同步,以保护您的环境免受漏洞侵害。