Docker - 数据存储



出于设计原因,通常不应将数据直接持久化到 Docker 容器中,原因如下:首先,容器始终旨在是短暂的。换句话说,它们可以随时停止、启动或在理论上销毁。因此,存储在容器内部的数据在容器停止存在时会丢失。这样一来,数据持久化和恢复数据变得困难。

其次,容器的可写层可能与它运行在其上的主机机器紧密协调,这使得将其移动到另一台机器或提取数据变得困难。此外,此层中的写入通常使用存储驱动程序和联合文件系统执行,与主机文件系统的写入相比,这可能会导致性能开销。

数据也可以存储在容器内。这可能导致扩展和共享方面的问题,因为多个容器可能希望访问相同的数据,这使得管理和保持所述数据同步变得复杂。这就是为什么最好使用 Docker 卷或绑定挂载来存储容器外部的数据,这将提供持久性、可移植性和易于访问。

在本章中,我们将讨论如何使用卷和绑定挂载来持久化 Docker 容器中的数据。

在 Docker 容器中持久化数据的方法

无论您使用卷、绑定挂载还是 tmpfs 等挂载类型,容器内部的数据都作为容器文件系统内的目录或文件呈现。关键区别在于:持久化数据驻留在 Docker 主机上的位置。

卷位于 Docker 管理的主机文件系统的一部分,通常在 Linux 上为 **`/var/lib/docker/volumes/`**。此区域本机运行的 Docker 进程无法访问,因此卷是唯一适用于在 Docker 中持久存储数据的机制。

另一方面,绑定挂载可以位于主机系统的任何位置,甚至是一些关键系统文件,因此,可以由 Docker 未管理的进程更改。这使得它们更加灵活,但隔离性较差。最后,tmpfs 挂载仅存在于主机系统的内存中,并且从不触及底层文件系统 - 非常适合短暂的、非持久性数据。

**`-v`** 或 **`--volume`** 标志允许指定卷或绑定挂载的挂载点。语法略有不同:对于 tmpfs 挂载,请使用 **`--tmpfs`** 标志。但为了最大程度地提高可读性和清晰度,只要可能,请将 **`--mount`** 与所有选项合并并嵌套在其中。

Docker 卷

卷是在 Docker 容器中持久存储由其生成和使用的数据的首选方式。Docker 管理它们,并且独立于主机机器的文件系统是什么。与绑定挂载等其他存储策略相比,使用它们还有几个好处。

Docker 卷的关键特性

  • **持久性** - 存储在卷中的数据将超出已停止、删除或替换容器的生命周期。
  • **可移植性** - 使用卷可以轻松备份、迁移或在多个容器之间共享数据。
  • **管理** - 使用 Docker CLI 命令或通过 Docker API 控制和管理 Docker 卷。
  • **跨平台兼容性** - 在 Linux 和 Windows 容器上以卓越的一致性运行。
  • **性能** - 与来自 Mac 和 Windows 主机的绑定挂载相比,卷在 Docker Desktop 上具有更佳的性能。

创建卷

这是使用名称“my-vol”创建新卷的基本命令。

$ docker volume create my-vol

将卷附加到容器

以下命令将“my-vol”卷附加到容器内的“/app/data”目录。如果任何数据写入此目录,则会将其持久存储在卷中。

$ docker run -d --name my-container -v my-vol:/app/data my-image

列出卷

此命令列出 Docker 环境中所有可用的卷。

$ docker volume ls

检查卷

此命令提供有关卷的详细信息,包括挂载点、驱动程序和其他详细信息。

$ docker volume inspect my-vol

删除卷

此命令删除“my-vol”卷。警告:卷中的数据将被不可逆地销毁。

$ docker volume rm my-vol

Docker 卷的实际用例

  • **数据库** - 数据的数据库文件应存储在卷中,这将使其在所有容器重启中保持持久性。
  • **Web 服务器内容** - 将网站文件或用户上传存储在卷中,以便即使替换了 Web 服务器容器,它们仍然可以访问。
  • **应用程序日志** - 将日志存储在卷中,以便于分析和持久化。

Docker 卷带来了强大且灵活的容器化应用程序内持久数据管理。即使在动态容器环境中利用卷,数据也能保持安全和可访问。

绑定挂载

Docker 中的绑定挂载是一种将主机机器上的文件或目录直接共享到 Docker 应用程序中的方式。绑定挂载将主机机器上的文件或目录直接关联到容器中的路径;与卷不同,它们不需要管理,因为 Docker 管理它们。

绑定挂载的关键特性

  • **直接访问** - 对主机上文件进行的任何更改都会立即反映在容器内,反之亦然。
  • **灵活性** - 您可以挂载主机系统上的任何位置,包括系统文件、配置文件或项目的源代码。
  • **开发工作流** - 在开发中,绑定挂载对您来说是一个福音,因为您可以在主机驱动器上编辑代码,并且在运行的容器中发生的更改几乎会立即显示。

挂载主机目录

以下命令将您机器上的当前目录挂载到容器的“/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 标志允许更详细地指定绑定挂载,明确说明其类型、源和目标。

$ docker run -d --name my-container --mount 
   type=bind,source="$(pwd)",target=/app my-image

Docker 中绑定挂载的实际应用

  • **开发环境** - 使包含源代码的目录可挂载,以便可以实时更新源代码中的更改。
  • **配置文件** - 将主机的配置文件挂载到容器中以自定义其行为。
  • **共享主机资源** - 挂载容器需要访问的文件或目录 - 例如,日志文件和数据文件。

