1. Manage data in Docker
默认情况下, 所有在容器内部创建的文件被存储在一个可写的容器层. 这就意味着:
当容器不存在的时候, 数据不能被持久化, 而且在容器外部想要读取这些数据十分困难.
容器的可写的层与运行容器的主机密切相关. 你不能轻易地移动数据.
要想把数据写到容器的可写层, 需要一个存储驱动来管理文件系统. 存储驱动提供一个文件系统供 Linux 内核调用.
Docker 有两种方式将容器中的文件存储到主机上, 这样的话即使容器停止了, 文件依然被持久化下来. 这两种方式分别是: volumes 和 bind mounts. 如果你是在 Linux 上运行 Docker, 那么你还可以使用 tmpfs mount.
2. 选择正确的挂载类型
无论你选择哪种挂载类型, 数据看起来是一样的. 它以目录或者容器的文件系统中的单个文件的形式暴露出来.
下面这幅图可以帮助我们更好的理解 volumes , bind mounts , tmpfs mounts 三者的区别
Volumes 存储在由 Docker 管理的主机文件系统的一部分中 (在 Linux 中是 /var/lib/docker/volumes/ ). 非 Docker 进程不应该去修改这部分文件系统. Volumes 是在 Docker 上持久化数据最好的方式.
Bind mounts 数据可以被储存在主机的任何地方. 它们甚至可能是重要的系统文件或目录. Docker 主机或 Docker 容器上的非 Docker 进程可以随时修改它们.
tmpfs mounts 数据只会被存储到主机的内存中, 而且从来不会写到文件系统上.
3. 关于挂载类型
Volumes
Volumes 由 Docker 创建并管理. 你可以用 docker volume create 命令显式地创建一个 volume, 或者在容器或服务创建的时候创建一个 volume.
当你创建了一个 volume 以后, 它被存储到 Docker 主机上的一个目录下. 当你挂载这个 volume 到一个容器的时候, 这个目录就是挂载到容器中的目录. 这种方式跟 bind mounts 很像, 除了 volumes 被 Docker 管理并与主机的核心功能隔离以外.
一个 volume 可以同时挂载到多个容器中. 当没有一个运行中的容器使用这个 volume 的时候, 这个 volume 仍然是可用的, 并且不会被自动删除. 你可以用 docker volume prune 命令删除未使用的 volumes.
当你挂载一个 volume 的时候, 它可能是被命名的或者匿名的. 匿名的 volumes 在它首次被挂载到一个容器中的时候不会被指定一个明确的名字, 因此 Docker 给它们一个随机的名字, 以保证它在 Docker 主机中是唯一的. 关于名字, 命名的和匿名的 volumes 在使用上是一样的.
Volumes 也支持 volume 驱动, 可以运行你存储数据到远程主机或云上.
Bind mounts
与 volumes 相比, bind mounts 有一些功能限制. 当你使用 bind mount 的时候, 主机上的一个文件或目录被挂载到一个容器. 这个文件或目录关联主机上的绝对路径. 这个文件或目录不需要事先在 Docker 主机上存在, 如果没有则会自动在后台创建. Bind mounts 的性能非常好, 但它依赖于主机的文件系统上有一个特定的目录结构可用. 如果你正在开发一个新的 Docker 应用, 建议用 volumes. 你不能直接用 Docker 命令来直接管理 bind mounts.
tmpfs mounts
一个 tmpfs 挂载不会持久化数据到磁盘, 无论是在 Docker 主机上还是在容器中. 容器可以在容器的生命周期中使用它来存储非持久性状态或敏感信息. 例如, 在内部, 群集服务使用 tmpfs 挂载来将秘钥挂载到服务的容器中.
4. volumes 最佳实践
Volumes 是在 Docker 容器和服务中保存数据的首选方式. 使用 volumes 的一些场景:
在多个运行的容器之间共享数据. 如果你没有显式地创建一个 volume, 那么在它首次被挂载到一个容器中的时候会被自动创建. 当容器停止或被删除以后, 这个 volume 仍然存在. 多个容器可以挂载同一个 volume, 可以是读写或只读的. 只有当你显式地删除 volumes 的时候它们才会被删除.
Docker 主机不保证有一个给定的目录或文件结构. Volumes 解耦从容器运行时到 Docker 主机之间的配置.
当你想要存储你的容器的数据到一个远程主机或云上, 而不是本地
当你需要备份, 恢复, 或者将数据从一个 Docker 主机移动到另一个 Docker 主机的时候, volumes 是最好的选择. 你可以停止正在使用这个 volume 的容器, 然后备份这个 volume 的目录 (例如:/var/lib/docker/volumes/<volume-name>)
5. bind mounts 最佳实践
一般而言, 你应该尽可能地用 volumes.Bind mounts 适用于下列情形:
在主机和容器之间共享配置. 默认情况下, 通过挂载 / etc/resolv.conf 到每个容器上, Docker 提供 DNS 解析到容器.
在 Docker 主机和容器之间开发环境共享源代码和构建 artifacts. 例如, 你可能挂载一个 Maven 的 target / 目录到一个容器, 并且每次你在 Docker 主机上构建 Maven 工程的时候, 这个容器可以获得构建后的 artifacts.
当保证 Docker 主机的文件或目录结构与容器所需的 bind mounts 一致时.
6. tmpfs mounts 最佳实践
当你不想要数据持久化到主机或容器的时候, tmps mounts 是最好的选择. 这可能是出于安全原因, 或者是为了在应用程序需要编写大量非持久性状态数据时保护容器的性能.
7. 文档
- https://docs.docker.com/storage/
- https://docs.docker.com/storage/volumes/
来源: https://www.cnblogs.com/cjsblog/p/10900291.html