如何将仅数据卷从一个主机移植到另一个主机?

时间:2014-02-06 08:20:41

标签: docker

Working with Volumes上的Docker文档中所述,有一个所谓的仅数据容器的概念,它提供了一个可以挂载到多个其他容器中的卷,无论数据专用容器是否实际运行。

基本上,这听起来很棒。但有一件事我不明白。

由于Docker在主机上的某个内部文件夹中创建并管理这些卷(由于可移植性原因而显式映射到主机上的文件夹)({{1> }})。

假设我使用这样的卷,然后我需要将它从一个主机迁移到另一个主机 - 如何移植卷? AFAICS它有一个唯一的ID - 我可以将卷及其仅数据容器复制到新主机吗?如何找出要复制的文件?或者是否有一些内置于Docker的支持我还没有发现?

7 个答案:

答案 0 :(得分:111)

官方答案现已公布:

Sharing Directories using Volumes

在"备份,还原或迁移数据卷"你有这个部分:

<强> BACKUP:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm:退出时移除容器
  • --volumes-from DATA:附加到DATA容器共享的卷
  • -v $(pwd):/backup:bind将当前目录挂载到容器中;将tar文件写入
  • busybox:一个简单的小图片 - 适合快速维护
  • tar cvf /backup/backup.tar /data:创建/ data目录中所有文件的未压缩tar文件

<强> RESTORE:

# create a new data container
$ sudo docker create -v /data --name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

答案 1 :(得分:15)

您可以将卷导出到tar并转移到另一台计算机。并在第二台机器上使用tar导入数据。这不依赖于卷的实现细节。

# you can list shared directories of the data container
docker inspect <data container> | grep "/vfs/dir/"

# you can export data container directory to tgz
docker run --cidfile=id.tmp --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgz

# clean up: remove exited container used for export and temporary file
docker rm `cat id.tmp` && rm -f id.tmp

答案 2 :(得分:13)

Docker docstop answer here扩展官方答案,您可以在.bashrc或.zshrc中使用以下别名

# backup files from a docker volume into /tmp/backup.tar.gz
function docker-volume-backup-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -czvf /backup/backup.tar.gz "${@:2}"
}
# restore files from /tmp/backup.tar.gz into a docker volume
function docker-volume-restore-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -xzvf /backup/backup.tar.gz "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie ls -lh "${@:2}"
}
# backup files from a docker volume into /tmp/backup.tar
function docker-volume-backup() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -cvf /backup/backup.tar "${@:2}"
}
# restore files from /tmp/backup.tar into a docker volume
function docker-volume-restore() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -xvf /backup/backup.tar "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox ls -lh "${@:2}"
}

请注意,备份会保存到/tmp,因此您可以移动保存在Docker主机之间的备份文件。

还有两对备份/恢复别名。一个使用压缩和debian:jessie和其他没有压缩但使用busybox。如果要备份的文件很大,请使用压缩。

答案 3 :(得分:2)

如果可以在机器之间建立 SSH 连接,这里是一个单行:

docker run --rm -v <SOURCE_DATA_VOLUME_NAME>:/from alpine ash -c "cd /from ; tar -cf - . " | ssh <TARGET_HOST> 'docker run --rm -i -v <TARGET_DATA_VOLUME_NAME>:/to alpine ash -c "cd /to ; tar -xpvf - " '

感谢 Guido Diepen 的 post

答案 4 :(得分:1)

我将在IBM添加另一个最近的工具,它实际上是为从一个容器主机到另一个容器主机的卷迁移而创建的。这是一个目前正在进行的项目。因此,您可能会在将来找到具有其他功能的其他版本。

开发

货物是为了将容器从一个主机迁移到另一个主机及其数据,同时将停机时间降至最低。 Cargo使用联合文件系统的数据联合功能,在源主机和目标主机上创建统一的数据视图(主要是根文件系统)。这允许Cargo在目标主机上几乎立即(在几毫秒内)启动容器,因为来自源根文件系统的数据被按需复制到目标主机(使用写时复制(COW)< / strong>分区)或懒惰地在后台(使用rsync)

重点是: - centralized 服务器处理迁移过程

这里给出了项目的链接:

https://github.com/nadgowdas/cargo

答案 5 :(得分:1)

如果您的计算机位于不同的VPC中,或者要从本地计算机复制到本地计算机(例如,对于我的情况),则可以使用我创建的dvsync。它基本上是ngrokrsync结合在SSH上,打包成两个小映像(均为约25MB)。首先,在要复制数据的机器上启动dvsync-server(您需要NGROK_AUTHTOKEN,可以从ngrok dashboard获得):

$ docker run --rm -e NGROK_AUTHTOKEN="$NGROK_AUTHTOKEN" \
  --mount source=MY_VOLUME,target=/data,readonly \
  quay.io/suda/dvsync-server

然后,您可以在要将文件复制到的机器上启动dvsync-client,并传递服务器显示的DVSYNC_TOKEN

docker run -e DVSYNC_TOKEN="$DVSYNC_TOKEN" \
  --mount source=MY_TARGET_VOLUME,target=/data \
  quay.io/suda/dvsync-client 

一旦复制完成,客户端将退出。这也适用于Docker CLI,Compose,Swarm和Kubernetes。

答案 6 :(得分:0)

改编自已接受的答案,但提供了更大的灵活性,您可以在 bash 管道中使用它:

#!/bin/bash

if [ $# != 2 ]; then
    echo Usage "$0": volume /path/of/the/dir/in/volume/to/backup
    exit 1
fi

if [ -t 1 ]; then
    echo The output of the cmd is binary data "(tar)", \
         and it should be redirected instead of printed to terminal
    exit 1
fi

volume="$1"
path="$2"

exec docker run --rm --mount type=volume,src="$volume",dst=/mnt/volume/ alpine tar cf - . -C /mnt/volume/"$path"

如果您想定期和增量备份卷,那么您可以使用以下脚本:

#!/bin/bash

if [ $# != 3 ]; then
    echo Usage "$0": volume /path/of/the/dir/in/volume/to/backup /path/to/put/backup
    exit 1
fi

volume="$1"
volume_path="$2"
path="$3"

if [[ "$path" =~ ^.*/$ ]]; then
    echo "The 3rd argument shouldn't end in '/', otherwise rsync would not behave as expected"
    exit 1
fi

container_name="docker-backup-rsync-service-$RANDOM"
docker run --rm --name="$container_name" -d -p 8738:873 \
    --mount type=volume,src="$volume",dst=/mnt/volume/ \
    nobodyxu/rsyncd

echo -e '\nStarting syncing...'

rsync --info=progress2,stats,symsafe -aHAX --delete \
    "rsync://localhost:8738/root/mnt/volume/$volume_path/"  "$path"
exit_status=$?

echo -e '\nStopping the rsyncd docker...'
docker stop -t 1 "$container_name"

exit $exit_status

它利用 rsync 的服务器和客户端功能直接同步卷和主机目录之间的目录。