Docker 存储
- docker 默认存储方式
- docker 持久化存储
- Volumes (卷)
- 简介
- 推荐使用情况
- Bind mounts (绑定挂载)
- 简介
- 推荐使用情况
- 绑定挂载与卷注意点
- docker 非持久化存储
- tmpfs mounts (tmpfs 挂载)
- 简介
- 推荐使用情况
- named pipes (命名管道)
docker 默认存储方式
默认情况下,在容器内创建的所有文件都存储在可写的容器层上。这意味着:当容器不存在时,数据不会持久存在,如果另一个进程需要数据,则很难将数据从容器中取出。容器的可写层与运行容器的主机紧密耦合。不能轻易地将数据移动到其他地方。
docker 持久化存储
Volumes (卷)
简介
- 由 Docker 创建和管理,是主机文件系统的一部分中(在Linux上为
/var/lib/doker/Volumes/
)。 非Docker进程不应该修改文件系统的这一部分。卷是在Docker中持久化数据的最佳方式。 - 可以使用
docker volume create
命令显式创建卷,也可以在创建容器或服务时创建卷。 - 创建卷时,它存储在Docker主机上的一个目录中。当将卷装入容器时,这个目录就是装入容器的目录。这与绑定装载的工作方式类似,只是卷由Docker管理,并且与主机的核心功能隔离。
- 当没有正在运行的容器使用卷时,Docker仍然可以使用该卷,并且不会自动删除。可以使用
docker volume prune
删除未使用的卷。 - 挂载卷时,它可以是命名的,也可以是匿名的。当匿名卷首次装入容器时,不会为其指定明确的名称,Docker会为其提供一个随机名称,该名称保证在给定的Docker主机中是唯一的。除了名称之外,命名卷和匿名卷的行为方式相同。
- 卷还支持使用卷驱动程序,允许将数据存储在远程主机或云提供商上。
推荐使用情况
- 在多个正在运行的容器之间共享数据。 多个容器可以同时装载同一个卷,可以是读写的,也可以是只读的。只有当明确删除卷时,才会删除这些卷。
- 当Docker主机不能保证具有给定的目录或文件结构时。 卷可以帮助将Docker主机的配置与容器运行时解耦。
- 当希望将容器的数据存储在远程主机或云提供商上,而不是本地时。
- 当需要将数据从一个Docker主机备份、恢复或迁移到另一个主机时。 可以停止使用卷的容器,然后备份卷的目录(如
/var/lib/docker/volumes/<volume-name>
)。
Bind mounts (绑定挂载)
简介
- 绑定挂载可以存储在
主机系统的任何位置
。它们甚至可能是重要的系统文件或目录
。 Docker主机或Docker容器上的非Docker进程可以随时修改它们。 - 绑定挂载的性能非常高,但它们依赖于主机的文件系统,该文件系统具有特定的可用目录结构。
- 绑定挂载允许访问敏感文件
使用绑定挂载的一个副作用是,可以通过在容器中运行的进程来更改主机文件系统,包括创建、修改或删除重要的系统文件或目录。这是一种强大的能力,可能会带来安全隐患,包括影响主机系统上的非Docker进程。
推荐使用情况
- 将配置文件从主机共享到容器。 这就是Docker默认情况下为容器提供DNS解析的方式,通过将
/etc/resolv.conf
从主机安装到每个容器中。 - 当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时。
绑定挂载与卷注意点
如果将空卷挂载到容器中已经存在的文件或目录时,则这些文件或目录的内容会被复制到卷中。同样,如果启动一个容器时并指定了一个不存在的卷,则会创建一个空卷。这是预填充另一个容器所需数据的好方法。
如果将绑定挂载或非空卷挂载到容器中已经存在的某些文件或目录时,则这些文件或目录会被挂载遮挡,就像将文件保存到Linux主机上的
/mnt
中,然后将USB驱动器挂载到/mnt
中一样。/mnt
的内容将被USB驱动器的内容遮挡,直到USB驱动器被卸载。遮挡的文件不会被删除或更改,但在绑定挂载或卷挂载还未卸载前是无法访问的。
docker 非持久化存储
tmpfs mounts (tmpfs 挂载)
简介
tmpfs 挂载 只存储在主机系统的内存中,从不写入主机系统的文件系统。
- tmpfs 挂载 不持久化在磁盘上,无论是在Docker主机上还是在容器内。
它可以在容器的生命周期内被容器用来存储非持久状态或敏感信息
。
推荐使用情况
- tmpfs 挂载 最适合于不希望数据持久存在于主机或容器中的情况。 这可能是出于安全原因,或者是为了在应用程序需要写入大量非持久性状态数据时保护容器的性能。
named pipes (命名管道)
npipe
挂载 可以用于Docker主机和容器之间的通信。常见的用例是在容器内运行第三方工具,并使用命名管道连接到Docker Engine API。