介绍
在本实验中,你将学习如何使用卷(volumes)来管理 Docker 容器中的数据。Docker 卷是持久化由 Docker 容器生成和使用的数据的首选机制。本实验将引导你了解 Docker 卷的各个方面,包括创建、管理、数据共享、备份和恢复。通过本实验,你将掌握如何在 Docker 环境中有效管理数据。
在本实验中,你将学习如何使用卷(volumes)来管理 Docker 容器中的数据。Docker 卷是持久化由 Docker 容器生成和使用的数据的首选机制。本实验将引导你了解 Docker 卷的各个方面,包括创建、管理、数据共享、备份和恢复。通过本实验,你将掌握如何在 Docker 环境中有效管理数据。
在深入探讨 Docker 卷之前,了解 Docker 中可用的不同存储选项非常重要。Docker 提供了三种主要的数据存储选项:
在本实验中,我们将主要关注卷,因为它们是管理 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"
}
]
此输出告诉我们关于卷的几项信息:
如果你现在不理解所有这些细节,请不要担心。对我们来说,最重要的部分是名称(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,请记住将数据持久性和管理视为容器化应用程序的关键部分。始终为数据备份和恢复做好计划,尤其是在生产环境中。