如何备份一个Docker容器及其数据卷?

我一直在使用这个Docker-image tutum / wordpress来演示一个WordPress的网站。 最近我发现图像使用了MySQL数据的卷。

所以问题是这样的:如果我想备份和恢复容器,我可以尝试提交一个图像,然后删除容器,并从提交的图像创build一个新的容器。 但是,如果我这样做,音量被删除,我的所有数据都消失了。

必须有一些简单的方法来备份我的容器加上它的卷数据,但我找不到任何地方。

如果我想恢复容器,我可以尝试提交一个图像,然后删除容器,并从提交的图像创build一个新的容器。 但是,如果我这样做,音量被删除,我的所有数据都消失了

正如Docker用户指南解释的那样, 数据卷是为了在容器文件系统之外保存数据。 这也便于在多个容器之间共享数据。

尽pipeDocker永远不会删除卷中的数据(除非使用docker rm -v删除关联的容器),任何docker容器都没有引用的称为dangling卷 。 那些悬而未决的卷很难摆脱和难以访问。

这意味着一旦使用卷的最后一个容器被删除,数据量就会变得悬而未决,并且其内容难以获取。

为了防止这些悬空卷,诀窍是使用您想保留的数据量创build一个额外的docker容器; 所以总会有至less那个docker容器引用这个卷。 通过这种方式,您可以删除运行wordpress应用程序的Docker容器,而不会轻易访问该数据卷内容。

这种容器被称为数据容器 。

必须有一些简单的方法来备份我的容器和卷数据,但是我无法在任何地方find它。

备份docker图像

要备份泊坞窗图像,请使用docker save命令,该命令将生成一个tar存档,稍后可以使用docker load命令创build新的docker图像。

备用docker集装箱

您可以通过不同的方式备份docker集装箱

  • 通过使用docker commit命令提交基于docker container当前状态的新docker镜像
  • 通过使用docker export命令将Docker容器文件系统导出为tar归档文件。 稍后可以使用docker import命令从该tar归档文件创build一个新的docker映像。

请注意,这些命令将仅备份docker容器分层文件系统。 这不包括数据量

备份docker数据卷

要备份数据卷,可以使用要备份的卷运行新的容器,然后执行tar命令,以按照docker用户指南中的描述生成卷内容的存档。

在您的具体情况下,数据卷用于存储MySQL服务器的数据。 所以如果你想为这个卷导出一个tar档案,你需要先停止MySQL服务器。 要做到这一点,你将不得不停止wordpress容器。

备份MySQL数据

另一种方法是使用mysqldump命令远程连接到MySQL服务器以产生数据库转储。 但是为了达到这个目的,你的MySQL服务器必须被configuration为接受远程连接,并且有一个允许远程连接的用户。 这可能不是你正在使用的wordpress docker镜像的情况。


编辑

Docker最近推出了Docker卷插件 ,允许将卷的处理委托给供应商实现的插件。

docker run命令对-v选项有一个新的行为。 现在可以传递一个卷名称 。 以这种方式创build的卷被命名并且稍后很容易引用,从而缓解了悬挂卷的问题。

编辑2

Docker引入了docker volume prune命令来轻松删除所有悬挂的卷。

更新2

原始单个卷备份脚本:

 #!/bin/bash # This script allows you to backup a single volume from a container # Data in given volume is saved in the current directory in a tar archive. CONTAINER_NAME=$1 VOLUME_NAME=$2 usage() { echo "Usage: $0 [container name] [volume name]" exit 1 } if [ -z $CONTAINER_NAME ] then echo "Error: missing container name parameter." usage fi if [ -z $VOLUME_NAME ] then echo "Error: missing volume name parameter." usage fi sudo docker run -rm --volumes-from $CONTAINER_NAME -v $(pwd):/backup busybox tar cvf /backup/backup.tar $VOLUME_NAME 

原始单卷还原脚本:

 #!/bin/bash # This script allows you to restore a single volume from a container # Data in restored in volume with same backupped path NEW_CONTAINER_NAME=$1 usage() { echo "Usage: $0 [container name]" exit 1 } if [ -z $NEW_CONTAINER_NAME ] then echo "Error: missing container name parameter." usage fi sudo docker run -rm --volumes-from $NEW_CONTAINER_NAME -v $(pwd):/backup busybox tar xvf /backup/backup.tar 

用法可以是这样的:

 $ volume_backup.sh old_container /srv/www $ sudo docker stop old_container && sudo docker rm old_container $ sudo docker run -d --name new_container myrepo/new_container $ volume_restore.sh new_container 

假设:备份文件名为backup.tar,与备份和还原脚本位于同一目录,容器名称相同。

