Docker卷:重命名或复制操作

问题描述 投票:0回答:2

根据文档 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 copy command-line-interface rename docker-volume
2个回答
8
投票

并不是真正的答案,但我会发布这个副本示例,因为我之前找不到任何答案,并且搜索它让我想到了这个问题。

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

5
投票

对于下一个搜索者,我制作了一个脚本,可以通过 @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
© www.soinside.com 2019 - 2024. All rights reserved.