介绍
Docker 卷为容器化应用提供了持久性存储,即使容器停止或移除,数据也能保持完整。随着你的基础设施不断发展,你可能需要将这些卷迁移到不同的主机上,以支持扩展、升级或服务的重新部署。
本教程将指导你完成在主机之间迁移 Docker 卷的过程。你将学习如何创建卷、用数据填充卷、备份卷,以及在新主机上恢复卷。通过完成本实验,你将清楚地了解 Docker 卷迁移技术,以确保在你的容器化环境中数据持续可用。
理解和创建 Docker 卷
Docker 卷为你的容器提供持久性存储。在迁移卷之前,你需要了解它们是什么以及如何创建它们。
什么是 Docker 卷?
Docker 卷是持久化由 Docker 容器生成和使用的数据的首选机制。与存储在容器的可写层中的数据(在容器被移除时会丢失)不同,卷完全由 Docker 管理,并且独立于容器存在。
Docker 卷的一些主要优点包括:
- 数据在容器生命周期中的持久性
- 能够在容器之间共享数据
- 比容器的文件系统更好的性能
- 独立于容器的管理
创建你的第一个 Docker 卷
让我们从创建一个简单的 Docker 卷开始:
docker volume create my-data-volume
当你运行此命令时,Docker 将创建一个名为 my-data-volume 的新卷。你应该在终端中看到卷名称被打印出来:
my-data-volume
你可以使用以下命令列出系统上的所有 Docker 卷:
docker volume ls
这将显示一个包含所有卷的表格:
DRIVER VOLUME NAME
local my-data-volume
检查 Docker 卷
要获取有关你的卷的更多详细信息,请使用 inspect 命令:
docker volume inspect my-data-volume
你将以 JSON 格式看到有关卷的详细信息:
[
{
"CreatedAt": "2023-10-01T12:34:56Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-data-volume/_data",
"Name": "my-data-volume",
"Options": {},
"Scope": "local"
}
]
注意 Mountpoint 值——这是 Docker 在主机系统上存储卷数据的位置。
将 Docker 卷与容器一起使用
现在你已经创建了一个卷,让我们将其与容器一起使用。我们将创建一个简单的容器,该容器挂载卷并将一些数据添加到其中:
docker run --name my-container -v my-data-volume:/data ubuntu /bin/bash -c "echo 'Hello from Docker volume' > /data/test.txt"
此命令:
- 创建一个名为
my-container的容器 - 将
my-data-volume挂载到容器内的/data目录 - 运行一个简单的命令,将文本写入该目录中的文件
让我们通过创建另一个挂载相同卷的容器来验证数据是否已写入卷:
docker run --rm -v my-data-volume:/data ubuntu cat /data/test.txt
你应该看到输出:
Hello from Docker volume
这表明数据保留在卷中,并且可以被不同的容器访问。
准备卷迁移
在将 Docker 卷迁移到另一台主机之前,我们需要准备我们的源数据并了解迁移过程。在此步骤中,我们将向我们的卷添加更多数据并准备进行迁移。
向卷添加更多数据
让我们创建一个容器,该容器将向我们的卷添加更多数据。这将有助于演示所有卷数据都已正确迁移:
docker run --name data-generator -v my-data-volume:/data ubuntu /bin/bash -c "mkdir -p /data/config && echo 'database_url=postgres://user:password@db:5432/mydb' > /data/config/settings.conf && echo 'This is important data' > /data/important.txt"
此命令在我们的卷中创建具有示例内容的目录和文件。
让我们验证卷中的数据结构:
docker run --rm -v my-data-volume:/data ubuntu ls -la /data
你应该看到类似这样的输出:
total 12
drwxr-xr-x 3 root root 4096 Oct 1 12:34 .
drwxr-xr-x 1 root root 4096 Oct 1 12:34 ..
drwxr-xr-x 2 root root 4096 Oct 1 12:34 config
-rw-r--r-- 1 root root 21 Oct 1 12:34 important.txt
-rw-r--r-- 1 root root 24 Oct 1 12:34 test.txt
我们还检查一下其中一个文件的内容:
docker run --rm -v my-data-volume:/data ubuntu cat /data/important.txt
输出:
This is important data
了解卷迁移方法
有几种迁移 Docker 卷的方法:
- 直接主机到主机复制(Direct host-to-host copy):直接在主机之间复制卷数据
- 备份和恢复(Backup and restore):创建备份存档并在新主机上恢复它
- 使用 Docker 插件(Using Docker plugins):某些存储插件具有内置的复制功能
对于本实验,我们将使用备份和恢复方法,该方法适用于大多数环境,并且不需要特殊的插件。
创建卷的备份
要创建我们卷的备份,我们将使用 Docker 容器来存档卷内容:
docker run --rm -v my-data-volume:/source -v $(pwd):/backup ubuntu tar cvf /backup/my-data-volume-backup.tar -C /source .
此命令:
- 在容器中将我们的卷挂载到
/source - 在容器中将当前目录挂载到
/backup - 创建
/source目录中所有内容的 tar 存档,并将其保存到/backup/my-data-volume-backup.tar
验证是否创建了备份文件:
ls -lh my-data-volume-backup.tar
你应该看到类似这样的内容:
-rw-r--r-- 1 labex labex 10K Oct 1 12:34 my-data-volume-backup.tar
让我们检查备份文件的内容,以确保所有内容都已正确存档:
tar -tf my-data-volume-backup.tar
输出应包括:
./
./config/
./config/settings.conf
./important.txt
./test.txt
现在我们已经创建了卷的备份,我们准备好模拟将其迁移到新主机。
模拟将卷迁移到新主机
在现实世界中,你将使用 scp、rsync 或文件共享服务等工具将备份文件传输到新主机。对于本实验,我们将通过删除原始卷并创建一个新卷来恢复我们的数据,从而模拟迁移。
模拟新主机环境
首先,让我们清理旧容器,以模拟移动到新环境:
docker rm -f my-container data-generator
现在,让我们删除原始卷,以模拟在新主机上重新开始:
docker volume rm my-data-volume
创建一个新卷,它将代表我们在“新主机”上的卷:
docker volume create my-new-host-volume
从备份恢复卷
现在我们将把备份恢复到新卷:
docker run --rm -v my-new-host-volume:/destination -v $(pwd):/backup ubuntu bash -c "cd /destination && tar xvf /backup/my-data-volume-backup.tar"
此命令:
- 创建一个临时容器
- 将我们的新卷挂载到
/destination - 将当前目录(我们的备份所在位置)挂载到
/backup - 将 tar 存档解压缩到
/destination目录
验证已恢复的数据
让我们验证所有数据是否已正确恢复到新卷:
docker run --rm -v my-new-host-volume:/data ubuntu ls -la /data
你应该看到与之前相同的文件结构:
total 12
drwxr-xr-x 3 root root 4096 Oct 1 12:34 .
drwxr-xr-x 1 root root 4096 Oct 1 12:34 ..
drwxr-xr-x 2 root root 4096 Oct 1 12:34 config
-rw-r--r-- 1 root root 21 Oct 1 12:34 important.txt
-rw-r--r-- 1 root root 24 Oct 1 12:34 test.txt
检查其中一个文件的内容,以确保数据完好无损:
docker run --rm -v my-new-host-volume:/data ubuntu cat /data/important.txt
输出:
This is important data
也检查配置文件:
docker run --rm -v my-new-host-volume:/data ubuntu cat /data/config/settings.conf
输出:
database_url=postgres://user:password@db:5432/mydb
将恢复的卷与新容器一起使用
现在我们已经成功“迁移”了我们的卷,让我们将其与新容器一起使用:
docker run --name my-new-container -v my-new-host-volume:/app/data -d nginx
这会创建一个新的 Nginx 容器,该容器将我们恢复的卷挂载到 /app/data。
让我们验证容器是否可以访问卷数据:
docker exec my-new-container ls -la /app/data
你应该看到与之前相同的文件,确认迁移成功。
更新应用程序以使用新卷
在现实世界中,将卷迁移到新主机后,你需要更新你的 Docker Compose 文件或容器运行命令以使用新的卷名称或路径。例如,如果你使用 Docker Compose,你可能会按如下方式更新你的 docker-compose.yml 文件:
version: "3"
services:
webapp:
image: nginx
volumes:
- my-new-host-volume:/app/data
volumes:
my-new-host-volume:
external: true
这告诉 Docker 使用名为 my-new-host-volume 的外部创建的卷。
迁移过程现已完成!你已成功:
- 创建了一个 Docker 卷并向其中添加了数据
- 备份了卷数据
- 在模拟的“新主机”上创建了一个新卷
- 将备份数据恢复到新卷
- 验证了数据完整性
- 将新容器连接到已迁移的卷
最佳实践和高级迁移技术
现在你已经了解了 Docker 卷迁移的基础知识,让我们来探索一些最佳实践和高级技术,以使你的卷迁移更高效、更健壮。
规划卷迁移
在规划卷迁移时,请考虑以下因素:
- 卷大小:较大的卷传输时间更长,可能需要特殊处理。
- 停机时间要求:确定你的应用程序可以容忍的停机时间。
- 数据敏感性:确保敏感数据在传输过程中得到妥善保护。
- 网络带宽:考虑主机之间的可用带宽。
自动化迁移过程
对于频繁的迁移或多个卷的迁移,自动化可以节省时间并减少错误。让我们创建一个简单的 shell 脚本来自动化备份和恢复过程:
nano migrate-volume.sh
将以下内容添加到脚本中:
#!/bin/bash
## Simple Docker volume migration script
if [ $## -ne 2 ]; then
echo "Usage: $0 <source_volume> <destination_volume>"
exit 1
fi
SOURCE_VOLUME=$1
DEST_VOLUME=$2
BACKUP_FILE="/tmp/${SOURCE_VOLUME}-backup.tar"
echo "Creating backup of ${SOURCE_VOLUME}..."
docker run --rm -v ${SOURCE_VOLUME}:/source -v /tmp:/backup ubuntu tar cf /backup/${SOURCE_VOLUME}-backup.tar -C /source .
echo "Creating destination volume ${DEST_VOLUME}..."
docker volume create ${DEST_VOLUME}
echo "Restoring backup to ${DEST_VOLUME}..."
docker run --rm -v ${DEST_VOLUME}:/destination -v /tmp:/backup ubuntu bash -c "cd /destination && tar xf /backup/${SOURCE_VOLUME}-backup.tar"
echo "Migration complete. Verifying volume contents..."
docker run --rm -v ${DEST_VOLUME}:/data ubuntu ls -la /data
echo "Done!"
保存文件(Ctrl+O,然后 Enter)并退出(Ctrl+X)。
使脚本可执行:
chmod +x migrate-volume.sh
现在你可以使用一个命令来迁移卷:
./migrate-volume.sh my-new-host-volume another-volume
这将创建 my-new-host-volume 的备份,创建一个名为 another-volume 的新卷,并将备份恢复到其中。
处理大卷
对于大卷,基本的 tar 方法可能效率不高。这里有一些替代方案:
- 增量备份:仅传输自上次备份以来的更改。
- 压缩:使用压缩来减小备份文件的大小。
- 直接复制:使用
rsync在主机之间直接复制。
让我们实现一种压缩备份方法:
docker run --rm -v my-new-host-volume:/source -v $(pwd):/backup ubuntu tar czf /backup/compressed-backup.tar.gz -C /source .
添加到 tar 命令中的 z 选项启用了压缩,从而生成了更小的备份文件。这对于文本密集型数据尤其有用。
从压缩备份恢复:
docker volume create compressed-volume
docker run --rm -v compressed-volume:/destination -v $(pwd):/backup ubuntu bash -c "cd /destination && tar xzf /backup/compressed-backup.tar.gz"
生产环境中的卷迁移
在生产环境中,你可能需要考虑以下附加方法:
- 存储驱动程序复制:一些存储驱动程序支持内置复制。
- Docker 卷插件:为你的存储系统使用专用插件。
- 数据库备份:对于数据库卷,使用数据库的原生备份工具。
- 计划迁移:使用 cron 等工具安排定期备份。
这标志着你 Docker 卷迁移之旅的结束。现在你已经掌握了在主机之间有效迁移 Docker 卷的知识和工具,确保在基础设施变更期间容器化应用程序的数据保持完整。
总结
在本实验中,你学习了如何在主机之间迁移 Docker 卷,这是管理容器化应用程序的一项基本技能。你获得了以下方面的实践经验:
- 创建和管理 Docker 卷
- 在 Docker 卷中添加和访问数据
- 使用 tar 命令备份卷数据
- 在新主机上恢复卷数据
- 验证迁移后的数据完整性
- 为卷迁移创建自动化脚本
- 处理各种迁移场景,包括大卷
这些技能使你能够在环境之间移动容器、扩展你的基础设施或执行系统升级时保持数据连续性。Docker 卷迁移是一项基本操作,它使你能够自信地管理你的容器化应用程序,因为你知道你的持久数据可以根据需要安全可靠地传输。