命名管道和 TMPFS

在 Docker 中,您可以使用 tmpfs 挂载和命名管道将数据存储在主机系统内存中,尽管它们在不同的操作系统中实现方式不同。

tmpfs 挂载(Linux)

在 Linux 上使用 Docker 时,tmpfs 挂载用于创建存储在内存中的临时文件系统。这意味着写入 tmpfs 挂载的文件不会持久化到磁盘,因此非常适合存储敏感信息或临时数据,而不需要在容器之外存在。

tmpfs 从内存运行;因此,与旧的基于磁盘的存储方法相比,它的读写速度要快得多。但是,tmpfs 中的数据是易失性的,如果主机系统重新启动或容器停止,则会丢失。

命名管道(Windows)

在 Windows 中,命名管道的工作原理与 tmpfs 挂载非常相似,用于将数据存储在内存中。它们使进程能够相互通信,从而可以将其数据存储在容器的临时内存中。

与 tmpfs 一样,命名管道的内容不会写入磁盘,并且一旦容器停止就会丢失。命名管道是 Windows 中进程间通信的基本机制之一,Docker 利用其功能在 Windows 主机上提供内存存储功能。

tmpfs 挂载和命名管道都旨在支持性能而非数据持久性至关重要的用例。它们很好地用于存储临时文件、缓存或不应写入磁盘的敏感信息。

何时使用 Docker 卷和绑定挂载?

卷是在 Docker 中处理持久存储的最佳方式。它非常适合在容器之间共享数据,在这种情况下,您无法保证主机文件结构,远程存储数据,必须备份、恢复或迁移数据的情况等等。此外,卷的性能更高,并且在 Docker Desktop 上为 I/O 密集型应用程序提供了本机文件系统行为。

相反,绑定挂载将主机上的文件/目录直接链接到容器的路径。通常,它们通过允许用户在主机和容器之间共享配置文件或源代码来提供帮助,尤其是在开发环境中。但在将绑定挂载与敏感数据一起使用时要谨慎,因为容器中的更改会直接影响主机。

Tmpfs 挂载完全基于内存且是临时的,非常适合非持久性数据,如缓存或敏感信息。它们专注于速度和安全性,因此数据持久性不是它们的关注点。

结论

就是这样。您已经掌握了 Docker 存储选项:卷、绑定挂载和 tmpfs 挂载,以优化容器化应用程序中的数据管理。了解它们之间的区别将使您能够明智地选择在何处以及如何存储您的数据。

卷(Volumes)提供持久性、可移植性和隔离性,使其适合保存需要比单个容器存活时间更长的宝贵数据。绑定挂载(Bind mounts)更加灵活,可以提供对主机文件的实时访问;它们有助于开发和共享特定资源。Tmpfs 可以被挂载,优先考虑速度和安全性;它在内存中提供临时的存储空间,用于敏感或瞬态数据。

很多将取决于您需要适当的存储机制的具体需求和用例。通过考虑数据持久性、访问模式和性能需求等因素,Docker 的存储选项使人们能够构建高效、可靠和安全的容器化应用程序。

Docker 数据存储常见问题解答

问 1. 当 Docker 容器停止或被移除时,我的数据会发生什么?

直接在容器可写层创建的数据在容器停止或移除时会丢失。这是因为容器应该被短暂创建。

为了确保数据的持久性,引入了诸如 Docker 卷和绑定挂载等数据存储机制,通过这些机制,数据存储在主机文件系统上或使用 Docker 管理的存储并链接到容器。

问 2. Docker 中的卷和绑定挂载有什么区别?

卷是 Docker 处理持久存储的首选方式。它们由 Docker 本身管理,独立于任何单个容器存在,但某些平台为它们提供了出色的生命周期特性,例如可移植性、轻松备份和更好的性能。

绑定挂载是容器中对主机目录或文件的直接链接。这样,它们就可以直接与容器共享文件,并且实际上优于卷来实现此目的:在大多数情况下,更安全,当然也更易于移植。

问 3. Docker 中的 tmpfs 挂载是什么,何时应该使用它们?

Tmpfs 挂载是仅驻留在主机系统内存中的临时文件系统。因此,它们不是持久性的,因此非常适合确保敏感数据或临时文件不会超出容器的生命周期。

尽管 tmpfs 挂载适合进行读写操作,但它们是易失性的:当主机重新启动或容器停止时,数据会丢失。

问 4. 我可以将 AWS S3 或 Azure Blob 存储解决方案与 Docker 一起使用吗?

通过 Docker 进行操作,您仍然可以使用任何云存储解决方案。但是,它更多的是与云提供商的 SDK 或 API 交互,而不是将其云存储直接挂载到卷中。这允许用户存储和检索来自云的数据;该解决方案几乎可以无限扩展并且具有持久性。

问 5. 如何保护存储在 Docker 卷中的数据?

保护 Docker 卷中数据的潜在措施包括:使用正确的权限隔离对卷的访问,避免无区别地共享卷,通过定期将卷备份到外部存储以进行灾难恢复来建立适当的备份机制,如果存储的是敏感数据,则对卷的内容进行加密,或加密主机的整个文件系统,最后,始终关注 Docker 的新安全更新和最佳实践,以保护您的环境免受漏洞的影响。

广告