Docker Volumes:掌握容器中的持久存储

在这里,你将学习如何使用卷管理 Docker 容器中的数据。Docker 卷是用于持久保存 Docker 容器生成和使用的数据的首选机制。本实验将引导你了解 Docker 卷的各个方面,包括创建、管理、数据共享、备份和恢复。在本实验结束时,你将对如何有效地管理 Docker 环境中的数据有深入的了解。

了解 Docker 存储选项

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

  • volumes:Docker 中持久保存数据的首选机制。
  • 绑定挂载:将主机的特定路径连接到容器。
  • tmpfs 挂载:将数据临时存储在主机的内存中。

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

让我们首先列出系统上的当前卷:

1
docker volume ls

你将看到类似如下的输出:

1
2
DRIVER    VOLUME NAME
local jenkins-data

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

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

创建和管理命名卷

现在,让我们创建一个新的命名卷。命名卷是你明确创建并指定特定名称的卷。这使得以后引用和管理更加容易。

运行此命令以创建新卷:

1
docker volume create my_data

此命令创建一个名为 my_data 的新卷。Docker 将处理此卷在主机系统上存储位置和存储方式的所有详细信息。

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

1
docker volume ls

你现在应该可以在卷列表中看到 my_data,以及之前存在的任何卷。

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

1
docker volume inspect my_data

这将输出类似以下内容的内容:

1
2
3
4
5
6
7
8
9
10
11
[
{
"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"
}
]

此输出告诉我们有关卷的几个信息:

  • 创建时间
  • 它使用的驱动程序(在本例中为本地)
  • 挂载点(数据实际存储在主机系统上的位置)
  • 我们为其指定的名称

如果你现在不了解所有这些详细信息,请不要担心。对我们来说,最重要的部分是名称和挂载点。

将卷与容器一起使用

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

运行此命令:

1
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:这是容器将运行的命令。它只是让容器无限期地运行

现在我们的容器正在运行,卷已安装。让我们在卷中创建一些数据:

1
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”

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

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

你应该看到控制台上打印出“Hello from Docker volume”消息。

在容器之间共享数据

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

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

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

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

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

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

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

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

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

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

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

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

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

卷备份和恢复

备份和恢复 Docker 卷对于数据保存至关重要。让我们来看看这个过程:

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

1
2
docker stop my_container another_container
docker rm my_container another_container

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

1
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 存档

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

1
docker volume rm my_data

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

1
2
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"

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

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

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

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

摘要

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

关键要点:

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

在继续使用 Docker 时,请记住将数据持久性和管理视为容器化应用程序的一个重要方面。始终规划数据备份和恢复,尤其是在生产环境中。