如何使用 docker volume create 命令管理数据

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何使用 docker volume create 命令在 Docker 中有效管理数据持久化。我们将探讨创建基本卷的基本过程,由于卷由 Docker 管理,并且与绑定挂载相比更易于备份和迁移,因此它是存储容器数据的首选方法。

在掌握基础知识的基础上,你将深入学习如何使用特定的驱动程序和选项创建卷,以定制其行为。此外,本实验将指导你使用自定义挂载选项创建本地卷,并演示如何利用 NFS 创建本地卷,为各种数据存储场景提供灵活性。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/VolumeOperationsGroup(["Volume Operations"]) docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ContainerOperationsGroup -.-> docker/create("Create Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/VolumeOperationsGroup -.-> docker/volume("Manage Volumes") subgraph Lab Skills docker/exec -.-> lab-555258{{"如何使用 docker volume create 命令管理数据"}} docker/inspect -.-> lab-555258{{"如何使用 docker volume create 命令管理数据"}} docker/create -.-> lab-555258{{"如何使用 docker volume create 命令管理数据"}} docker/pull -.-> lab-555258{{"如何使用 docker volume create 命令管理数据"}} docker/volume -.-> lab-555258{{"如何使用 docker volume create 命令管理数据"}} end

创建基本卷

在这一步中,你将学习如何创建一个基本的 Docker 卷。卷是持久化 Docker 容器生成和使用的数据的首选方式。虽然绑定挂载也是一种选择,但卷由 Docker 管理,通常更易于备份或迁移。

首先,让我们使用 docker volume create 命令创建一个简单的卷。我们将这个卷命名为 myvolume

docker volume create myvolume

你应该会看到卷的名称打印到控制台,确认其已创建。

现在,让我们使用 docker volume inspect 命令检查卷的详细信息。这将向我们展示卷的驱动程序、挂载点和作用域等信息。

docker volume inspect myvolume

输出将提供有关该卷的详细信息。注意 Mountpoint 字段,它显示了主机上存储卷数据的位置。Docker 管理这个位置,你通常应避免直接在该目录中修改文件。

接下来,我们将运行一个容器并将这个卷附加到它上面。我们将使用 ubuntu 镜像,并将 myvolume 挂载到容器内的 /app 目录。我们还将运行一个简单的命令,将一些数据写入挂载卷内的文件。

首先,如果你本地没有 ubuntu 镜像,请拉取它。

docker pull ubuntu

现在,运行容器并将数据写入卷。

docker run -d --name mycontainer -v myvolume:/app ubuntu bash -c "echo 'Hello from the volume!' > /app/greeting.txt && tail -f /dev/null"

让我们分解一下这个命令:

  • docker run -d:以分离模式(在后台)运行容器。
  • --name mycontainer:将容器命名为 mycontainer
  • -v myvolume:/app:将名为 myvolume 的卷挂载到容器内的 /app 目录。
  • ubuntu:指定要使用的镜像。
  • bash -c "echo 'Hello from the volume!' > /app/greeting.txt && tail -f /dev/null":在容器内执行一个 bash 命令。它将字符串 "Hello from the volume!" 写入 /app 目录(即挂载的卷)中名为 greeting.txt 的文件,然后运行 tail -f /dev/null 以保持容器运行。

为了验证数据是否已写入卷,我们可以在运行的容器内执行一个命令来读取该文件。

docker exec mycontainer cat /app/greeting.txt

你应该会看到输出 "Hello from the volume!",确认数据已从容器内成功写入卷。

最后,让我们停止并移除容器。即使容器被移除,卷仍将保留。

docker stop mycontainer
docker rm mycontainer

使用特定驱动程序和选项创建卷

在这一步中,你将学习如何使用特定的驱动程序并提供特定于驱动程序的选项来创建 Docker 卷。虽然默认的 local 驱动程序足以满足许多用例,但 Docker 支持各种卷驱动程序,以用于不同的存储后端,如网络存储或云存储。

我们将继续使用 local 驱动程序,但演示如何显式指定它并传递选项。local 驱动程序支持诸如 typedeviceo 之类的选项,分别用于指定文件系统类型、要挂载的设备和挂载选项。

让我们使用 local 驱动程序创建一个名为 myvolume2 的卷,并指定一些选项。在这个示例中,我们将使用 tmpfs 文件系统类型,它将数据存储在内存中。这对于不需要在主机重启后持久化的临时数据很有用。

docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m myvolume2

让我们分解一下这个命令:

  • docker volume create:用于创建卷的命令。
  • --driver local:显式指定 local 卷驱动程序。
  • --opt type=tmpfs:将选项 type=tmpfs 传递给驱动程序,指定文件系统类型。
  • --opt device=tmpfs:将选项 device=tmpfs 传递给驱动程序,指定设备。对于 tmpfs,设备也是 tmpfs
  • --opt o=size=100m:将选项 o=size=100m 传递给驱动程序。o 选项用于传递挂载选项。在这种情况下,我们将 tmpfs 卷的最大大小设置为 100 兆字节。
  • myvolume2:要创建的卷的名称。

成功创建后,你应该会看到卷的名称打印到控制台。

现在,让我们检查该卷,查看所应用的驱动程序和选项。

docker volume inspect myvolume2

在输出中,你应该会看到 Driver 字段设置为 localOptions 字段列出了我们提供的选项(type=tmpfsdevice=tmpfso=size=100m)。Mountpoint 将显示这个 tmpfs 卷在主机上的挂载位置。

接下来,我们将运行一个容器并将这个新卷附加到它上面。我们将再次使用 ubuntu 镜像,并将 myvolume2 挂载到容器内的 /data 目录。

首先,如果你本地没有 ubuntu 镜像(尽管你可能在上一步已经拉取了),请拉取它。

docker pull ubuntu

现在,运行容器并附加卷。

docker run -d --name mycontainer2 -v myvolume2:/data ubuntu tail -f /dev/null

这个命令以分离模式运行一个名为 mycontainer2ubuntu 容器,并将 myvolume2 挂载到 /datatail -f /dev/null 使容器保持运行。

由于 myvolume2 是一个 tmpfs 卷,写入容器内 /data 的任何数据都将存储在内存中,并且在容器停止和移除后,或者主机重启后,这些数据将不会持久化。

让我们停止并移除容器。

docker stop mycontainer2
docker rm mycontainer2

myvolume2 仍然存在,但它的内容(如果有写入的话)已经消失了,因为它是一个 tmpfs 卷。

创建带有挂载选项的本地卷

在这一步中,你将学习如何创建一个本地 Docker 卷并指定挂载选项。挂载选项使你能够控制文件系统的挂载方式,例如设置权限、启用特定功能或优化性能。

我们将创建一个名为 myvolume3 的本地卷,并使用 o 选项指定挂载选项。在这个示例中,我们将设置 uidgid 选项,以确保容器在卷中创建的文件由主机上的特定用户和组拥有。这在容器和主机之间共享数据时,对管理权限很有用。

首先,让我们在主机上创建一个目录,作为卷的源。对于标准的本地卷,这并非严格必要,但它有助于说明挂载选项如何影响底层文件系统。

mkdir -p ~/project/myvolumedata

现在,让我们使用 local 驱动程序创建卷 myvolume3,并使用 uidgid 指定 o 选项。我们将使用当前 labex 用户的用户和组 ID。你可以使用 id -uid -g 命令找到你的用户和组 ID。

USER_ID=$(id -u)
GROUP_ID=$(id -g)
docker volume create --driver local --opt type=none --opt device=/home/labex/project/myvolumedata --opt o=bind,uid=$USER_ID,gid=$GROUP_ID myvolume3

让我们分解一下这个命令:

  • docker volume create:用于创建卷的命令。
  • --driver local:指定 local 卷驱动程序。
  • --opt type=none:指定不自动创建文件系统类型。我们是绑定到一个现有的目录。
  • --opt device=/home/labex/project/myvolumedata:指定要挂载的设备,即我们在主机上创建的目录。注意使用的是绝对路径 /home/labex/project/myvolumedata
  • --opt o=bind,uid=$USER_ID,gid=$GROUP_ID:传递挂载选项。
    • bind:指定一个绑定挂载,将卷链接到指定的设备(我们的主机目录)。
    • uid=$USER_ID:将卷中创建的文件的用户 ID 设置为当前用户的 ID。
    • gid=$GROUP_ID:将卷中创建的文件的组 ID 设置为当前用户的组 ID。
  • myvolume3:卷的名称。

你应该会看到卷的名称打印到控制台。

现在,让我们检查该卷以查看选项。

docker volume inspect myvolume3

在输出中,你应该会看到 DriverlocalOptions 包括 type=nonedevice=/home/labex/project/myvolumedatao=bind,uid=...,gid=...(包含你的用户和组 ID)。Mountpoint 将与 device 路径相同。

接下来,我们将运行一个容器并附加这个卷。我们将使用 ubuntu 镜像,并将 myvolume3 挂载到容器内的 /app 目录。然后,我们将在容器的 /app 目录中创建一个文件,并在主机上检查其所有权。

首先,如果需要的话,拉取 ubuntu 镜像。

docker pull ubuntu

现在,运行容器并在挂载的卷中创建一个文件。

docker run --rm -v myvolume3:/app ubuntu bash -c "echo 'Testing ownership' > /app/testfile.txt && ls -l /app/testfile.txt"

这个命令运行一个 ubuntu 容器,将 myvolume3 挂载到 /app,将 "Testing ownership" 写入 /app/testfile.txt,然后列出容器内的文件详细信息。你应该会看到容器内的文件显示为 root 所有权,因为容器默认通常以 root 身份运行。

现在,让我们在主机的 ~/project/myvolumedata 目录中检查该文件的所有权。

ls -l ~/project/myvolumedata/testfile.txt

你应该会看到文件 testfile.txt 在主机上由 labex 用户和组拥有,这得益于我们在创建卷时指定的 uidgid 挂载选项。

最后,让我们清理创建的目录。

rm -rf ~/project/myvolumedata

使用 NFS 创建本地卷

在这一步中,你将学习如何创建一个使用 NFS 共享作为后端存储的本地 Docker 卷。这允许容器将数据存储在网络附属存储设备上,使数据可从多个主机访问,并提供集中式存储解决方案。

要将 NFS 与 local 卷驱动程序一起使用,你需要使用 device 选项指定 NFS 服务器地址和共享目录的路径,并使用 type 选项将文件系统类型指定为 nfs。你还需要使用 o 选项提供适当的挂载选项。

对于这个实验环境,我们将使用回环地址 127.0.0.1 和主机上的一个目录来模拟 NFS 共享。注意:在实际场景中,你需要将 127.0.0.1 替换为你的 NFS 服务器的实际 IP 地址或主机名,并将 /path/to/nfs/share 替换为 NFS 服务器上的导出路径。

首先,让我们在主机上创建一个目录,作为模拟的 NFS 共享。

mkdir -p ~/project/nfs_share

现在,让我们使用带有 NFS 选项的 local 驱动程序创建卷 myvolume4

sudo docker volume create --driver local --opt type=nfs --opt device=127.0.0.1:/home/labex/project/nfs_share --opt o=addr=127.0.0.1,rw myvolume4

让我们分解一下这个命令:

  • sudo docker volume create:我们使用 sudo,因为创建 NFS 卷通常需要 root 权限才能在主机上执行挂载操作。
  • --driver local:指定 local 卷驱动程序。
  • --opt type=nfs:将文件系统类型指定为 NFS。
  • --opt device=127.0.0.1:/home/labex/project/nfs_share:指定 NFS 设备。格式为 nfs_server_address:/exported_path。我们使用回环地址和刚刚创建的目录。注意使用的是绝对路径 /home/labex/project/nfs_share
  • --opt o=addr=127.0.0.1,rw:将挂载选项传递给 NFS 客户端。
    • addr=127.0.0.1:指定 NFS 服务器的地址。
    • rw:以读写权限挂载共享。
  • myvolume4:卷的名称。

成功创建后,你应该会看到卷的名称打印到控制台。

现在,让我们检查该卷以查看 NFS 特定的详细信息。

docker volume inspect myvolume4

在输出中,你应该会看到 DriverlocalOptions 应包括 type=nfsdevice=127.0.0.1:/home/labex/project/nfs_shareo=addr=127.0.0.1,rwMountpoint 将显示 Docker 在主机上挂载这个 NFS 卷的位置。

接下来,我们将运行一个容器并附加这个 NFS 卷。我们将使用 ubuntu 镜像,并将 myvolume4 挂载到容器内的 /data 目录。然后,我们将在容器的 /data 目录中创建一个文件,并验证它是否存在于主机的模拟 NFS 共享中。

首先,如果需要的话,拉取 ubuntu 镜像。

docker pull ubuntu

现在,运行容器并在挂载的卷中创建一个文件。

docker run --rm -v myvolume4:/data ubuntu bash -c "echo 'Data on NFS' > /data/nfs_test.txt && ls -l /data/nfs_test.txt"

这个命令运行一个 ubuntu 容器,将 myvolume4 挂载到 /data,将 "Data on NFS" 写入 /data/nfs_test.txt,并列出容器内的文件详细信息。

现在,让我们在主机的 ~/project/nfs_share 目录中检查该文件。

ls -l ~/project/nfs_share/nfs_test.txt

你应该会看到列出的 nfs_test.txt 文件,这证实了使用 NFS 卷在容器内写入的数据存在于主机的模拟 NFS 共享中。

最后,让我们清理创建的目录。

rm -rf ~/project/nfs_share

总结

在这个实验中,你学习了如何使用 docker volume create 命令创建和管理 Docker 卷。你首先创建了一个基本卷并检查其详细信息,了解了 Docker 如何管理数据存储位置。然后,你练习了将这个卷附加到容器并向其中写入数据,展示了卷如何为容器数据提供持久存储。本实验还涵盖了使用特定驱动程序和选项创建卷,包括带有挂载选项的本地卷和使用 NFS 的本地卷,展示了 Docker 卷针对不同存储需求的灵活性和各种用例。