rsync+inotify实现文件双向同步
背景需求说明
已经使用keepalived实现nginx VIP动态漂移,那么在实际使用中还发现一个问题,即nginx端做CURD配置操作时,需要涉及到两台(或更多节点)nginx同时手工做修改,会比较繁琐,还会导致配置不一致的情况出现。
那么2台nginx server配置目录的文件双向同步需求衍生出来了。
为了解决这个问题,调研了一下业务常用的技术方案,发现rsyn + inotify结合的方式使用比较普遍。
本次实验素材:
Server | IP |
---|---|
ng-serv-1 | 11.11.11.57 |
ng-serv-2 | 11.11.11.67 |
如果无特殊说明,如下操作均已root身份执行。
1、2台server双向ssh免密登陆
不再详述,核心操作如下:
1.1、生成.ssh供秘钥文件
两台server上执行:
ssh-keygen -t rsa
1.2、拷贝公钥文件到对方主机
ssh-copy-id -i ~/.ssh/id_rsa.pub 目标机器ip地址/主机名
2、rsync安装配置
2.1 rsync安装
./configure --prefix=/usr/local/rsync/ --disable-xxhash --disable-zstd --disable-lz4
make && make install
/usr/local/rsync/bin/rsync -ruPip /opt/cloudera /data/sys_disk_mirror
-r 循环目录
-u update模式,只同步更新过的
-P 等于--partial --progress,显示进度,并支持断点续传
-i 显示每个文件的同步细节,见下面--itemize-changes部分
-p 保留权限
-l 拷贝软链接(如果要拷贝链接指向的实际文件,用-L)
-E 保留执行权限
-t 保留修改时间
--delete 同步删除动作
其中,-i 显示每个文件的同步细节,见下面--itemize-changes部分
下面内容转自:stackoverflow
Explanation of each bit position and value in rsync's output:
YXcstpoguax path/to/file
|||||||||||
||||||||||╰- x: The extended attribute information changed
|||||||||╰-- a: The ACL information changed
||||||||╰--- u: The u slot is reserved for future use
|||||||╰---- g: Group is different
||||||╰----- o: Owner is different
|||||╰------ p: Permission are different
||||╰------- t: Modification time is different
|||╰-------- s: Size is different
||╰--------- c: Different checksum (for regular files), or
|| changed value (for symlinks, devices, and special files)
|╰---------- the file type:
| f: for a file,
| d: for a directory,
| L: for a symlink,
| D: for a device,
| S: for a special file (e.g. named sockets and fifos)
╰----------- the type of update being done::
<: file is being transferred to the remote host (sent)
>: file is being transferred to the local host (received)
c: local change/creation for the item, such as:
- the creation of a directory
- the changing of a symlink,
- etc.
h: the item is a hard link to another item (requires
--hard-links).
.: the item is not being updated (though it might have
attributes that are being modified)
*: means that the rest of the itemized-output area contains
a message (e.g. "deleting")
2.2 rsync配置
2.3.1 ng-serv-1 侧 “/etc/rsyncd.conf” 配置
pid file = /var/run/rsyncd.pid
port = 873
address = 11.11.11.57
uid = root
gid = root
use chroot = yes
read only = no
hosts allow=11.11.11.67
hosts deny=*
max connections = 5
motd file=/etc/rsyncd.motd
lock file=/var/run/rsyncd.lock
log file =/var/log/rsyncd.log
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300
[nginx_backup_module] ## 自定义模块名,哪个用户使用哪个秘钥配置同步文件到对方的哪个目录下
path = /etc/nginx/conf
list=no
ignore errors
comment = Nginx config backup
auth users = admin_backuper
secrets file = /etc/rsyncd.secrets
2.3.2 ng-serv-2 侧 “/etc/rsyncd.conf” 配置
pid file = /var/run/rsyncd.pid
port = 873
address = 11.11.11.67
uid = root
gid = root
use chroot = yes
read only = no
hosts allow=11.11.11.57
hosts deny=*
max connections = 5
motd file=/etc/rsyncd.motd
lock file=/var/run/rsyncd.lock
log file =/var/log/rsyncd.log
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300
[nginx_backup_module] ## 自定义模块名,哪个用户使用哪个秘钥配置同步文件到对方的哪个目录下
path = /etc/nginx/conf
list=no
ignore errors
comment = Nginx config backup
auth users = admin_backuper
secrets file = /etc/rsyncd.secrets
3、同步用户秘钥文件
文件内容格式:
同步用户名 : 同步使用的密码
使用范例:
admin_backuper:1234abcd
注意:
1、同步用户并非linux系统真实用户;
2、用户名与密码之间以英文冒号(:)隔开,冒号2侧不要加空格;
3.1 查看rsync进程
[root@server11-57 conf.d]# ps -ef | grep rsync | grep -v grep
root 18535 1 0 3月29 ? 00:00:02 rsync --daemon --config=/etc/rsynd.conf
3.2 检查启动用户并kill掉进程,删除进程文件
kill -9 18535
rm -rf /var/run/rsyncd.pid
3.3 启动rsync进程
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
4、inotify配置
4.1、安装,略;
4.2、inotify的配置
此处仅以ng-serv-1 的配置为例,ng-serv-2同理。
inotify结合rsync实现双向实时同步可以在shell脚本中实现,如:/usr/local/inotify/inotify_back.sh
#!/bin/bash
#chkconfig: 2345 80 90
#description: inotify autostart service.
# sync folder to be synced in this server
src_tobe_synced=/etc/nginx/conf/
# 同步接收方ip
remote_nginx_ip=11.11.11.67
# sync receiver's rsync module name
dest_module_name=nginx_backup_module
# sync receiver's authentication username
remote_auth_user=admin_backuper
set -x
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' -e modify,delete,create,move,attrib $src_tobe_synced | while read file
do
/usr/bin/rsync -vzrtopgl --progress --delete --password-file=/etc/rsyncd.passwd $src_tobe_synced $remote_auth_user@$remote_nginx_ip::$dest_module_name
echo "${file} was rsynced" >> /var/log/rsync.log 2>&1
done
set +x
配置说明:
1、inotify中可以使用inotifywait指令,进行文件增、删、改、移动、或修改文件元数据(如更改文件创建时间)等状态的监控,一旦有变动,则将被监视目录的变动情况实时打印出来;
2、实际使用中,常将1中的文件变动list,通过管道命令传递给rsync进程,进而实现文件实时变动后的同步操作。
5、rsync、inotify设置开机自启动
5.1 rsync开机自启
①、打开/etc/rc.local文件
vim /etc/rc.local
②、文件末尾换行,添加rsync启动命令
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
③、如果开启未自动启动,请检查文件是否有x权限
lrwxrwxrwx. 1 root root 13 3月 21 2016 /etc/rc.local -> rc.d/rc.local
这里的情况是,软链接有x权限,但需进一步检查原始文件是否有x权限
-rwxr-xr-x 1 root root 625 5月 10 15:00 /etc/rc.d/rc.local
如果无,添加之:
chmod +x /etc/rc.d/rc.local
5.2 inotify开机自启
前置:
Linux shell类脚本必须在其前添加如下3行属性,才可以使用chkconfig命令主要来更新(启动或停止)和查询系统服务的运行级信息。
谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接。
#!/bin/bash
#chkconfig: 2345 80 90
#description: inotify autostart service.
修改原脚本文件,添加start、stop函数:
#!/bin/bash
#chkconfig: 2345 80 90
#description: inotify autostart service.
# sync folder to be synced in this server
src_tobe_synced=/etc/nginx/conf.d/
# 同步接收方ip
remote_nginx_ip=11.11.11.67
# sync receiver's rsync module name
dest_module_name=nginx_backup_module
# sync receiver's authentication username
remote_auth_user=admin_backuper
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
pid_file="${dir}/inotify.$(hostname).pid"
log_file="${dir}/logs/inotify.`hostname`.log"
function start(){
echo "inotify for nginx service is start..."
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y/%m/%d-%H:%M:%S' --format '%T %w %f' -e modify,delete,create,move,attrib $src_tobe_synced | while read file
do
/usr/bin/rsync -vzrtopgl --progress --delete --password-file=/etc/rsyncd.passwd $src_tobe_synced $remote_auth_user@$remote_nginx_ip::$dest_module_name
echo "${file} was rsynced" >> /var/log/rsync.log 2>&1
done &
let sub_pid=$!-1
echo $sub_pid > "$pid_file"
#echo "sub-process :"$$ >> "$pid_file"
#echo "PPID of this script: $PPID" >> "$pid_file"
#echo "UID of this script: $UID" >> "$pid_file"
}
function stop(){
echo "inotify for nginx service is stop..."
inotify_pid=`cat $pid_file`
kill -9 $inotify_pid
#delete the pid
sed -i "/${inotify_pid}/d" $pid_file
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
printf 'Usage: $0 {start|stop|restart}\n'
exit 1
;;
esac
①、脚本移动至/etc/rc.d/init.d目录下,或在其下建软链接
ln -s /usr/local/inotify/inotify_back.sh autostart_inotify.sh
②、为脚本增加可执行权限
chmod +x /etc/rc.d/init.d/autostart_inotify.sh
③、将脚本添加到开机自启项目
chkconfig --list
cd /etc/rc.d/init.d
chkconfig --add autostart_inotify.sh (增加,删除为–del)
chkconfig autostart_inotify.sh on (开启,关闭为 off)
6、同步服务说明
6.1 单向同步说明
如果仅开启从 ng-serv-1 到 ng-serv-2 的单向文件同步,只需:
源 | 方向 | 目标 |
---|---|---|
ng-serv-1(开启rsync、inotify) | —》 | ng-serv-2(仅开启rsync即可) |
6.2 双向同步说明
如果需开启 ng-serv-1 到 ng-serv-2 的双向文件同步,需要:
源 | 方向 | 目标 |
---|---|---|
ng-serv-1(开启rsync、inotify) | 《—》 | ng-serv-2(开启rsync、inotify) |
参考列表:
1、rsync同步本机目录(https://www.cnblogs.com/taosim/articles/3808389.html)
2、rsync增量同步标志位详细解释(https://www.cnblogs.com/felix-zp/p/9740487.html)