根据文档 Docker 卷以这种方式进行广告:
卷是持久保存 Docker 容器生成和使用的数据的首选机制。虽然绑定挂载取决于主机的目录结构和操作系统,但卷完全由 Docker 管理。
但是如果它们这么好,为什么没有类似的操作来管理它们:复制,重命名?
命令:
docker volume --help
仅提供以下选项:
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
文档还没有说明任何其他命令,也没有任何具有复制或重命名功能的解决方法。
我想重命名当前现有的卷并创建另一个(空白)来代替最初命名的卷,并用新数据填充它以进行测试。
完成测试后,我可能希望(或不希望)删除新创建的卷,并将另一个卷重命名为之前的(原始)名称,以恢复卷设置之前的状态。
我不想创建要重命名的原始卷的备份。重命名对我来说已经足够好了,而且比创建备份和恢复要快得多。
编辑 docker-compose 文件并更改卷的名称,这也是我想避免的事情。
是否有任何解决方法可以用于重命名卷?
针对
Docker Root Dir: /var/lib/docker
和 volumes
子目录的 shell 进行低级手动管理是否可以作为解决方案,或者该方法可能会导致某些 dockeremon 数据不一致?
并不是真正的答案,但我会发布这个副本示例,因为我之前找不到任何答案,并且搜索它让我想到了这个问题。
Docker 建议
--volumes-from
用于备份目的此处。--volumes-from
的意义。所以我只使用了一个中间容器,安装了两个卷和一个复制命令。
要完成迁移,新容器可以使用新卷
这是一个快速测试
准备一卷
prova
docker run --name myname -d -v prova:/usr/share/nginx/html nginx:latest
docker exec myname touch /usr/share/nginx/html/added_file
docker stop myname
验证该卷是否包含 nginx 数据 + 我们的文件
added_file
sudo ls /var/lib/docker/volumes/prova/_data
输出:
50x.html added_file index.html
将数据迁移到卷
prova2
docker run --rm \
-v prova:/original \
-v prova2:/migration \
ubuntu:latest \
bash -c "cp -R /original/* /migration/"
验证新卷具有相同的数据
sudo ls /var/lib/docker/volumes/prova2/_data
输出:
50x.html added_file index.html
使用迁移的卷运行新容器:
docker run --name copyname -d -v prova2:/user/share/nginx/html nginx:latest
验证新容器在原始卷挂载点看到迁移的数据:
docker exec copyname ls -al /user/share/nginx/html
对于下一个搜索者,我制作了一个脚本,可以通过 @Lennonry 示例复制卷。这是https://github.com/KOYU-Tech/docker-volume-copy
为历史编写脚本:
#!/bin/bash
if (( $# < 2 )); then
echo ""
echo "No arguments provided"
echo "Use command example:"
echo "./dcv.sh OLD_VOLUME_NAME NEW_VOLUME_NAME"
echo ""
exit 1
fi
OLD_VOLUME_NAME="$1"
NEW_VOLUME_NAME="$2"
echo "== From '$OLD_VOLUME_NAME' to '$NEW_VOLUME_NAME' =="
function isVolumeExists {
local isOldExists=$(docker volume inspect "$1" 2>/dev/null | grep '"Name":')
local isOldExists=${isOldExists#*'"Name": "'}
local isOldExists=${isOldExists%'",'}
local isOldExists=${isOldExists##*( )}
if [[ "$isOldExists" == "$1" ]]; then
return 1
else
return 0
fi
}
# check if old volume exists
isVolumeExists ${OLD_VOLUME_NAME}
if [[ "$?" -eq 0 ]]; then
echo "Volume $OLD_VOLUME_NAME doesn't exist"
exit 2
fi
# check if new volume exists
isVolumeExists ${NEW_VOLUME_NAME}
if [[ "$?" -eq 0 ]]; then
echo "creating '$NEW_VOLUME_NAME' ..."
docker volume create ${NEW_VOLUME_NAME} 2>/dev/null 1>/dev/null
isVolumeExists ${NEW_VOLUME_NAME}
if [[ "$?" -eq 0 ]]; then
echo "Cannot create new volume"
exit 3
else
echo "OK"
fi
fi
# most important part, data migration
docker run --rm --volume ${OLD_VOLUME_NAME}:/source --volume ${NEW_VOLUME_NAME}:/destination ubuntu:latest bash -c "echo 'copying volume ...'; cp -Rp /source/* /destination/"
if [[ "$?" -eq 0 ]]; then
echo "Done successfuly 🎉"
else
echo "Some error occured 😭"
fi