数据持久化
数据持久化的目的
大家肯定能发现,每次我们根据镜像创建出来的容器都是独立的,各个容器之间是完全隔离的;
每次在一个容器里新建一个文件,然后另一个根据相同镜像创建出来的容器却访问不到这个文件;
但是有时候我们想在容器之间共享数据,比如多个容器共享一份管理员名单,我该怎么办呢?
这时候就要用到我们的Volume
(卷)了, 它可以在镜像中创建一个文件夹,用于保存容器的共享文件。
在学习下面内容之前,我们只用知道卷就是用来存储共享数据的。
怎么创建卷
我们可以通过docker volume create [OPTIONS] [VOLUME]
比如使用: docker create todo-db来创建一个名为todo-db的卷。
常用选项
- --label: 指定一个标签名,用于介绍该卷
- --driver: 卷的驱动程序是一种插件机制,用于指定 Docker 如何实现数据卷的创建、管理和存储等操作。每个驱动程序可以提供不同的功能和性能特点,可以根据需要选择和配置。
默认情况下,Docker 使用本地驱动程序来创建和管理数据卷。
- --opt: 用于指定驱动程序特定的选项。具体选项的名称和取值取决于所选的驱动程序。
查看具体卷
当我们创建卷之后,我们可以怎么查看
docker volume inspect [OPTIONS] VOLUME [VOLUME...]
这个命令是查看volume的完整信息。
常用option就是:
-f: 用于指定数据显示的格式,默认是json格式。
举个例子吧: docker volume inspect todo-db
, 运行该命令之前你必须先创建todo-db这个卷。
然后你就可以看到如下信息:
它默认是存储在本地文件中的,我发现我在windows里找不到它的Mountpoint, gpt说是在docker的WSL2的文件系统中。
查看所有的卷
docker volume ls 命令可以查看所有的卷
你可以看到一些具体卷,也可以看到一些匿名卷,匿名卷就是你看到的那些一串串感觉像十六进制的数据
下面讲讲匿名卷产生的原因
匿名卷产生的原因
第一种方式:
使用 docker volume create, 你不给它指定名字,那它就会帮你创建一个随机的名字。
第二种方式:
当您在 Dockerfile 中使用 VOLUME
指令指定一个卷时,在运行容器时如果没有明确指定该卷的挂载点位置,Docker 会自动为该卷创建一个匿名卷,并将其挂载到容器中。这个匿名卷的挂载点将会是 Dockerfile 中指定的卷的路径。
下面的例子可以不看
例如,以下是一个包含 VOLUME
指令的 Dockerfile:
FROM ubuntu:latest
VOLUME /myvolume
在上面的示例中,Dockerfile 中指定了一个名为 /myvolume
的卷。在运行容器时,如果没有使用 -v
参数来指定该卷的挂载点位置,Docker 会自动为该卷创建一个匿名卷,并将其挂载到容器中的 /myvolume
目录中。
例如,以下命令将会运行一个基于上面的 Dockerfile 构建的镜像,并启动一个容器:
$ docker run myimage
在上面的命令中,没有使用 -v
参数来指定要将 /myvolume
挂载到容器中的哪个位置。因此,Docker 会自动为 /myvolume
创建一个匿名卷,并将其挂载到容器中的 /myvolume
目录中。
匿名卷与具名卷的区别
匿名卷是由Docker自动创建的卷,没有用户定义的名称。匿名卷在容器内部使用,用于存储容器产生的数据。匿名卷是临时的,当容器被删除时,匿名卷中的数据也会被删除。
而具名卷是一直存在的,不会自动删除。
但是由 docker volume create创建的卷是不会自动删除的,因为没有绑定任何一个容器,上面说的是启动容器自动绑定的匿名卷,所以会与容器生命周期挂钩。
删除容器之前:
删除容器之后:
可以发现,与容器挂钩的匿名卷自动删除了。
删除卷
docker volume rm <卷名>
加个 -f 表示强制删除。
使用卷
两种使用卷的方法
下面两种写法一样
docker run -it --mount type=volume,src=todo-db,target=/test/todo ubuntu /bin/bash
docker run -it -v todo-db:/test/todo ubuntu /bin/bash
- 我们使用
docker volume create todo-db
来创建一个名叫todo-db的卷 - 使用
docker volume ls
查看卷的列表。 - 这样之后,我们随便启动一个容器挂载该volume,
docker run -it --mount type=volume,src=todo-db,target=/test/todo ubuntu /bin/bash
- 然后进入我们指定的挂载volume的文件,可以看到
可以看到卷里面的文件。
我们在里面随便添加一些数据,如果增加一个hhh.txt。touch hhh.txt
。 - 同样的命令,再开一个容器:
docker run -it --mount type=volume,src=todo-db,target=/test/todo ubuntu /bin/bash
- 进入新容器,查看里面的卷:
可以看到里面的数据,包括我们刚才添加的 hhh.txt; 现在删除 hhh.txt, 去刚才的容器看看,然后发现文件消失。
验证完毕, 数据确实是共享的,可以对里面的数据进行修改然后挂载该卷的容器都能看到。
命令查看卷
当大家忘记卷放哪了,可以使用命令去查看。
查看容器挂载的卷: docker inspect <Container ID>, 就可以看到
如果您使用--mount
选项来挂载卷,那么在返回的输出中,卷的详细信息将会包含在Mounts
字段中。
下面的指令可以只看.Mounts:
docker inspect --format='{{.Mounts}}' <containerId>