克隆/快照Docker容器及其数据的脚本?

7
我希望复制包括所有数据的docker化应用程序,该示例使用三个容器:1)Web应用程序容器(例如CMS),2)数据库容器和3)数据卷容器(使用docker卷)。
通过docker-compose,我可以轻松地创建具有初始数据的相同实例的这些容器。但是,如果我想要在同一服务器上克隆一组正在运行的容器,并包括所有累积的数据,就像我克隆KVM容器一样,该怎么办?对于KVM,我会挂起或关闭虚拟机,使用类似virt-clone的工具进行克隆,然后启动克隆的客户机,它具有与原始客户机相同的所有数据。
一个用例是在进行重大更改或安装新版本插件之前,创建正在运行的开发Web服务器的克隆/快照。
使用Docker,这似乎不那么简单,因为数据不会自动与其容器一起复制。理想情况下,我想做一些简单的事情,例如docker-compose clone,最终得到第二组容器,与第一组完全相同,包括所有它们的数据。 Docker和docker-compose都没有提供克隆命令(截至1.8版本),因此我需要考虑各种方法,例如备份和还原数据/数据库或使用第三方工具,例如Flocker。
与此相关的问题是如何执行类似于docker化应用程序的KVM快照,并具有轻松返回先前状态的功能。最好的克隆、快照和还原应该可以在最少的停机时间内完成。
用什么方法来实现这些操作会更好呢?
  1. 复制包含docker-compose文件的目录
  2. 暂停容器
  3. 创建第二组容器(但不一定要运行)
  4. 确定要复制的数据卷
  5. 备份这些数据卷
  6. 将数据卷还原到克隆的数据容器中
  7. 启动第二组容器

    • 这是否是正确的做法,我该如何实现?我对如何在脚本中执行步骤4 (确定要复制的数据卷) 不太确定,因为命令 docker volume ls 只在Docker 1.9中可用。

    • 如何使用此方法类似于KVM快照?(可能使用ZFS的COW文件系统功能,我的Docker安装已经在使用)。

3个回答

0

使用Docker,您可以将所有状态保存在卷中。只要容器重用相同的卷(来自主机或数据卷容器),就可以从镜像重新创建容器。

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

如果您正在使用主机卷,则可以从Docker外部管理状态。


是的,正如问题中所示,我已经在使用数据卷容器(现在我已经将措辞表述得更清晰了)。我不想使用主机容器,因为它们不够便携。据我所知,Docker 1.9 将添加 docker volume create, inspect, ls, rm commands,但这些命令并不能完全提供克隆所需的功能。您有没有关于如何在脚本中确定要复制的数据卷的建议? - ChrisW

0
在Windows上,有一个来自Windocks的docker开源容器项目的端口可用,可以满足您的需求。有两个选项:
1. 通过指定构建镜像时的Add database命令,将较小的数据库复制到容器中。之后从该镜像构建的每个容器都会自动接收数据库。
2. 对于大型数据库,有一个克隆功能。在创建容器时克隆数据库,即使是大小为TB级别的数据库,也可以在几秒钟内完成克隆。删除容器也会自动删除克隆。目前仅适用于SQL Server。
有关添加和克隆数据库的更多详细信息,请参见此处

0

目前,我正在使用以下脚本来克隆基于Docker的CMS Web应用程序Concrete5.7,该脚本基于上述方法。它使用docker-compose创建了一组完全相同的第二个容器集,然后仅备份数据卷中的数据,并将其还原到第二个容器集中的数据容器中。

这可以作为开发更通用脚本的示例:

#!/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

已经测试并且可以工作,但仍然有以下限制:

  • 需要手动确定要复制的数据卷
  • 脚本需要根据数据容器和数据卷的数量进行修改
  • 没有快照/恢复功能

我欢迎任何改进建议(特别是第四步)。或者,如果有人提出了不同、更好的方法,我也会接受那个作为答案。

在这个例子中使用的应用程序以及docker-compose.yml文件可以在这里找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接