一、前言
默认情况下,在Docker容器内创建的所有文件都只能在容器内部使用。容器删除后,数据也跟着删除,虽然通常我们不会删除容器,但是一旦宿主机发生故障,我们重新创建容器恢复服务,那么之前容器创建的文件就会丢失,这会为我们带来不必要的麻烦。另外,由于在容器中的文件对于Docker来说是卸载了“可写层”,性能也会下降,所以我们需要把数据写到宿主机,方便数据的存储、转移,以及容器间的数据共享,提高数据读写性能等等
1、本文主要内容
使用Golang提供HTTP服务,将日志写入磁盘,并制作镜像
数据卷绑定、文件挂载、tmpfs缓存挂载优点与特性介绍
将数据卷(Volume)绑定到容器指定目录,实现容器数据的持久化存储与共享
将宿主机文件/目录挂载(bind mounts)到容器指定目录,实现容器数据的持久化存储与共享
将宿主机tmpfs缓存挂载到容器指定目录
二、数据卷与挂载
1、数据卷(Volume)
卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特:。多个容器可挂载同一个数据卷
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
数据卷(Volume)是Docker官方推荐的数据持久化存储方式,也是目前最成熟的Docker持久化存储方案,它具备以下优点/特性
- 数据卷比绑定挂载(Bind mounts)更容易备份或迁移
- 数据卷可以通过 Docker CLI 命令或 Docker API 进行管理
- 数据卷适用于 Linux 和 Windows 容器
- 数据卷支持存储在远端主机上,并支持加密存储
- 数据卷的数据不支持在宿主机上直接查看或管理
- 数据卷可以在宿主机上预先占用空间,以免磁盘被占用导致容器无法正常运行
- 在 Mac 和 Windows 开发环境下,数据卷相比绑定挂载(Bind mounts)有更好的性能
- 数据卷可以用于容器之间共享数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
2、绑定挂载(Bind mounts)
绑定挂载(Bind mounts)是Docker早期提供的数据持久化存储方式,我们可以将宿主机的目录/文件挂载到容器中, 并绑定在容器指定的目录/文件上,它具备以下优点/特性
挂载目录/文件非常方便,但文件的备份跟迁移相对麻烦
挂载的目录/文件无法通过Docker本身进行管理
挂载的目录/文件使用的磁盘空间可能会受其他程序影响
挂载的目录/文件可以便捷的在宿主机上进行查看及管理
挂载的目录/文件可以用于容器之间共享数据 绑定挂载为直译,我更愿称之为文件挂载
3、缓存挂载(tmpfs mounts)
Docker在Linux上提供了tmpfs(一种基于内存的文件系统)挂载,可以让容器把内容放在宿主机内存中进行读写,它具备以下优点/特性
存储在内存中,有较好的读写性能
存储在内存中,适合存储一些敏感信息,或者随着容器关闭就丢弃的数据
只能被Linux上运行的Docker容器使用(?),且不能用于容器间的数据共享 虽然官方文档上说只能在Linux环境下的Docker上使用,但我基于Docker Desktop 4.14 on Windows测试下来是可以,猜测是Docker官方在某个Docker Desktop版本之后支持了该特性的测试,但并没有更新文档
4、关系说明图
这个图可以帮助我们理解这三种方式,后面我就简称为数据卷绑定、文件挂载、缓存挂载