docker数据持久化

docker数据持久化

docker的数据储存方案,volums bind mounts 为持久化方案,tmpfs mounts 是临时储存。

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:

  • 当该容器不再存在时,数据不会持久存在。
  • 如果另一个进程需要数据,则很难将数据从容器中取出。容器的可写层与运行容器的主机紧密耦合。您无法轻松地将数据移动到其他地方。
  • 写入容器的可写层需要存储驱动程序来管理文件系统。存储驱动程序提供了一个联合文件系统,使用 Linux 内核。与使用直接写入主机文件系统的数据卷相比,会降低性能。

Docker 为容器在主机上存储文件提供了两种选择,以便即使在容器停止后文件也能持久保存:卷 volumes 和绑定挂载 bind mounts

Docker 还支持将文件存储在主机内存中的容器。此类文件不会持久保存。即使用 tmpfs mount 将文件存储在主机的系统内存中。

方案区别

无论您选择使用哪种类型的挂载,容器内的数据看起来都是一样的。它以目录或容器文件系统中的单个文件的形式公开。

可视化卷、绑定挂载和 tmpfs 挂载之间差异的是数据在 Docker 主机上的位置。

  • 卷存储在由 Docker 管理的主机文件系统的一部分(Linux 上的 /var/lib/docker/volumes/)。非 Docker 进程不应修改文件系统的这一部分。卷是在 Docker 中持久化数据的最佳方式。
  • 绑定挂载可以存储在主机系统的任何位置。它们甚至可能是重要的系统文件或目录。 Docker 主机或 Docker 容器上的非 Docker 进程可以随时修改它们。
  • tmpfs 挂载仅存储在主机系统的内存中,永远不会写入主机系统的文件系统。

docker-storage

volums卷

由 Docker 创建和管理。使用 docker volume create 命令显式创建卷,或者 Docker 可以在容器或服务创建期间创建卷。

创建卷时,它存储在 Docker 主机上的目录中。当您将卷挂载到容器中时,此目录就是挂载到容器中的目录。类似于绑定挂载的工作方式,只是卷由 Docker 管理并且与主机的核心功能隔离。

给定的卷可以同时安装到多个容器中。当没有正在运行的容器使用卷时,卷仍然可供 Docker 使用,并且不会自动删除。您可以使用 docker volume prune 删除未使用的卷。

挂载一个卷时,它可能是命名的或匿名的。匿名卷在首次挂载到容器时没有明确的名称,因此 Docker 为它们提供了一个随机名称,该名称保证在给定的 Docker 主机中是唯一的。除了名称之外,命名卷和匿名卷的行为方式相同。

bind mounts绑定挂载

绑定挂载:从 Docker 早期就可用。与卷相比,绑定挂载的功能有限。当您使用绑定挂载时,主机上的文件或目录会挂载到容器中。文件或目录由其在主机上的完整路径引用。该文件或目录不需要已经存在于 Docker 主机上。如果它尚不存在,则按需创建。绑定挂载非常高效,但它们依赖于具有特定目录结构的主机文件系统。(要部署到新主机的时候就麻烦了,移植性差,自己用的话性能倒是很不错),不能使用 Docker CLI 命令直接管理绑定挂载。绑定挂载允许访问敏感文件。

使用绑定挂载的一个副作用是,您可以通过在容器中运行的进程更改主机文件系统,包括创建、修改或删除重要的系统文件或目录。可能会产生安全隐患,包括影响主机系统上的非 Docker 进程。

tmpfs 挂载

tmpfs 挂载不会持久保存在磁盘上,无论是在 Docker 主机上还是在容器内。它可以在容器的生命周期内被容器使用,用于存储非持久状态或敏感信息。例如,在内部,swarm 服务使用 tmpfs 挂载将机密信息挂载到服务的容器中。

绑定挂载和卷都可以使用 -v 或 –volume 标志挂载到容器中,但每个的语法略有不同。对于 tmpfs 挂载,您可以使用 –tmpfs 标志。我们建议对容器和服务使用 –mount 标志,用于绑定挂载、卷或 tmpfs 挂载,因为语法更清晰。

实例

Volumes

有两种方式,其中 –mount 更加明确和详细。最大的区别是 -v 语法将所有选项组合在一个字段中,而 –mount 语法将它们分开。

1
2
3
4
5
6
7
8
9
10
11
#v
docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest

# mount
docker run -d \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest

-v 或 –volume:

由三个字段组成,以冒号字符 (:) 分隔。字段必须按正确的顺序排列,每个字段的含义不是很明显。
在命名卷的情况下,第一个字段是卷的名称,并且在给定的主机上是唯一的。对于匿名卷,省略第一个字段。
第二个字段是文件或目录在容器中挂载的路径。
第三个字段是可选的,是以逗号分隔的选项列表,例如 ro。

–mount

由多个键值对组成,以逗号分隔,每个由一个 <key>=<value> 元组组成。 –mount 语法比 -v 或 –volume 更冗长,但键的顺序并不重要,标志的值更容易理解。如果需要指定卷驱动程序选项,则必须使用 –mount。

  • type 挂载类型,可以是 bind、volume 或 tmpfs。
  • source 挂载源。对于命名卷,这是卷的名称。对于匿名卷,此字段被省略。可以指定为 source 或 src。
  • detination 将安装在容器中的文件或目录路径作为其值。可以指定为destination、dst 或target。
  • readonly 选项(如果存在)会导致绑定挂载以只读方式挂载到容器中。可以指定为 readonly 或 ro。
  • 可以多次指定的 volume-opt 选项,由选项名称及其值组成的键值对。
1
2
3
4
docker service create \
--mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
--name myservice \
<IMAGE>

验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo docker volume ls
DRIVER VOLUME NAME
local c0afcad67ec7b5489fe1a44aaf405a477b14fa806b64353759685d3fc20256fc

sudo docker inspect c0afcad67ec7b5489fe1a44aaf405a477b14fa806b64353759685d3fc20256fc
[
{
"CreatedAt": "2022-04-24T13:05:51+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/c0afcad67ec7b5489fe1a44aaf405a477b14fa806b64353759685d3fc20256fc/_data",
"Name": "c0afcad67ec7b5489fe1a44aaf405a477b14fa806b64353759685d3fc20256fc",
"Options": null,
"Scope": "local"
}
]

bind mounts 与 tmpfs

一样用 mount,只是 type 不同,如:

1
2
3
4
docker run -d --name tomcat-bind --mount type=bind,source=/tmp,target=/user/local tomcat:latest

#bind mounts use -v flag, absolute working directory
docker run -d -it --name=test-nginx -v /app/page:/usr/share/nginx/html nginx

参考

docker-docs-volumes

Manage data in Docker

Use volumes

docker数据持久化/共享—volume,bind-mount,tmpfs-mount

作者

ivy

发布于

2021-09-28

更新于

2023-03-25

许可协议

CC BY-NC-SA 4.0

评论