rsync+inotify实现文件的实时同步

一、rsync工具介绍

rsync(remote sync)即远程同步。rsync不仅可以远程同步数据(类似于scp),而且可以本地同步数据(类似于cp),但不同于cp或scp的是,它不会覆盖以前的数据,而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。

rsync安装:yum install -y rsync

rsync的命令格式:

rsync [选项] ... SRC DEST

rsync [选项] ... SRC [ USER@ ]HOST:DEST

rsync [选项] ... [ USER@ ]HOST: SRC DEST

rsync [选项] ... [ USER@ ]HOST::SRC DEST

rsync [选项] ... SRC [ USER@ ]HOST::DEST

二、rsync常用选项

-a:归档模式,表示以递归的方式传输文件,并保持所有属性,等同于-rlptgoD。-a选项后面可以跟一个–no-OPTION,表示关闭-rlptgoD中的某一个,比如-a–no-l等同于-rptgoD。

-r:以递归的方式处理子目录。主要是针对目录来说的,如果单独传一个文件不需要加-r选项,但是传输目录时必须要加。

-v:打印一些信息,比如文件列表、文件数量等。

-l:保留软链接。

-L:表示像对待常规文件一样处理软链接。如果是SRC中有软链接文件,则加上该选项后,将会把软链接指向的目标文件复制到DST。

-p:保持文件权限。

-o:保持文件属主信息。

-g:保持文件属组信息。

-D:保持设备文件信息。

-t:保持文件时间信息。

–delete:删除DST中SRC没有的文件。

–exclude=PATTERN:指定排除不需要传输的文件,等号后面跟文件名,可以是万用字符模式(如*.txt)。

–progress:在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、同步的文件传输速度等。

-u:表示把DST中比SRC还新的文件排除掉,不会覆盖。

-z:加上该选项,将会在传输过程中压缩。

常用的选项有-a、-v、-z、–delete和–exclude这几个。

三、inotify介绍

inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。 inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等,还可以跟踪活动的源头和目标等细节。 inotify同时是一种强大的、细粒度的、异步的文件系统事件监控机制,Linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加、删除,修改、移动等各种细微事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样的一个第三方软件。

安装inotify:yum install -y inotify-tools

四、sync+inotify实现文件的实时同步

环境准备:两台CentOS7 源服务器192.168.154.10 目标服务器192.168.154.11

目标服务器上(11)
1、关闭防火墙并设置开机不启动 2、关闭Selinux 3、安装rsync
yum install -y rsync 4、编写配置文件/etc/rsyncd.conf,内容如下:

log file = /var/log/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
secrets file = /etc/rsyncd.pass


[share]
path = /data/rsync
uid = root
gid = root
port = 873
ignore errors
use chroot = no
read only = no
list = no
timeout = 600
auth users = zjin

实例中 如图:
rsync+inotify实现文件的实时同步_第1张图片

[root@BK-S ~]# vi /etc/rsyncd.conf
##rsync config start
##created by root 2016-08-08 15:00
syncd.conf config start 以上为注释部分
adress=ip // 是本机的IP,也就是源服务器地址
uid = rsync
gid = rsync
use chroot = no
max connetctions = 200 最大连接数(并发)
timeout = 100 超时时间默认S单位
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
[backup] 模块名称可自定义任意名称
path = /backup/ 备份数据的路径
ignore errors 忽略错误
read only = false
list = false
hosts allow = 192.168.1.0/24 //这个是目标服务器的IP地址
hosts deny = 0.0.0.0/32
auth users = rsync_backup 虚拟的用户用于连接认证
secrets file = /etc/rsync.password 认证的密码配置文件路径
##rsync config end

5、编写文件/etc/rsyncd.pass,并设置权限为600,内容如下:

zjin:123456 #用户名:密码

6、开启rsyncd服务并设置开机启动 systemctl start rsyncd systemctl enable rsyncd

源服务器上(10)

1、关闭防火墙并设置开机不启动 2、关闭Selinux 3、安装rsync

yum isntall -y rsync

4、创建认证密码文件/etc/rsyncd.passwd,内容如下:

123456 #对应目标机器上的密码