UPDATE

在我看来,从容器回退容量与从数据容器回退容量没有区别。

卷是没有别的path链接到一个容器,所以过程是一样的。

我不知道docker-backup是否适用于同一个容器卷,但可以使用:

 sudo docker run -rm --volumes-from yourcontainer -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data 

和:

 sudo docker run -rm --volumes-from yournewcontainer -v $(pwd):/backup busybox tar xvf /backup/backup.tar 

END UPDATE

有这个好工具可以让你备份和恢复docker容器容器:

https://github.com/discordianfish/docker-backup

如果你有一个容器链接到这样的容器卷:

 $ docker run --volumes-from=my-data-container --name my-server ... 

你可以像这样备份所有的卷:

 $ docker-backup store my-server-backup.tar my-server 

并像这样恢复:

 $ docker-backup restore my-server-backup.tar 

或者你可以按照官方的方式:

如何将只有数据的卷从一台主机移植到另一台主机?

如果您只需要备份已安装的卷,则只需从Dockerhost复制文件夹即可

注意:如果你在Ubuntu上Dockerhost是你的本地机器。 如果你在Mac上Dockerhost是你的虚拟机。

在Ubuntu上

你可以在这里find卷的所有文件夹: /var/lib/docker/volumes/这样你就可以复制它们并存档到你想要的地方。

在MAC上

这不像在Ubuntu上那么容易。 您需要从VM复制文件。

这里是一个脚本,介绍如何将虚拟机(Docker服务器运行的地方)卷的所有文件夹复制到本地机器上。 我们假设你的docker-machine虚拟机名为default

 docker-machine ssh default sudo cp -v -R /var/lib/docker/volumes/ /home/docker/volumes docker-machine ssh default sudo chmod -R 777 /home/docker/volumes docker-machine scp -R default:/home/docker/volumes ./backup_volumes docker-machine ssh default sudo rm -r /home/docker/volumes 

它将在当前目录中创build一个文件夹./backup_volumes并将所有卷复制到此文件夹。

以下是如何将所有保存的卷从本地目录( ./backup_volumes )复制到Dockerhost机器的脚本

 docker-machine scp -r ./backup_volumes default:/home/docker docker-machine ssh default sudo mv -f /home/docker/backup_volumes /home/docker/volumes docker-machine ssh default sudo chmod -R 777 /home/docker/volumes docker-machine ssh default sudo cp -v -R /home/docker/volumes /var/lib/docker/ docker-machine ssh default sudo rm -r /home/docker/volumes 

现在你可以检查它是否工作:

 docker volume ls 

我知道这是旧的,但我意识到,没有一个有据可查的解决scheme推动数据容器(作为备份)docker集线器。 我刚刚发布了一个简短的例子,在https://dzone.com/articles/docker-backup-your-data-volumes-to-docker-hub

以下是底线

docker教程build议您可以在本地备份和恢复数据卷。 我们将使用这种技术,添加更多的线路将这个备份推送到docker集线器,以便将来可以恢复到我们所需的任何位置。 所以,让我们开始吧。 这些步骤如下:

从名为data-container-to-backup的数据容器备份数据卷

 docker run --rm --volumes-from data-container-backup --name tmp-backup -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /folderToBackup 

将这个tar文件扩展成一个新的容器,这样我们就可以把它作为它的图像的一部分提交

 docker run -d -v $(pwd):/backup --name data-backup ubuntu /bin/sh -c "cd / && tar xvf /backup/backup.tar" 

使用所需的标签提交并推送图像($ VERSION)

 docker commit data-backup repo/data-backup:$VERSION docker push repo/data-backup:$VERSION 

最后,让我们清理一下

 docker rm data-backup docker rmi $(docker images -f "dangling=true" -q) 

现在我们在我们的仓库中有一个名为data-backup的映像,它只是一个带有备份文件和文件夹的文件系统。 为了使用这个图像(又名从备份恢复),我们做到以下几点:

使用数据备份映像运行数据容器

 run -v /folderToBackup --entrypoint "bin/sh" --name data-container repo/data-backup:${VERSION} 

用数据结合体的卷运行你的whatEver映像

 docker run --volumes-from=data-container repo/whatEver 

而已。

我很惊讶这项工作没有文件。 我希望有人觉得这有帮助。 我知道我花了一段时间来思考这个问题。

以下命令将在装有所有命名数据卷的容器中运行tar,并将输出redirect到一个文件中:

 docker run --rm `docker volume list -q | egrep -v '^.{64}$' | awk '{print "-v " $1 ":/mnt/" $1}'` alpine tar -C /mnt -cj . > data-volumes.tar.bz2 

