使用 Docker 卷

DockerDockerBeginner
立即练习

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

介绍

在本实验中,你将学习如何使用卷(volumes)来管理 Docker 容器中的数据。Docker 卷是持久化由 Docker 容器生成和使用的数据的首选机制。本实验将引导你了解 Docker 卷的各个方面,包括创建、管理、数据共享、备份和恢复。通过本实验,你将掌握如何在 Docker 环境中有效管理数据。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/VolumeOperationsGroup(["Volume Operations"]) docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/stop("Stop Container") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/VolumeOperationsGroup -.-> docker/volume("Manage Volumes") subgraph Lab Skills docker/run -.-> lab-389189{{"使用 Docker 卷"}} docker/ls -.-> lab-389189{{"使用 Docker 卷"}} docker/stop -.-> lab-389189{{"使用 Docker 卷"}} docker/rm -.-> lab-389189{{"使用 Docker 卷"}} docker/exec -.-> lab-389189{{"使用 Docker 卷"}} docker/inspect -.-> lab-389189{{"使用 Docker 卷"}} docker/volume -.-> lab-389189{{"使用 Docker 卷"}} end

理解 Docker 存储选项

在深入探讨 Docker 卷之前,了解 Docker 中可用的不同存储选项非常重要。Docker 提供了三种主要的数据存储选项:

  1. 卷(Volumes):Docker 中持久化数据的首选机制。
  2. 绑定挂载(Bind mounts):将主机上的特定路径连接到容器。
  3. tmpfs 挂载(tmpfs mounts):将数据临时存储在主机内存中。

在本实验中,我们将主要关注卷,因为它们是管理 Docker 数据的最灵活且推荐的方式。

让我们从列出你系统上的当前卷开始:

docker volume ls

你会看到类似以下的输出:

DRIVER    VOLUME NAME
local     jenkins-data

此命令列出了系统上的所有 Docker 卷。输出显示了卷驱动(通常是 "local")和卷名称。你可能会看到一些现有的卷,或者如果你尚未创建任何卷,列表可能为空。

如果你看到不同的卷名称或根本没有卷,请不要担心。这是正常的,具体取决于你之前在系统上使用 Docker 的情况。

创建和管理命名卷

现在,让我们创建一个新的命名卷。命名卷是你显式创建并赋予特定名称的卷,这使得后续引用和管理更加方便。

运行以下命令来创建一个新卷:

docker volume create my_data

此命令创建了一个名为 my_data 的新卷。Docker 会处理所有关于卷在主机系统上存储位置和方式的细节。

让我们验证卷是否已成功创建:

docker volume ls

现在你应该会在卷列表中看到 my_data,以及之前可能存在的其他卷。

要获取有关卷的更多详细信息,我们可以使用 inspect 命令:

docker volume inspect my_data

这将输出类似以下内容:

[
  {
    "CreatedAt": "2024-08-22T14:31:09+08:00",
    "Driver": "local",
    "Labels": {},
    "Mountpoint": "/var/lib/docker/volumes/my_data/_data",
    "Name": "my_data",
    "Options": {},
    "Scope": "local"
  }
]

此输出告诉我们关于卷的几项信息:

  • 创建时间
  • 使用的驱动(本例中为 local)
  • 挂载点(数据在主机系统上的实际存储位置)
  • 我们赋予的名称

如果你现在不理解所有这些细节,请不要担心。对我们来说,最重要的部分是名称(Name)和挂载点(Mountpoint)。

在容器中使用卷

现在我们已经有了一个卷,让我们将其与容器一起使用。我们将启动一个新容器并将卷挂载到其中。

运行以下命令:

docker run -d --name my_container -v my_data:/app/data ubuntu:latest sleep infinity

让我们分解这个命令:

  • docker run:告诉 Docker 运行一个新容器
  • -d:以分离模式(后台运行)运行容器
  • --name my_container:为容器命名,方便后续引用
  • -v my_data:/app/data:将我们的 my_data 卷挂载到容器内的 /app/data 目录
  • ubuntu:latest:我们用于容器的镜像
  • sleep infinity:容器运行的命令,使容器无限期保持运行状态

