【docker基础】: 数据持久化--volume

71 阅读5分钟

数据持久化

数据持久化的目的

大家肯定能发现,每次我们根据镜像创建出来的容器都是独立的,各个容器之间是完全隔离的;

每次在一个容器里新建一个文件,然后另一个根据相同镜像创建出来的容器却访问不到这个文件;

但是有时候我们想在容器之间共享数据,比如多个容器共享一份管理员名单,我该怎么办呢?

这时候就要用到我们的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这个卷。

然后你就可以看到如下信息:

image.png

它默认是存储在本地文件中的,我发现我在windows里找不到它的Mountpoint, gpt说是在docker的WSL2的文件系统中。

查看所有的卷

docker volume ls 命令可以查看所有的卷

image.png

你可以看到一些具体卷,也可以看到一些匿名卷,匿名卷就是你看到的那些一串串感觉像十六进制的数据


下面讲讲匿名卷产生的原因

匿名卷产生的原因

第一种方式:

使用 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创建的卷是不会自动删除的,因为没有绑定任何一个容器,上面说的是启动容器自动绑定的匿名卷,所以会与容器生命周期挂钩。

删除容器之前:

image.png

删除容器之后:

image.png

可以发现,与容器挂钩的匿名卷自动删除了。

删除卷

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

  1. 我们使用docker volume create todo-db来创建一个名叫todo-db的卷
  2. 使用docker volume ls查看卷的列表。
  3. 这样之后,我们随便启动一个容器挂载该volume,docker run -it --mount type=volume,src=todo-db,target=/test/todo ubuntu /bin/bash
  4. 然后进入我们指定的挂载volume的文件,可以看到 image.png 可以看到卷里面的文件。
    我们在里面随便添加一些数据,如果增加一个hhh.txt。 touch hhh.txt
  5. 同样的命令,再开一个容器: docker run -it --mount type=volume,src=todo-db,target=/test/todo ubuntu /bin/bash
  6. 进入新容器,查看里面的卷: image.png 可以看到里面的数据,包括我们刚才添加的 hhh.txt; 现在删除 hhh.txt, 去刚才的容器看看,然后发现文件消失。

验证完毕, 数据确实是共享的,可以对里面的数据进行修改然后挂载该卷的容器都能看到。

命令查看卷

当大家忘记卷放哪了,可以使用命令去查看。

查看容器挂载的卷: docker inspect <Container ID>, 就可以看到

image.png

如果您使用--mount选项来挂载卷,那么在返回的输出中,卷的详细信息将会包含在Mounts字段中。

下面的指令可以只看.Mounts:

docker inspect --format='{{.Mounts}}' <containerId>

image.png