备份和还原数据

尽管部署在Deis上的应用因遵循12因子的方法学而无状态,Deis却需要在存储(Store)部件维护着平台的状态。

存储部件运行着Ceph、数据库组件(Database)、注册表组件(Registry)、控制器组件(Controller)和日志组件(Logger)都需要把存储组件(Store)当做一个数据存储来使用。数据库组件和注册表组件使用存储网关(store-gateway),控制器和日志组件使用存储卷(store-volume)。这些组件有了存储组件作为后备,可以自由的在集群上移动,因为他们的状态有存储组件做后备。

假如一个主机失效然后重新加入集群,根据配置存储组件仍然会以降级的状态运作,并且会自动的恢复。Ceph的数据完全丢失只可能发生在所有的存储容器被移除的情形下。然而,备份Ceph相当直接简单,我们建议在升级Deis之前进行备份。

存放在Ceph中的数据可以通过两个地方访问到:在CoreOS文件系统的/var/lib/deis/store下,和存储网关组件(store-gateway)。备份此份数据也比较简单,我们可以把该文件系统的数据做一个tar包,然后使用任何S3兼容的blob存储工具将存储网关所有的文件下载下来。

设置

Deis的存储网关组件对外暴露了一个S3兼容的API,因而我们可以使用如s3cmd来操作存储(object store)服务。首先请安装我们的fork的s3cmd,里面包含了支持ceph的补丁。

  1. $ pip install git+https://github.com/deis/s3cmd

我们需要生成了的访问key(access key)和秘钥key(secret kejy)来使用存储网关。我们可以通过在集群上的任意一台主机,或者通过在设置了DEISCTL_TUNNEL的远程主机上使用deisctl来获取访问key和秘钥key。

  1. $ deisctl config store get gateway/accessKey
  2. $ deisctl config store get gateway/secretKey

回到本地主机,运行s3cmd —configure并且输入你的访问key和秘钥key。其他设置都可以不修改使用默认值。如果配置脚本提示你测试下身份验证,略过此步骤 - 它会去Amazon S3做验证然后肯定会返回失败。

你需要更改一些其他的设置。首先,编辑~/.s3cfg文件然后修改host_basehost_bucket的值,使它们与deis-store.一致。比如,在我本地的Vagrant主机上,我做了如下修改:

  1. host_base = deis-store.local3.deisapp.com
  2. host_bucket = deis-store.local3.deisapp.com/%(bucket)

你还需要开启use_path_mode模式:

  1. use_path_mode = True

现在我们可以使用s3cmd命令通过存储网关做备份和还原的操作了。

备份

数据库组件和注册表数据的备份

存储网关组件存储数据库的备份,并且会被用来存储注册表的数据。在我们本地的机器上,我们可以使用s3cmd sync来把数据对象拷贝到本地:

  1. $ s3cmd sync s3://db_wal .
  2. $ s3cmd sync s3://registry .

日志数据

存储卷(store-volumn)服务挂载了一个文件系统,控制器组件和日志组件用它来存储和获取应用和组件的日志。

由于这只是一个POSIX的文件系统,你可以方便的将此目录打包然后rsync到本地主机上:

  1. $ ssh core@<hostname> 'cd /var/lib/deis/store && sudo tar cpzf ~/store_file_backup.tar.gz .'
  2. tar: /var/lib/deis/store/logs/deis-registry.log: file changed as we read it
  3. $ rsync -avhe ssh core@<hostname>:~/store_file_backup.tar.gz .

注意如果你使用的是Vagrant,你需要指定SSH的端口:

  1. $ rsync -avhe 'ssh -p 2222' core@127.0.0.1:~/store_file_backup.tar.gz .

留意此警告 - 在一个运行中的集群上,日志文件被不断地改写,因而我们仅仅是备份着一段时间的数据。

数据库数据

尽管备份Ceph的数据已经足够(因为数据库组件将备份和WAL日志放入存储组件中),我们可以使用pg_dumpall来备份PostgreSQL数据的数据,这样我们就得到了数据库的一个文本dump。

我们可以通过deisctl list找到该主机然后在该主机上:

  1. core@deis-1 ~ $ docker exec deis-database sudo -u postgres pg_dumpall > dump_all.sql
  2. core@deis-1 ~ $ docker cp deis-database:/app/dump_all.sql .

还原

注意:
还原仅仅在部署一个新的集群的时候才必要。大多数的用户只需要使用平常的即时升级(in-place upgrade)的工作流即可,不需要进行还原操作。

我们需要在Deis其余的组件启动和初始化之前进行数据的还原。因此,我们需要安装整个平台,但是仅仅启动存储组件:

  1. $ deisctl install platform
  2. $ deisctl start store-monitor
  3. $ deisctl start store-daemon
  4. $ deisctl start store-metadata
  5. $ deisctl start store-gateway
  6. $ deisctl start store-volume

我们也需要启动路由组件这样我们才能访问到存储网关:

  1. $ deisctl start router@1

路由组件上默认最大的消息体的大小对于支持数据较大的像存储网关的上传还是太小,因而我们需要增大此值:

  1. $ deisctl config router set bodySize=100m

新的集群应该已经生成了新的访问key和秘钥key,因此我们需要再次获取:

  1. $ deisctl config store get gateway/accessKey
  2. $ deisctl config store get gateway/secretKey

编辑~/.s3cfg然后更新key。
现在我们可以还原数据了!

数据库还原和注册表数据

因为数据库和注册表组件都还没有启动,我们要还原的目标bucket还不存在。因此我们需要手动创建这些bucket:

  1. $ s3cmd mb s3://db_wal
  2. $ s3cmd mb s3://registry

现在我们可以开始还原数据了:

  1. $ s3cmd sync basebackups_005 s3://db_wal
  2. $ s3cmd sync wal_005 s3://db_wal
  3. $ s3cmd sync registry s3://registry

日志数据

一旦我们将tarball拷贝回一个CoreOS的主机上,我们可以解包:

  1. $ rsync -avhe ssh store_file_backup.tar.gz core@<hostname>:~/store_file_backup.tar.gz
  2. $ ssh core@<hostname> 'cd /var/lib/deis/store && sudo tar -xzpf ~/store_file_backup.tar.gz --same-owner'

注意如果你使用的Vagrant你需要指定SSH的端口:

  1. $ rsync -avhe 'ssh -p 2222' store_file_backup.tar.gz core@127.0.0.1:~/store_file_backup.tar.gz

收尾

现在数据已经还原好了,集群剩下的组件在执行deisctl start platform后应该能正常的启动。

最后的任务就是告诉控制器组件重写用户的Key,应用的数据,和domains域到etcd。登陆进入运行着deis控制器组件的主机然后运行如下命令。注意在export命令上使用的IP地址应该符合运行此容器的宿主主机的IP。

  1. $ nse deis-controller
  2. $ cd /app
  3. $ export ETCD=172.17.8.100:4001
  4. ./manage.py shell <<EOF
  5. from api.models import *
  6. [k.save() for k in Key.objects.all()]
  7. [a.save() for a in App.objects.all()]
  8. [d.save() for d in Domain.objects.all()]
  9. EOF
  10. $ exit

注意:

数据库组件会监控运行应用容器。由于这是一个全新的集群,我们建议用deis scale =0然后deis scale回到你想要一个应用的容器的数量。这可以保证数据库组件对集群有一个确切的了解。