现在我们的容器正在运行,并且卷已挂载。让我们在卷中创建一些数据:

docker exec my_container sh -c "echo 'Hello from Docker volume' > /app/data/test.txt"

此命令执行以下操作:

  • docker exec:允许我们在运行的容器中执行命令
  • my_container:我们的容器名称
  • sh -c "...":在容器内运行一个 shell 命令
  • 实际命令在卷中创建一个名为 test.txt 的文件,内容为 "Hello from Docker volume"

为了验证数据是否已写入,我们可以读取文件:

docker exec my_container cat /app/data/test.txt

你应该会在控制台中看到打印的消息 "Hello from Docker volume"。

在容器之间共享数据

Docker 卷的一大优势是能够在容器之间共享数据。让我们创建另一个使用相同卷的容器:

docker run -d --name another_container -v my_data:/app/shared_data ubuntu:latest sleep infinity

这个命令与我们之前使用的命令非常相似,但我们为容器赋予了一个不同的名称,并将卷挂载到容器内的不同路径。

现在,让我们验证这个新容器是否可以访问我们之前创建的数据:

docker exec another_container cat /app/shared_data/test.txt

你应该会看到我们之前写入的 "Hello from Docker volume" 消息。这表明两个容器正在访问相同的数据。

让我们从这个新容器中添加更多数据:

docker exec another_container sh -c "echo 'Data from another container' >> /app/shared_data/test.txt"

此命令将新的一行追加到我们的 test.txt 文件中。

现在,如果我们从任一容器检查文件内容,应该会看到两行内容:

docker exec my_container cat /app/data/test.txt

你应该会在输出中看到 "Hello from Docker volume" 和 "Data from another container"。

这展示了 Docker 卷如何用于在容器之间共享数据,这对于许多应用程序来说非常有用。

卷的备份与恢复

备份和恢复 Docker 卷对于数据保护至关重要。让我们逐步完成这一过程:

首先,我们需要停止并删除使用该卷的容器。这是因为在卷被使用时无法删除它:

docker stop my_container another_container
docker rm my_container another_container

现在,让我们创建卷的备份:

docker run --rm -v my_data:/source:ro -v $(pwd):/backup ubuntu tar cvf /backup/my_data_backup.tar -C /source .

这个命令可能看起来有些复杂,让我们分解一下:

  • docker run --rm:运行一个临时容器,并在完成后将其删除
  • -v my_data:/source:ro:将我们的卷以只读方式挂载到容器中
  • -v $(pwd):/backup:将当前目录挂载为容器中的 /backup
  • ubuntu:使用 Ubuntu 镜像
  • tar cvf /backup/my_data_backup.tar -C /source .:创建卷数据的 tar 归档文件

现在,让我们删除原始卷:

docker volume rm my_data

为了恢复数据,我们将创建一个新卷并将备份解压到其中:

docker volume create my_restored_data
docker run --rm -v my_restored_data:/dest -v $(pwd):/backup ubuntu bash -c "tar xvf /backup/my_data_backup.tar -C /dest"

这将创建一个新卷并将我们的备份解压到其中。

让我们验证数据是否已恢复:

docker run --rm -v my_restored_data:/app/data ubuntu cat /app/data/test.txt

你应该会看到我们之前创建的文件内容。

总结

在本实验中,你学习了如何使用 Docker 卷。你创建并管理了命名卷,将卷与容器结合使用,在容器之间共享数据,并执行了备份和恢复操作。这些技能对于在 Docker 环境中有效管理数据至关重要。

关键要点:

  • Docker 卷提供了一种灵活且高效的方式来管理容器中的持久化数据。
  • 可以使用 Docker CLI 命令轻松创建、检查和删除卷。
  • 卷中的数据可以在多个容器之间共享。
  • 备份和恢复卷对于数据保护至关重要,可以使用标准的 Linux 命令实现。

随着你继续使用 Docker,请记住将数据持久性和管理视为容器化应用程序的关键部分。始终为数据备份和恢复做好计划,尤其是在生产环境中。