通过Inotify+rsync同步gitlab备份库

再参考其他人的方案,比如看了下老外怎么做,最终确认了可行的方案:

让gitlab定时运行它自己的备份任务,他会把库中所有项目信息和权限管理等信息,打包备份成一个压缩包。可以通过gitlab的自带命令导回去(gitlab程序版本必须完全一致)。

然后让inotify实时监控gitlab的备份目录,在备份目录发生变化时,告知rsync,让它以增量方式实时同步到远端存储(nas)上。

rsync除了增量方式,安全起见,再写一个定时任务,比如每2小时就全量备份同步一次。

具体步骤,我完全贴出来,有需要的朋友就可以直接使用了!

1).windows服务器(备份目的,ip:192.168.0.107),安装、配置cwRsync-server同步备份服务端程序

①安装cwRsync-server

从网上搜索到cwRsyncServer_4.1.0_Installer.exe,在windows下进行安装。

我选择的是默认安装位置:C:\Program Files (x86)\ICW

安装时会给windows创建一个账号,默认是SvcCWRSYNC,密码我们设定为123456。

②配置rsync服务端

打开安装目录下的rsyncd.conf文件,编辑同步服务器(同步目的)的配置信息:

use chroot = false strict modes = false hosts allow = * #允许所有主机连接

指定日志文件输出位置,下面地址为:F:\synch_backup_home\rsyncd.log

log file = /cygdrive/f/synch_backup_home/rsyncd.log

uid = 0 # 需要配置此项,不然连接报错 gid = 0 # 需要配置此项,不然连接报错

新增自己的库配置信息

自定义库名称,客户端连接时需指定这个名字

[syn_git_repo]

仓库位置,对应本机为:F:\synch_backup_home\shared_repository

path = /cygdrive/f/synch_backup_home/shared_repository

可读可写

read only = false

输出日志

transfer logging = yes

不允许客户端列出服务端的信息

list = no

对应配置用户名

auth users = SvcCWRSYNC

指定密码文件的位置,本机为:F:\synch_backup_home\rsync.passwd

secrets file = /cygdrive/f/synch_backup_home/rsync.passwd

[syn_git_repo]为自定义的服务端仓库名称,客户端(Centos7备份源)连接时需指定这个库的名称。

rsync.passwd文件中内容为:SvcCWRSYNC:123456

SvcCWRSYNC为备份时鉴权使用的账号名。123456为密码。

③给备份目的文件夹授权

为了防止客户端向服务器中备份文件时没有权限,按照网上的建议,我们把备份目的文件夹,也就是上面指定的仓库目录“F:\synch_backup_home\shared_repository”进行共享,并赋予SvcCWRSYNC用户所有权限。(有的教程中无此项配置,我为了以防万一还是授权了)

④重启rsync服务

修改完配置文件后,我们打开计算机的服务页面,在里面找到名为“RsyncServer”的服务。

把它设定为开机自动启动,然后重启它。

到此为止,windows服务器(备份目的)端就配置完毕了,剩下的就是Centos7(备份源)的工具安装和配置了!

2).Centos7上(备份源,ip:192.168.0.105),gitlab修改备份位置

①修改gitlab配置文件:

vim /etc/gitlab/gitlab.rb

找到备份相关的两项,进行修改:

修改备份路径,到我们准备实时监控备份的主目录下(/home/shared_repository是我们准备备份的根目录):


gitlab_rails['backup_path'] = "/home/shared_repository/git_backup"

备份文件保存时间,单位是秒,默认是7天

gitlab_rails['backup_keep_time'] = 604800

②修改完毕后保存退出,之后让gitlab重新配置一下:

gitlab-ctl reconfigure  #重新配置

gitlab-ctl restart #重启gitlab服务

然后我们可以通过gitlab的备份和导入备份的命令,测试下备份功能有效(请自行搜索验证gitlab的备份和导入功能并验证)。

3).Centos7(备份源),安装inotify和rsync客户端

接下来,该准备安装之前所说的“inotify(文件实时监控)+rsync(文件实时同步)的综合解决方案”所需的这两个命令了。

①在Centos7主机上,安装inotify:

yum -y install inotify-tools

若提示找不到软件,则需先安装Centos7的扩展安装源:

yum install epel-release

②安装成功后,再安装rsync客户端


yum -y install rsync

安装成功后,我们直接使用rsync命令,进行一次全量同步的测试。

在测试前,我们给待备份的源文件夹:“/home/shared_repository”中创建三个空文件:1.txt、2.txt和3.txt。

在Centos7中再创建一个rsync.passwd文件,用于同步时指定密码。

