克隆/快照的Docker容器包括他们的数据的脚本?

我想克隆包含所有数据的dockerized应用程序,在这个例子中使用三个容器:1)一个web应用程序容器,如CMS,2)数据库容器和3)数据卷容器(使用docker卷) 。

使用docker-compose,我可以轻松地创build这些容器的相同实例,只需要初始数据。 但是,如果我想用克隆KVM容器的相似方式克隆同一台服务器上的一组正在运行的容器(包括其所有累积的数据),那又如何呢? 使用KVM,我会暂停或closures虚拟机,克隆一些类似virt-clone的东西,然后启动克隆的guest虚拟机,它具有与原始数据相同的数据。

一个用例是在进行重大更改之前或者在安装新版本的插件之前创build正在运行的开发Web服务器的克隆/快照。

对于Docker来说,这看起来并不那么简单,因为数据不会自动与容器一起复制。 理想情况下,我想做一些像docker-compose clone这样简单的事情,并最终得到与第一组相同的第二组容器,包括所有的数据。 Docker和Docker-compose都不提供克隆命令(从版本1.8开始),因此我需要考虑各种方法,如备份和恢复数据/数据库或使用Flocker等第三方工具。

与此相关的是如何做一个类似于dockerized应用程序的KVM快照的问题,能够轻松地返回到以前的状态。 优选地,克隆,快照和恢复应该是可能的,并具有最小的停机时间。

什么是首选的Docker完成这些事情的方式?

编辑:基于第一个答案,我会让我的问题更具体一点,以便有希望到达编程步骤,以便能够使用bash或python脚本来执行诸如docker-compose-clonedocker-compose-snapshot操作。 克隆docker卷的内容似乎是关键,因为每次我在相同的yaml文件上运行docker-compose时,容器本身都基本被克隆。

通常我的完整克隆脚本将需要

  1. 复制包含docker-compose文件的目录
  2. 暂时停止集装箱
  3. 创build(但不一定运行)第二组容器
  4. 确定要复制的数据卷
  5. 备份这些数据卷
  6. 将数据卷还原到克隆的数据容器中
  7. 启动第二组容器

    • 这是否是正确的方式去做,我应该如何执行这个? 我特别不确定如何在脚本中执行步骤4( 确定要复制的数据卷 ),因为命令docker volume ls只能在Docker 1.9中使用。

    • 我怎样才能使用这种方法做类似于KVM快照? (可能使用ZFS中的COW文件系统function,这是我的Docker安装已经使用的function)。

docker工人可以保留所有的状态。 只要重新使用相同的卷(无论是从主机还是数据卷容器),都可以从映像重新创build容器。

我不知道从数据卷容器中导出卷的简单方法。 我知道docker 1.9版本将会添加一些顶级apis来与卷进行交互,但是我不确定导出是否可以立即使用。

如果您使用的是主机卷,则可以从Dockerpipe理外部状态。

目前,我正在使用以下脚本来克隆一个dockerized CMS web应用程序Concrete5.7,基于上面概述的方法。 它使用docker-compose创build第二组相同的容器,然后仅备份数据卷中的数据,并将其恢复到第二组中的数据容器。

这可以作为开发更广义的脚本的一个例子:

 #!/bin/bash set -e # This script will clone a set of containers including all its data # the docker-compose.yml is in the PROJ_ORIG directory # - do not use capital letters or underscores for clone suffix, # as docker-compose will modify or remove these PROJ_ORIG="c5app" PROJ_CLONE="${PROJ_ORIG}003" # 1. duplicate the directory containing the docker-compose file cd /opt/docker/compose/concrete5.7/ cp -Rv ${PROJ_ORIG}/ ${PROJ_CLONE}/ # 2. temporarily stop the containers cd ${PROJ_ORIG} docker-compose stop # 3. create, run and stop the second set of containers # (docker-compose does not have a create command) cd ../${PROJ_CLONE} docker-compose up -d docker-compose stop # 4. determine the data-volumes to be duplicated # a) examine which containers are designated data containers # b) then use docker inspect to determine the relevant directories # c) store destination directories & process them for backup and clone # # In this appliaction we use two data containers # (here we used DATA as part of the name): # $ docker-compose ps | grep DATA # c5app_DB-DATA_1 /true Exit 0 # c5app_WEB-DATA_1 /true Exit 0 # # $ docker inspect ${PROJ_ORIG}_WEB-DATA_1 | grep Destination # "Destination": "/var/www/html", # "Destination": "/etc/apache2", # # $ docker inspect ${PROJ_ORIG}_DB-DATA_1 | grep Destination # "Destination": "/var/lib/mysql", # these still need to be determined manually from examining # the docker-compose.yml or using the commands in 4. DATA_SUF1="_WEB-DATA_1" VOL1_1="/etc/apache2" VOL1_2="/var/www/html" DATA_SUF2="_DB-DATA_1" VOL2_1="/var/lib/mysql" # 5. Backup Data: docker run --rm --volumes-from ${PROJ_ORIG}${DATA_SUF1} -v ${PWD}:/clone debian tar -cpzf /clone/clone${DATA_SUF1}.tar.gz ${VOL1_1} ${VOL1_2} docker run --rm --volumes-from ${PROJ_ORIG}${DATA_SUF2} -v ${PWD}:/clone debian tar -cpzf /clone/clone${DATA_SUF2}.tar.gz ${VOL2_1} # 6. Clone Data: # existing files in volumes need to be deleted before restoring, # as the installation may have created additional files during initial run, # which do not get overwritten during restore docker run --rm --volumes-from ${PROJ_CLONE}${DATA_SUF1} -v ${PWD}:/clone debian bash -c "rm -rf ${VOL1_1}/* ${VOL1_2}/* && tar -xpf /clone/clone${DATA_SUF1}.tar.gz" docker run --rm --volumes-from ${PROJ_CLONE}${DATA_SUF2} -v ${PWD}:/clone debian bash -c "rm -rf ${VOL2_1}/* && tar -xpf /clone/clone${DATA_SUF2}.tar.gz" # 7. Start Cloned Containers: docker-compose start # 8. Remove tar archives rm -v clone${DATA_SUF1}.tar.gz rm -v clone${DATA_SUF2}.tar.gz 

它已被testing和工作,但仍有以下限制:

  • 要复制的数据量需要手动确定
  • 脚本需要修改,这取决于数据容器和数据卷的数量
  • 没有快照/恢复function

我欢迎任何有关改进的build议(特别是第4步)。 或者,如果有人想出一个不同的,更好的方法,我会接受,而不是作为一个答案。

本例中使用的应用程序和docker-compose.yml文件可以在这里find。

在Windows上,有一个Docker的开源容器项目的端口可以从Windocks获得,它可以满足你的需求。 有两个选项:

  1. 通过在构build映像时指定的添加数据库命令将较小大小的数据库复制到容器中。 之后,每个从中build立的容器自动接收数据库。
  2. 对于大型数据库,有一个克隆function。 数据库在容器的创build过程中被克隆,即使对于TB级别的DB,克隆也是在几秒钟内完成的。 删除容器也会自动删除克隆。 现在它只能用于SQL Server。

    有关数据库添加和克隆的更多详细信息,请参阅此处 。

    Interesting Posts