我一直在使用这个Docker-image tutum / wordpress演示Wordpress网站。最近,我发现该映像将卷用于MySQL数据。
所以问题是这样的:如果我要备份和还原容器,则可以尝试提交映像,然后再删除该容器,并从提交的映像中创建一个新的容器。但是,如果我这样做,该卷将被删除,我的所有数据都将消失。
必须有一些简单的方法来备份我的容器及其卷数据,但是我在任何地方都找不到它。
我一直在使用这个Docker-image tutum / wordpress演示Wordpress网站。最近,我发现该映像将卷用于MySQL数据。
所以问题是这样的:如果我要备份和还原容器,则可以尝试提交映像,然后再删除该容器,并从提交的映像中创建一个新的容器。但是,如果我这样做,该卷将被删除,我的所有数据都将消失。
必须有一些简单的方法来备份我的容器及其卷数据,但是我在任何地方都找不到它。
Answers:
如果我想还原容器,则可以尝试提交映像,然后再删除该容器,并从提交的映像中创建一个新的容器。但是,如果我这样做,该卷将被删除,我所有的数据都将消失
正如docker用户指南所解释的那样,数据卷旨在将数据持久保存在容器文件系统之外。这也简化了多个容器之间的数据共享。
尽管Docker永远不会删除卷中的数据(除非您使用删除关联的容器docker rm -v
),但任何Docker容器未引用的卷都称为悬空卷。这些悬而未决的书卷很难摆脱,也很难获得。
这意味着,一旦删除了最后一个使用卷的容器,数据卷就会变得悬而未决,其内容也难以访问。
为了防止这些悬空的卷,诀窍是使用要保留的数据卷创建一个额外的docker容器;这样,至少总会有那个docker容器引用该卷。这样,您可以删除运行wordpress应用程序的docker容器,而不会失去对该数据卷内容的访问。
这种容器称为数据卷容器。
必须有一些简单的方法来备份我的容器以及卷数据,但是我在任何地方都找不到它。
要备份docker映像,请使用docker save命令,该命令将生成tar归档文件,以后可使用docker load命令创建一个新的docker映像。
您可以通过其他方式备份Docker容器
请注意,这些命令将仅备份docker容器分层文件系统。这不包括数据量。
要备份数据卷,您可以使用要备份的卷运行新容器,并执行tar命令以生成卷内容的存档,如docker用户指南中所述。
在您的特定情况下,数据量用于存储MySQL服务器的数据。因此,如果要导出该卷的tar归档文件,则需要首先停止MySQL服务器。为此,您必须停止wordpress容器。
另一种方法是使用mysqldump命令远程连接到MySQL服务器以生成数据库转储。但是,为了使它起作用,必须将您的MySQL服务器配置为接受远程连接,并且还具有允许远程连接的用户。您使用的wordpress docker映像可能不是这种情况。
Docker最近推出了Docker卷插件,该卷插件允许将卷的处理委托给供应商实现的插件。
该docker run
命令对该-v
选项具有新的行为。现在可以为它传递一个卷名。以这种方式创建的卷将被命名,并在以后易于引用,从而减轻了悬空卷的问题。
Docker引入了docker volume prune
轻松删除所有悬空卷的命令。
Data volumes are designed to persist data, independent of the container’s life cycle. Docker therefore never automatically delete volumes when you remove a container, nor will it “garbage collect” volumes that are no longer referenced by a container.
因此只有数据容器才是传统的容器
mysqldump
。只需将其装入容器中,将其转储,然后使用将其复制出去docker cp
。
data only container obsolete?
没有。仅数据容器为您提供了一个容器,docker exec data-container tar -czf snapshot.tgz /data
然后再docker cp data-container:snapshot.tgz ./snapshot.tgz
等等。如果您希望容器长期存在,则tail -f /dev/null
使用最少的资源使它的命令像永不退出一样。
更新2
原始单卷备份bash脚本:
#!/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
原始单卷还原bash脚本:
#!/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,它与备份和还原脚本位于同一目录中,容器之间的卷名相同。
更新
在我看来,从容器备份卷与从数据容器备份卷没有什么不同。
卷只不过是链接到容器的路径,因此过程是相同的。
我不知道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
结束更新
有一个很好的工具可以让您备份和还原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
或者您可以按照官方的方式:
unknown shorthand flag: 'r' in -rm.
应该--rm
吗?(Docker版本18.09.5,内部版本e8ff056)
如果只需要备份已装载的卷,则只需从Dockerhost复制文件夹。
注意:如果您使用Ubuntu,则Dockerhost是您的本地计算机。如果您使用的是Mac,则Dockerhost是您的虚拟机。
在Ubuntu上
您可以在此处找到所有带有卷的文件夹:/var/lib/docker/volumes/
这样就可以将它们复制并存档到任何位置。
在MAC上
这并不像在Ubuntu上那么容易。您需要从VM复制文件。
这是一个脚本,说明如何将具有卷的所有文件夹从虚拟机(运行Docker服务器的服务器)复制到本地计算机。我们假设您的docker-machine VM名为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
它将在当前目录中创建一个文件夹./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
/var/lib/docker/volumes
在Ubuntu下对该文件夹进行备份?
假设您的卷名是data_volume
。您可以使用以下命令在名为的docker映像之间备份和还原卷data_image
:
备份:
docker run --rm --mount source=data_volume,destination=/data alpine tar -c -f- data | docker run -i --name data_container alpine tar -x -f-
docker container commit data_container data_image
docker rm data_container
恢复:
docker run --rm data_image tar -c -f- data | docker run -i --rm --mount source=data_volume,destination=/data alpine tar -x -f-
我知道这已经很老了,但是我意识到没有一个有据可查的解决方案可以将数据容器(作为备份)推送到Docker Hub。我刚刚在https://dzone.com/articles/docker-backup-your-data-volumes-to-docker-hub上发布了有关此操作的简短示例。
以下是底线
码头工人教程建议您可以在本地备份和还原数据量。我们将使用此技术,再添加几行,以将该备份推送到docker hub中,以便将来轻松还原到所需的任何位置。因此,让我们开始吧。这些是要遵循的步骤:
从名为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
而已。
我很惊讶没有解决此问题的文档。我希望有人能对此有所帮助。我知道我花了一些时间思考这个问题。
如果您的项目使用docker-compose,则这是一种用于备份和还原卷的方法。
基本上你添加db-backup
和db-restore
服务,您的码头工人,compose.yml文件,并使其适应你的卷的名称。我的卷dbdata
在此示例中被命名。
version: "3"
services:
db:
image: percona:5.7
volumes:
- dbdata:/var/lib/mysql
db-backup:
image: alpine
tty: false
environment:
- TARGET=dbdata
volumes:
- ./backup:/backup
- dbdata:/volume
command: sh -c "tar -cjf /backup/$${TARGET}.tar.bz2 -C /volume ./"
db-restore:
image: alpine
environment:
- SOURCE=dbdata
volumes:
- ./backup:/backup
- dbdata:/volume
command: sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/$${SOURCE}.tar.bz2"
为确保数据一致性,请在备份或还原之前停止数据库容器
docker-compose stop db
备份到默认目的地(backup/dbdata.tar.bz2
):
docker-compose run --rm db-backup
或者,如果要指定备用目标名称,请执行以下操作:
docker-compose run --rm -e TARGET=mybackup db-backup
要从恢复backup/dbdata.tar.bz2
,请执行以下操作:
docker-compose run --rm db-restore
或使用以下方法从特定文件还原:
docker-compose run --rm -e SOURCE=mybackup db-restore
我从https://loomchild.net/2017/03/26/backup-restore-docker-named-volumes/改编了命令来创建这种方法。
如果只需要对存档的简单备份,则可以尝试使用我的小实用程序:https : //github.com/loomchild/volume-backup
例
备份:
docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup backup archive1
将归档卷命名some_volume
为/tmp/archive1.tar.bz2
归档文件
恢复:
docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup restore archive1
将擦除并恢复some_volume
从/tmp/archive1.tar.bz2
存档文件命名的卷。
更多信息:https : //medium.com/@loomchild/backup-restore-docker-named-volumes-350397b8e362
我创建了一个工具来协调和启动数据和mysql容器的备份,简称为docker-backup。docker hub上甚至有一个现成的映像。
它主要是编排,所以主要用Bash编写。它duplicity
用于实际的备份引擎。您目前可以备份到FTP(S)和Amazon S3。
配置非常简单:在YAML中编写一个配置文件,描述要备份的内容以及备份的位置,然后开始!
对于数据容器,它将自动挂载容器共享的卷以备份和处理它。对于mysql容器,它将链接它们并执行与您的容器捆绑在一起的mysqldump并处理结果。
我写它的原因是因为我使用的不是最新docker-engine版本的最新Docker-Cloud,而且因为我想通过不将任何备份过程包含在我的应用程序容器中来拥抱Docker方式。
如果要完整备份,则需要执行一些步骤:
请注意,仅将容器对映像进行Docker提交并不包括附加到容器的卷(请参阅:Docker commit documentation)。
“ 提交操作将不包含容器内安装的卷中包含的任何数据。 ”
如果您喜欢从命令行输入奥术运算符,那么您会喜欢这些手动容器备份技术。请记住,有一种更快捷,更有效的备份容器的方法,它同样有效。我在这里写了说明:https : //www.morpheusdata.com/blog/2017-03-02-how-to-create-a-docker-backup-with-morpheus
步骤1:将Docker主机 添加到任何云中正如Morpheus支持站点上的教程中所述,您可以在几秒钟内将Docker主机添加到您选择的云中。首先在主Morpheus导航栏上选择“基础结构”。选择基础结构窗口顶部的主机,然后单击右上角的“ +容器主机”按钮。
要通过Morpheus将Docker主机备份到云中,请导航至“基础架构”屏幕,然后打开“ +容器主机”菜单。
在菜单上选择一个容器主机类型,选择一个组,然后在五个字段中输入数据:名称,描述,可见性,选择云和输入标签(可选)。单击“下一步”,然后通过选择服务计划来配置主机选项。请注意,仅当您选择的计划启用了自定义选项时,“卷”,“内存”和“ CPU计数”字段才可见。
您可以在此处添加卷并为其设置大小,设置内存大小和CPU数量,然后选择一个网络。您还可以配置OS用户名和密码,域名和主机名,默认情况下,它们是您先前输入的容器名称。单击下一步,然后添加任何自动化工作流(可选)。最后,检查您的设置并单击完成以保存设置。
第2步:将Docker注册表集成添加到公共云或私有云中, Adam Hicks在另一份Morpheus教程中描述了与私有Docker Registry集成的简单性。(使用Morpheus使用公共Docker API通过Docker的公共集线器配置映像时,不需要进行额外的配置。)
在主导航栏的“管理”标签下选择“集成”,然后选择屏幕右侧的“ +新集成”按钮。在出现的“集成”窗口中,在“类型”下拉菜单中选择“ Docker Repository”,输入名称并添加私有注册表API端点。提供您正在使用的注册表的用户名和密码,然后单击“保存更改”按钮。
通过Morpheus的“ New Integration”对话框将Docker Registry与私有云集成。
要置备刚创建的集成,请在“创建实例”对话框的“类型”下选择“ Docker”,在“配置”选项卡下的“ Docker注册表”下拉菜单中选择注册表,然后像配置任何Docker容器一样继续置备。
步骤3:管理备份 添加Docker主机并集成注册表后,将为您配置的每个实例自动配置并执行备份。Morpheus支持提供了有关查看备份,创建实例备份以及创建服务器备份的说明。
如果您的案例像我的那么简单,则可以执行以下操作:
ADD folder destination
例如,假设您拥有主目录中卷中的数据(例如在处)/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 .
其余的东西是从基础映像继承的。您现在可以将该映像推送到Docker云,您的用户将直接在其容器上使用数据
docker cp
。
问题:您要备份包含数据卷的映像容器,但此选项并非开箱即用,简单而直接的方法是复制卷路径并备份docker映像,然后重新加载并链接它两者一起。但是此解决方案似乎笨拙,并且不可持续且不可维护-您将需要创建一个cron作业,以使每次工作都顺畅进行。
解决方案:使用dockup -Docker映像备份Docker容器卷并将其上传到s3(Docker + Backup = dockup)。对接将使用您的AWS凭证创建一个新的存储桶,其名称与环境变量相同,获取已配置的卷,并将其压缩,压缩,加盖时间戳记并上传到S3存储桶。
步骤:
docker-compose.yml
并将其附加env.txt
配置文件,数据应上传到专用的安全s3存储桶,并准备在执行DRP时重新加载。为了验证哪个卷路径配置运行docker inspect <service-name>
并且找到卷:“卷”:{“ / etc / service-example”:{},“ / service-example”:{}},
编辑配置文件的内容env.txt
,并将其放置在项目路径中:
AWS_ACCESS_KEY_ID=<key_here>
AWS_SECRET_ACCESS_KEY=<secret_here>
AWS_DEFAULT_REGION=us-east-1
BACKUP_NAME=service-backup
PATHS_TO_BACKUP=/etc/service-example /service-example
S3_BUCKET_NAME=docker-backups.example.com
RESTORE=false
运行停靠容器
$ docker run --rm \ --env-file env.txt \ --volumes-from <service-name> \ --name dockup tutum/dockup:latest
这是一种卷文件夹备份方式。
如果您具有以下docker Registry,则此方法非常有用。
这使用docker注册表轻松移动zip文件。
#volume folder backup script. !/bin/bash
#common bash variables. set these variable before running scripts
REPO=harbor.otcysk.org:20443/levee
VFOLDER=/data/mariadb
TAG=mariadb1
#zip local folder for volume files
tar cvfz volume-backup.tar.gz $VFOLDER
#copy the zip file to volume-backup container.
#zip file must be in current folder.
docker run -d -v $(pwd):/temp --name volume-backup ubuntu \
bash -c "cd / && cp /temp/volume-backup.tar.gz ."
#commit for pushing into REPO
docker commit volume-backup $REPO/volume-backup:$TAG
#check gz files in this container
#docker run --rm -it --entrypoint bash --name check-volume-backup \
$REPO/volume-backup:$TAG
#push into REPO
docker push $REPO/volume-backup:$TAG
在另一台服务器上
#pull the image in another server
docker pull $REPO/volume-backup:$TAG
#restore files in another server filesystem
docker run --rm -v $VFOLDER:$VFOLDER --name volume-backup $REPO/volume-backup:$TAG \
bash -c "cd / && tar xvfz volume-backup.tar.gz"
运行使用该卷文件夹的映像。
您可以轻松制作同时包含一个运行图像和一个体积zip文件的图像。
但是由于种种原因(图像大小,输入命令等),我不建议这样做。