确保在出现问题时testing结果存档:

 tar -tjf data-volumes.tar.bz2 

我创build了一个工具来编排和启动数据和mysql容器的备份 ,简单地称为docker-backup 。 docker集线器上甚至有一个现成的图像 。

它主要是用Bash编写的,因为它主要是编排。 它使用duplicity的实际备份引擎。 您目前可以备份到FTP(S)和Amazon S3。

configuration非常简单:在YAML中写一个configuration文件来描述备份和在哪里,在这里你去!

对于数据容器,它会自动安装容器共享的卷以进行备份和处理。 对于mysql容器,它将它们链接起来并执行与你的容器捆绑在一起的mysqldump并处理结果。

我写了它,因为我使用了Docker-Cloud,它不是最新的Docker-Engine版本,因为我想通过在应用程序容器中不包含任何备份过程来接受Docker的方式。

如果你喜欢从命令行input神秘的操作符,你会爱上这些手动的容器备份技术。 请记住,备份容器的速度更快,效率更高。 我在这里写了说明: https : //www.morpheusdata.com/blog/2017-03-02-how-to-create-a-docker-backup-with-morpheus

第1步:将Docker主机添加到任何云如Morpheus支持站点上的教程所述,您可以在几秒钟内将Docker主机添加到您select的云中。 首先在主Morpheus导航栏上selectInfrastructure。 在“基础结构”窗口顶部select主机,然后单击右上angular的“+容器主机”button。

要通过Morpheus将Docker主机备份到云,导航到基础架构屏幕并打开“+容器主机”菜单。

在菜单上select容器主机types,select一个组,然后在五个字段中input数据:名称,描述,可见性,select云和input标签(可选)。 单击下一步,然后通过select服务计划来configuration主机选项。 请注意,仅当您select的计划启用自定义选项时,“卷”,“内存”和“CPU计数”字段才可见。

这里是添加和调整卷的大小,设置内存大小和CPU数量,并select一个networking。 您还可以configuration操作系统用户名和密码,域名和主机名,默认情况下是您之前input的容器名称。 单击下一步,然后添加任何自动化工作stream(可选)。最后,检查您的设置,然后单击完成保存它们。

第2步:将Dockerregistry集成添加到公有云或私有云 Adam Hicks在另一篇Morpheus教程中介绍了与私有Docker Registry集成是多么简单。 (不需要添加configuration来使用Morpheus使用公共Docker API使用Docker的公共中心configuration图像。)

在主导航栏的Admin选项卡下selectIntegrations,然后select屏幕右侧的“+ New Integration”button。 在出现的Integration窗口中,在Type下拉菜单中selectDocker Repository,input名称并添加私有registryAPI端点。 为正在使用的registry提供用户名和密码,然后单击保存更改button。

通过Morpheus“新build集成”对话框集成Docker Registry与私有云。

要设置刚刚创build的集成,请在“创build实例”对话框的“types”下select“Docker”,在“configuration”选项卡下的“Docker Registry”下拉菜单中selectregistry,然后像任何Docker容器一样继续设置。

第3步:pipe理备份添加Docker主机并集成registry后,将为您configuration的每个实例自动configuration和执行备份。 Morpheus支持提供查看备份,创build实例备份和创build服务器备份的说明。

如果你有一个像我一样简单的情况,你可以做到以下几点:

  1. 创build一个扩展容器的基础镜像的Dockerfile
  2. 我假设你的卷映射到你的文件系统,所以你可以添加这些文件/文件夹到您的图像使用ADD folder destination
  3. 完成!

例如,假设您拥有主目录中卷的数据,例如/home/mydata ,则可以运行以下命令:

 DOCKERFILE=/home/dockerfile.bk-myimage docker build --rm --no-cache -t $IMAGENAME:$TAG -f $DOCKERFILE /home/pirate 

你的DOCKERFILE指向这样一个文件:

 FROM user/myimage MAINTAINER Danielo Rodríguez Rivero <example@gmail.com> WORKDIR /opt/data ADD mydata . 

剩下的东西是从基本图像inheritance的。 现在,您可以将该映像推送到Docker云中,并且您的用户将直接在其容器上提供数据

如果你只需要一个简单的备份到档案,你可以尝试我的小工具: https : //github.com/loomchild/volume-backup

备份:

 docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup backup archive1 

会将名为some_volume/tmp/archive.tar.bz2归档到/tmp/archive.tar.bz2归档文件

恢复:

 docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup restore archive1 

将从/tmp/archive.tar.bz2归档文件中擦除和恢复名为some_volume卷。

更多信息: http : //loomchild.net/2017/03/26/backup-restore-docker-named-volumes/