On this page... (hide)
- 1. 概述
- 2. Duplicity简介
- 3. 安装及配置
- 4. 安全性探讨
- 5. 问题与技巧
- 5.1 关于S3访问工具
- 5.2 关于403 Forbidden错误
- 5.3 关于Invalid SSH password错误
- 5.4 一次备份多个目录的方法
- 5.5 备份任务的自动执行
- 5.6 备份MySQL
- 5.7 “GnuPG exited non-zero”错误
- 6. 其他类似解决方案
1. 概述
amazon web services中的Amazon Simple Storage Service (Amazon S3)是一个很好的在线文件存储集群服务,安全可靠、接口丰富,并且收费价钱也比较合理(1G数据存储一个月只要10美分左右)。这比为了实现服务器文件备份专门准备一台服务器划算多了,而且S3的存储服务器可以选择在美国或者欧洲,于是和被备份的服务器自然形成了跨地域的分布式存储,数据抵抗自然灾害的能力由此提高了很多。本文简要介绍将Linux服务器上的文件增量备份到S3服务上的配置实现方法。
2. Duplicity简介
官方网站位于http://www.nongnu.org/duplicity/ 。这是一个使用Python语言实现的文件增量备份工具,其利用rsync底层类库,实现仅把文件中变化了的数据存入增量备份包的工作方式(类似给文件生成Patch补丁的方式),调用pgp对数据包进行签名和加密,而且支持本地文件系统、远端ftp、ssh/scp、rsync、WebDAV、WebDAVs、HSi以及Amazon S3等非常丰富的备份存储介质。
3. 安装及配置
3.1 手工安装
其实Debian自身已经提供了Duplicity的软件包,但Debian etch带的Duplicity是古老的0.4.2版本,还不支持向S3服务发送备份。我们得另想办法搞定高版本的。
- 安装Duplicity运行所需要的组件:apt-get install librsync1 python-central python python gnupg python-gnupginterface
- 准备Duplicity源代码安装所需要的编译环境:apt-get install build-essential duplicity
- 安装源代码安装所必须的头文件:apt-get install python-dev librsync-dev
- 下载http://savannah.nongnu.org/download/duplicity/duplicity-0.5.00.tar.gz
- tar zvxf解压上一步获得的压缩包
- python setup.py install
- 应该已经顺利安装成功了,“duplicity --version”应该显示是0.5.00版本
先不管S3,我们先玩一下duplicity增加一点感性认识:
如果我们不希望duplicity运行时候问“GnuPG passphrase:”怎么办呢,可以把这个参数设置成PASSPHRASE环境变量。比如我们在刚才运行duplicity之前,可以先执行“export PASSPHRASE=test”就可以把手动输入签名的步骤给省了。
下面我们来考虑和S3之间的联动,这需要python-boto这个包,但是etch里面还没有提供这个软件包。没关系,我们可以通过easy_install来自行安装:
- 下载http://peak.telecommunity.com/dist/ez_setup.py ,并用python执行这个文件(python ez_setup.py,执行时应该是需要root权限),系统会自动生成easy_install命令。
- easy_install boto
- 这样会通过easy_install安装python-boto的1.4c版本。
boto需要进行一些设置才能正常工作。首先要在http://aws.amazon.com 注册Amazon Simple Storage Service (Amazon S3)服务的帐号,并且确定付款方式(比如通过Visa信用卡支付美元)。然后查找自己访问S3服务的ID和Key(在AWS注册并登陆后,页面右上角附近有一个写着“Your Web Services Account”的黄色下拉菜单,鼠标在这个菜单上停留,选择“AWS Access Identifiers”即可以查到自己的Access Key ID以及Secret Access Key,这两个相当于访问S3用的用户名和密码)。这两个参数通过环境变量传递给duplicity(对于0.5.00版本来说),也就是需要:
export AWS_SECRET_ACCESS_KEY=<your access key>
此时如果我们把前面测试用的指令改成
如果要取回备份的文件,可以类似这样:
duplicity的详细使用说明参见“man duplicity”或者http://www.nongnu.org/duplicity/duplicity.1.html
3.2 从deb包进行安装
手工安装会使得Debian的dpkg管理工具搞不清python-boto和duplicity包的当前状况,因此lenny下我倾向于使用官方源里面的duplicity版本(0.4.11,基本上够用了)。etch下则还是古老的0.4.2,只好试着将高版本Debian的deb包弄下来想办法搞定版本依赖关系来安装。所幸只要不是最新的包,与etch的版本依赖的不匹配情况并不十分严重。我在etch环境下重新编译了duplicity 0.4.12-2以及python-boto 1.2a-1的deb包,经测试是完全可以在etch下正常工作的。可以下载后直接使用dpkg -i指令安装,并相应用apt-get install -f来自动安装其他依赖的软件包。这两个deb文件下载见(很可能已经不可用了,因为现在etch下面的Python版本比下面这两个deb文件编译时所指定依赖的Python版本更新一些……):
软件配置细节请参考手工安装的说明,但有一点是不同的:duplicity 0.4.12版本不是通过环境变量来接收S3访问ID和Key的,而是如下这样:编辑/etc/boto.cfg文件或者~/.boto文件,输入内容
aws_access_key_id = <your access key>
aws_secret_access_key = <your access key>
3.3 在Mac下安装
Darwin Ports有提供这个包,虽然不算很新。装好Darwin Ports之后,“sudo port install duplicity”即可,详细可以参照http://duplicity.darwinports.com/
4. 安全性探讨
我的理解是duplicity在生成备份文件包的时候用pgp加密过了,所以理论上备份文件包被别人弄走了也不怕,不过我没有仔细确认过这一点。
另外,S3有自身的权限控制机制,参见S3 ACLs。我的S3空间默认就是屏蔽公众访问的,所以权限控制这一块其实我也没有更仔细地去确认过。。
5. 问题与技巧
5.1 关于S3访问工具
如果想要登陆S3操作已经存储的文件备份,那么最好还是有一个对应的客户端才方便。Mac下可以使用Transmit。考虑所有平台的话,有开源的Java客户端实现JetS3t Cockpit。另外听说收钱的Jungle Disk也是相当好用的。
5.2 关于403 Forbidden错误
有时访问S3时,会得到一个S3ResponseError错误,并且说403 Forbidden。那是因为duplicity所在主机的时间与S3服务器差别太大(超过了10分钟)造成的。仔细看错误提示,里面有给出服务器当前时间和客户端当前时间。可以用ntpdate等互联网对时服务校正时间,或者干脆用“date --set="2008-01-23 13:47:43"”这样的指令手工进行修正。
5.3 关于Invalid SSH password错误
有时访问ssh或者scp时,会得到Invalid SSH password错误提示,虽然已经用类似ssh://user:pass@host这样的格式设置了正确的登陆密码。此时应当放弃在ssh://中写入密码,并且给duplicity增加--ssh-askpass运行参数,即可以正确完成向ssh或者scp进行的数据备份工作。
5.4 一次备份多个目录的方法
当需要一次备份多个目录时,可以这么写:
5.5 备份任务的自动执行
这里要用到Cron了。我在root用户下用crontab -e设定每天凌晨3点执行/boot/script/backup.sh脚本:
export AWS_ACCESS_KEY_ID=<your access key>
export AWS_SECRET_ACCESS_KEY=<your access key>
duplicity --include /etc --include /var/www --exclude '**' / s3+http://elias.cn-backup
不要忘记在0.5.00以前版本的duplicity编辑/etc/boto.cfg或者root/.boto文件设置访问S3的ID和Key,并且给backup.sh用“chmod +x”添加可执行权限。
5.6 备份MySQL
duplicity自己只能备份文件系统上的东西,我们可以通过与其他脚本的配合来解决MySQL、SVN等服务的备份问题。比如我们把backup.sh改成这样:
export AWS_ACCESS_KEY_ID=<your access key>
export AWS_SECRET_ACCESS_KEY=<your access key>
mysqldump --password=YourSqlPass --opt --skip-extended-insert database > /root/backup/backup-file.sql
duplicity --include /etc --include /var/www --include /root/backup --exclude '**' / s3+http://elias.cn-backup
5.7 “GnuPG exited non-zero”错误
如果Duplicity使用过程中遇到如下错误并造成程序运行中止:
raise IOError, "GnuPG exited non-zero, with code %d" % (e << 8)
IOError: GnuPG exited non-zero, with code 131072
简单来讲,这是因为Duplicity运行过程中调用GnuPG进行处理时,GnuPG出错了。这时应该查询系统的错误信息日志(比如dmesg)看看到底GnuPG是为什么出错。我当时遇到这个问题时,是GnuPG把系统内存用光了导致出错。我备份后删除了历史备份存档,让Duplicity需要检查的历史备份深度减少,就可以大致改善这个内存占用问题。(比如,让Duplicity删除15天以前的备份存档。)
6. 其他类似解决方案
其实Perl实现的backup-manager也是能够备份到S3上的,etch自带的版本就可以。但是试着向S3进行备份,会报错。查看/var/log/user.log,能看到详细的错误提升,原因是缺少了Net::Amazon::S3这个库。可以用“cpan -i Net::Amazon::S3”来安装,也可以直接用Debian里面的libnet-amazon-s3-perl这个包(这个包etch里面没有……得自己想办法盗用高版本的)。此外还得安装libxml2-dev这个包。如果仍然不能正常工作的话,就看user.log的错误提示吧。
但是backup-manager工作在S3上有一个重大问题:当上传3M的文件时,backup-manaer会占用系统26M左右的内存;上传单个文件10M大小的文件时,大约占用64M左右的内存。这怕是有点儿恐怖。因此虽然backup-manager别的功能都感觉相当不错,仍然是放弃了它,改用duplicity。而duplicity无论怎样使用,占用的内存都保持在10M左右。