我创建到了“/home/synch_backup_home/rsync.passwd”,文件中的内容为:123456

③rsync全量备份测试

然后运行下面的命令,开始全量同步测试:

rsync -avz --password-file=/home/synch_backup_home/rsync.passwd /home/synch_backup_home/shared_repository/ SvcCWRSYNC@192.168.0.107::syn_git_repo

上面命令中的几个参数说明:

“--password-file=/home/synch_backup_home/rsync.passwd”参数指定同步时的连接密码文件位置(里面是123456)。

上面参数紧跟着的“/home/synch_backup_home/shared_repository/”,为备份源文件夹位置,请加上最后的“/”,否则会在目的文件夹根目录中再创建一个名为“shared_repository”的文件夹。

最后的参数“SvcCWRSYNC@192.168.0.107::syn_git_repo”分为3段:第一段“SvcCWRSYNC”为对应服务器端的用户名;第二段“192.168.0.107”为rsync服务器地址(备份目的);第三段“syn_git_repo”为rsync服务器端配置的自定义仓库名称(与上面rsyncd.conf文件的配置对应)。

运行后,稍等一会儿,会有本次一共同步了哪些文件,发送和接收总字节数的提示,就代表成功了!

然后我们在rsync服务端(windows服务器),“F:\synch_backup_home\shared_repository”文件夹中,会发现多了1.txt、2.txt和3.txt文件!测试成功!

4).编辑增量实时同步脚本

为了做到按需实时同步有变化的文件(rsync增量同步),需要配合使用inotify实时监控和rsync的增量同步。

因此,我们需要编写一个sh脚本文件,并在开机时启动它(开机后自动开始监控功能)。

我们在“/home/synch_backup_home/”目录中,编辑增量实时同步脚本“inotify_start.sh”,内容如下(在此感谢第一个编写如下脚本的朋友,我只是做了略微调整):

#!/bin/bash

#先定义脚本中所需各种变量
src=/home/synch_backup_home/shared_repository          # 需要同步的源路径
des=syn_git_repo                             # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/home/synch_backup_home/rsync.passwd            # rsync验证的密码文件
server_ip=192.168.0.107                 # 目标服务器
user=SvcCWRSYNC                         # rsync --daemon定义的验证用户名
log_file=/home/synch_backup_home/rsync.log  #日志输出文件路径

cd ${src}                               # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
/usr/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file         # 把监控到有发生更改的"文件路径列表"循环
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                #INO_FILE变量代表路径哦  -c校验文件内容
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${server_ip}::${des}
                 #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
        fi
        #删除、移动出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${server_ip}::${des}
                #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]                 # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${server_ip}::${des}
                fi
        fi

        #记录日志
        echo "${file} was rsynced at $(date "+%Y%m%d-%H%M%S")" >>${log_file} 2>&1
done

记得给inotify_start.sh添加运行权限:

chmod 500 inotify_start.sh

上面权限设置为,仅对当前用户能够读取和执行(避免被修改)。

5).最后一步:开启定时任务,启动所有功能

到此为止,windows端具备了同步服务的能力,Centos7我们也具备了同步gitlab备份仓库的能力,只差自动运行了。

因此,我们通过Centos7的crontab定时任务,来完成开机启用实时备份、同步的能力。

crontab -e

按“i”进入编辑模式,在其中增加定时任务,我把我整个定时任务全部贴出来,仅供参考:

在开机后,等待25秒后,开始运行实时同步备份脚本。

@reboot (sleep 25;sh /home/synch_backup_home/inotify_start.sh)

每2小时运行一次gitlab仓库的全量同步,并在前面添加开始时间、后面添加结束时间:

55 */1 * * * (/usr/bin/date "+\%Y\%m\%d-\%H\%M\%S full backup begin:";/usr/bin/rsync -avz --password-file=/home/synch_backup_home/rsync.passwd /home/synch_backup_home/shared_repository/ SvcCWRSYNC@192.168.0.107::syn_git_repo;/usr/bin/date "+\%Y\%m\%d-\%H\%M\%S full backup end!") >>/home/synch_backup_home/full_backup.log 2>&1

每天在关机前(比如19点50分,开始运行gitlab的备份功能)

50 19 * /usr/bin/gitlab-rake gitlab:backup:create

每天晚上20点定时关机

0 20 * /usr/sbin/shutdown -h now 由于我的设备每天晚上20点自动关机,因此,为了避免备份遗漏,建议还是加上定时全量备份。

增量备份的日志会输出到“/home/synch_backup_home/rsync.log”中。

全量备份的日志会输出到“/home/synch_backup_home/full_backup.log”中。