并设置600权限
测试
1、在源服务器(10)的/data/rsync目录中创建几个文件 2、在源服务器(10)上输入以下命令:

rsync -avH --port 873 --progress --delete /data/rsync/ zjin@192.168.154.11::share --password-file=/etc/rsyncd.passwd

实例中,同步某个文件

rsync -avH --port 873 --progress --delete /home/vnfm/rsync/mingling eb_vnfm@10.1.118.2::share --password-file=/etc/rsyncd.secrets

在这里插入图片描述
3、在目标服务器(11)的/data/rsync目录中查看是否同步成功

相关命令:

 rsync -avH --port 873 --progress --delete /home/vnfm/rsync eb_vnfm@10.1.118.2::share --password-file=/etc/rsyncd.secrets
chmod 600 rsyncd.conf
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
lsof -i:873

安装inotify-tools工具,实现实时触发rsync进行同步

1、源服务器上(10)安装inotify-tools

yum isntall -y inotify-tools

2、创建目录/scripts,并在此目录上编写脚本文件inotify.sh,(设置755权限)内容如下:

#!/bin/bash

SRC="/data/rsync"

/usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %f%e' -e modify,delete,create,attrib ${SRC} | while read files
do
  /usr/bin/rsync -vzrtopg --progress --password-file=/etc/rsyncd.passwd /data/rsync/* zjin@192.168.154.11::share

  echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done

3、启动脚本(以后台方式运行),并查看是否启动成功

nohup bash /scripts/inotify.sh & ps -ef|grep inotify

此时就可以实现实时同步文件了。

4、设置脚本开机启动

chmod +x /etc/rc.d/rc.local

echo 'nohup /bin/bash /scripts/inotify.sh' >> /etc/rc.d/rc.local

注意事项

实现主备服务器互相同步文件,配置跟上面一样。
但会遇到如下问题:
在这里插入图片描述

网上查了下原因:
大概原因是客户端和服务端的密码文件写法不一样。

关于这个auth失败的问题,有以下可能的情况:

1、密码输入错误:
请再次确认你登录用户的密码无误

2、secrets file格式错误:
secrets file的文件格式是 upload:123456
表示upload用户的rsync密码是123456

3、配置文件写错:
最坑爹的一个,看看自己模块配置下面的auth users、secrets file有没写错

4、secrets file权限问题
服务端的secrets file权限必须是600,
可以使用chmod 600 /home/user/test/rsync/etc/test.pass

5、secrets file文件拥有者与rsync运行者
服务端rsync服务是以什么用户运行,则必须保证secrets file文件拥有者必须是同一个
假设root运行rsync --daemon,则secrets file的owner也必须是root

6、如果是以–password-file=file的方式附带密码(我的问题
确保客户端密码文件格式无误,与服务端的密码文件不同,
客户端的不用加上用户名,即直接是 123456

7、可以尝试使用本地存在的用户名作为auth users
这个是在网上看到的,没实践过,不过如果都没办法,可尝试一下,
密码不要跟本地用户的系统密码一样就行了。

六、说一下关于rsync的密码访问

如果你 rsync -av --delete /tmp/a/ [email protected]::backup/a/

如上命令同步文件时,也是可以的,只要你服务端没有指定 auth users 和 secrets file

如果模块指定了secrets file 那么就必须使用你secrets file指定位置的文件作为密码文件

这个密码文件内容就是 auth users 中指定的虚拟用户名 : 密码

例: back:123456 back 就是如上配置文件中auth users 指定的。 就这一句就够了。

然后你客户端访问服务端的时候就需要使用密码了,其中密码有五种解决方案。

(1) 手动输密码。就是手动指定,当然要是脚本或者定时任务这种肯定不行。

(2) 使用密码文件,如上服务端已经指定好密码文件位置和内容了。 下面就是客户端的操作了。客户端创建一个文件,爱在哪建在哪建。如 /etc/rsync.pass 然后文件里面就写密码就完事了。 比如 123456 就完了,不需要别的。然后在你输入rsync命令时加上–password-file=/etc/rsync.pass 参数 指定密码文件在哪就Ok 有个坑 密码文件必须 600 访问权限

(3) 使用ssh 传。 这个是ssh-keygen 一路回车。然后去找 公钥。/root/.ssh/id_rsa.pub 会生成在这个地方。然后从客户端将这个文件追加到服务端的 authorized_keys 中 然后就ok了 (这个我没试,我采用第二种方法)

(4) 使用环境变量 有一个环境变量叫RSYNC_PASSWORD vim /etc/profile 编辑这个文件 加入命令 export RSYNC_PASSWORD = “123456”# 123456就是你对应想连的远程模块的密码。 然后 source /etc/profile 或者

. /etc/profile 注意前面这个 . 点跟 / 是分开的 然后输env 命令获取环境变量,发现有了,那就ok。但是需要注意的是你的程序是在哪启动的,如果跑在服务器下没问题,要是跑到docker中使用这种方法就不合适了。(推荐第二种)

如果你想删掉某个环境变量,在/etc/profile中 unset RSYNC_PASSWORD 就删了

经过如上环境变量的配置 即使服务端设置密码rsync -av --delete /tmp/a/ [email protected]::backup/a/ 也OK不用手动输入密码。

(5) 使用 sshpass 这个来通过密码访问,这个密码是明示的,所以肯定不安全。

先 yum install sshpass 安装。然后就可以用了。

sshpass -p 123456 rsync -av --delete /tmp/a/ [email protected]::backup/a/ 就OK了。

可以是可以,但是密码是明文传输的,太危险了。 相比之下第二种方案是最好的。

rsync 常见错误及解决方法

1、ERROR: chroot failed
ERROR: chroot failed rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]

原因:服务器端的目录不存在或无权限。

解决办法:创建目录并修正权限可解决问题。

2、skipping non-regular file
receiving incremental file list

skipping non-regular file “vendor/bin/doctrine”

skipping non-regular file “vendor/bin/doctrine.php”

sent 1990 bytes received 489209 bytes 327466.00 bytes/sec total size is 182515746 speedup is 371.57

原因:source源文件有软链接。

解决方法:修改为 rsync -va,其中 -a == -rlptgoD (no -H,-A,-X) 或者 rsync -rvltOD 也可以。

解决后:

receiving incremental file list

vendor/bin/doctrine -> ../doctrine/orm/bin/doctrine

vendor/bin/doctrine.php -> ../doctrine/orm/bin/doctrine.php

sent 1998 bytes received 489279 bytes 327518.00 bytes/sec total size is 182515746 speedup is 371.51

3、ERROR: module is read only
sending incremental file list

ERROR: module is read only

rsync error: syntax or usage error (code 1) at main.c(866) [receiver=3.0.6]

rsync: read error: Connection reset by peer (104)

rsync error: error in rsync protocol data stream (code 12) at io.c(759) [sender=3.0.6]

原因:source源服务器端权限设置read为only只读权限。

解决方法:read only = false

4、ERROR: auth failed on module tee
ERROR: auth failed on module tee rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.6]

原因:服务器端该模块(tee)需要验证用户名密码,但客户端未提供正确的用户名密码,认证失败。

解决方法:提供正确的用户名密码解决此问题。

5、ERROR: Unknown module ‘tee_nonexists’
ERROR: Unknown module ‘tee_nonexists’ rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.6]

原因:服务器不存在指定模块。

解决方法:提供正确的模块名或在服务器端修改成你要的模块以解决问题。

6、password file must not be other-accessible
password file must not be other-accessible

continuing without password file

Password:

原因:这是因为rsyncd.pwd rsyncd.secrets的权限不对,应该设置为600。

解决方法:chmod 600 rsyncd.pwd

7、rsync: failed to connect No route to host
rsync: failed to connect to 192.168.1.10: No route to host (113) rsync error: error in socket IO (code 10) at clientserver.c(104) [receiver=3.0.6]

原因:对方没开机、防火墙阻挡、通过的网络上有防火墙阻挡,都有可能。

解决方法:在iptables 中开放该端口,语句如下:

iptables -I INPUT -p tcp –dport 873 -j ACCEPT

rsync默认端口873,其实就是把tcp udp的873端口打开。

8、rsync error: error starting client-server protocol
rsync error: error starting client-server protocol (code 5) at main.c(1524) [Receiver=3.0.6]

原因:/etc/rsyncd.conf配置文件内容有错误。请正确核对配置文件。

9、rsync: chown “” failed: Invalid argument (22)
rsync: chown “” failed: Invalid argument (22)

原因:权限无法复制。去掉同步权限的参数即可。(这种情况多见于Linux向Windows的时候)

10、问题 @ERROR: daemon security issue — contact admin
@ERROR: daemon security issue — contact admin rsync error: error starting client-server protocol (code 5) at main.c(1530) [sender=3.0.6]

原因:同步的目录里面有权限不足的软连接文件,需要服务器端的/etc/rsyncd.conf打开use chroot = yes。

11、 rsync: read error: Connection reset by peer (104)
rsync: read error: Connection reset by peer (104) rsync error: error in rsync protocol data stream (code 12) at io.c(794) [receiver=3.0.6]

解决:很大可能是服务器端没有开启 rsync 服务,开启服务。

12、ERROR: failed to open lock file
@ERROR: failed to open lock file rsync error: error starting client-server protocol (code 5) at main.c(1495) [receiver=3.0.6]

解决:配置文件 rsync.conf 中添加 lock file = rsyncd.lock 即可解决。

2022.12.06 更新

问题1:

两台机器互相同步文件,其中一台正常,另一台备机做为客户端时,报错如下:
在这里插入图片描述
解决方案:IP为10.1.13.213的主机上有防火墙阻拦,:在iptables 中开放该端口:

iptables -I INPUT -p tcp –dport 873 -j ACCEPT

rsync默认端口873,其实就是把tcp udp的873端口打开。
或者直接 iptables -F 清除掉规则。(我自己的方案

问题2:

如果是以–password-file=file的方式附带密码,并且指定的密码文件是rsyncd.conf模块中定义的secrets file文件。
确保客户端密码文件格式无误,与服务端的密码文件不同,
客户端的不用加上用户名,即直接是密码 123456。

密码

服务端需要 虚拟用户名 : 密码

用户名:密码

而且,经过测试发现,该文件/etc/rsyncd.secrets里 只能有密码或者用户名和密码。 不能使用#注释,而存在其他值。
正确形式:

用户名:密码

错误形式,(使用# 注释也没用,会报错):

用户名:密码
# 其他值

问题3:

如果想两台机器互相同步文件,即互为客户端、服务端。
如果/etc/rsyncd.conf模块指定了secrets file 那么就必须使用你secrets file指定位置的文件作为密码文件
这个密码文件内容就是 auth users 中指定的虚拟用户名 : 密码 (被这句话误导了,可恶)

经过实际测试,即使在/etc/rsyncd.conf模块指定了secrets file,也可以以–password-file=file的方式附带密码。
而且,如果是两台机器互相同步文件,那么指定secrets file的方式就不能用了,因为这种方式要求客户端和服务端密码文件不同,如问题2所示。

所以可以直接通过指定 --password-file=/etc/rsyncd.pwd 的方式解决,即使rsyncd.conf 中指定了secrets file 也没有关系 。
两台机器上的 /etc/rsyncd.pwd 文件中只需要写密码就行。如下:
第一台机器(213)上:
rsync+inotify实现文件的实时同步_第2张图片
第二台机器(7)上:
在这里插入图片描述
目前最终的情况:
两台机器通过--password-file=/etc/rsyncd.pwd 这种指定密码方式互相进行文件同步(该文件里只有 密码)。

rsync -avH --port 873 --progress --delete /home/vnfm/rsync_test/ eb_vnfm@10.1.13.7::vnfm_vnfd --password-file=/etc/rsyncd.pwd 

并且实际测试发现,两台机器的中 rsyncd.conf 指定的secrets file /etc/rsyncd.secrets 值的形式都必须是 用户名:密码。 也不能在配置文件中不指定该值
rsync+inotify实现文件的实时同步_第3张图片
任何一台机器的/etc/rsyncd.secrets 的值不是用户名:密码这种形式都会报错。如下:
在这里插入图片描述

你可能感兴趣的:(Linux,linux,centos)