多台服务器文件实时同步 rsync+inotify

前言

当线上服务器有多台并且又没有运维的时候,传输文件就成了一件非常麻烦的事儿,每次传代码都需要登录多台服务器,很容易就漏传了文件,这时候就需要一个自动化的文件同步工具了。

虚拟机服务端:192.168.146.103

虚拟机客户端1:192.168.146.102

虚拟机客户端2:192.168.146.104

系统:centos6.5

关于rsync

与传统的cp、tar备份方式相比,rsync具有安全性高、备份迅速、支持增量备份等优点,通过rsync可以解决对实时性要求不高的数据备份需求,例如定期的备份文件服务器数据到远端服务器,对本地磁盘定期做数据镜像等。

关于inotify

inotify是一种强大的、细粒度的、异步的文件系统事件监控机制,linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加、删除,修改、移动等各种细微事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools就是这样的一个第三方软件。

1、服务端安装rsync

检查服务器是否已经安装rsync

rpm -aq rsync

如果存在可以卸载之后再重新安装最新版,如果不存在直接安装。以下两种方式选择一种安装。

选择1、自动安装:

yum install -y rsync

选择2、手动安装:

cd /usr/local/src
wget  http://rsync.samba.org/ftp/rsync/src/rsync-3.0.9.tar.gz
tar zxvf rsync-3.0.9.tar.gz
cd rsync-3.0.9
./configure --prefix=/usr/local/rsync
make
make install

编辑配置文件/etc/rsyncd.conf,有时候这个文件会存在,如果不存在,手动创建即可。

motd file = /etc/rsyncd.motd
#设置服务器信息提示文件,在该文件中编写提示信息
transfer logging = yes
#开启rsync数据传输日志功能
log file = /var/log/rsyncd.log
#设置日志文件名,可通过log format参数设置日志格式
pid file = /var/run/rsyncd.log
#设置rsync进程号保存文件名称
lock file = /var/run/rsync.lock
#设置锁文件名称
port = 873
#设置服务器监听的端口号,默认是873
address = 192.168.146.103
#设置本服务器所监听网卡接口的ip地址
uid = nobody
#设置进行数据传输时所使用的帐户名或ID号,默认使用nobody
gid = nobody
#设置进行数据传输时所使用的组名或GID号,默认使用nobody
#若为yes, rsync会首先进行chroot设置,将根映射在下面的path参数路径下,对客户端而言,系统的根就是path参数指定的路径。但这样做需要root权限,并且在同步符号连接资料时只会同步名称,不会同步内容。
use chroot = no
read only = yes
#是否允许客户端上传数据,yes表示不允许
max connections =50
#设置并发连接数,0表示无限制
[common]
#自定义模块名,rsync通过模块定义同步的目录,可定义多个
comment = web content
#定义注释说明字串
path = /home/works
#同步目录的真是路径通过path指定
ignore errors
#忽略一些IO错误
#exclude = test/
#exclude指定common目录下某个目录可以不同步数据
auth users = tom
#设置允许连接服务器的账户,此账户可以是系统中不存在的用户
secrets file = /etc/rsyncd.secrets
#密码验证文件名,该文件权限要求为只读,建议为600,仅在设置auth users后有效
hosts allow = 192.168.146.104 192.168.146.102
#设置哪些主机可以同步数据,多ip和网段之间使用空格分隔
hosts deny=*
#除了hosts allow定义的主机外,拒绝其他所有
list = false
#客户端请求显示模块列表时,本模块名称是否显示,默认为true

创建密码文件并修改文件权限,用户名需要和上面配置的auth users对应

# 创建密码文件
echo "tom:123" > /etc/rsyncd.secrets

# 设置600权限
chmod 600 /etc/rsyncd.secrets

# 设置启动提示语
echo "welcome to access" > /etc/rsyncd.motd  #此项客户端不需要做

# 后台运行
rsync --daemon 
# --daemon表示后台执行,客户端开启rsync不需要--daemon选项

# 开机启动rsync服务
echo "/usr/bin/rsync --daemon" >> /etc/rc.local

开放防火墙设置

# 查看防火墙状态,发现没有开放873端口
iptables -L -n

# 开放873端口
/sbin/iptables -I INPUT -p tcp --dport 873 -j ACCEPT

# 保存设置
/etc/rc.d/init.d/iptables save

# 重启防火墙
/etc/init.d/iptables restart

# 查看开放的端口是否生效
/etc/init.d/iptables status

如果修改了conf文件,需要重启一下rsync,先找到进程,kill掉,再运行rsync --daemon

2、客户端安装rsync并同步

和上面一样步骤,选择自动安装,或者手动安装。

客户端不需要设置rsyncd.conf

# 客户端只需要把密码写入文件
echo "123" > /etc/rsyncd.secrets

# 添加600权限
chmod 600 /etc/rsyncd.secrets

和上面一样步骤,开放873端口

3、测试执行同步命令

这时候可以在客户端运行命令测试同步功能了。

由于安装方式的不同,rsync执行软件位置不一样,要注意先find / -name rsync查找一下。

比如在虚拟机:192.168.146.104中:

# 需要手动输入密码
usr/bin/rsync -vzrtopg --progress  tom@192.168.146.103::common /home/works

# 推荐这种,一步到位
usr/bin/rsync -vzrtopg --progress --password-file=/etc/rsyncd.secrets tom@192.168.146.103::common /home/works
# 使用的参数说明:
v:显示详细信息

z:传输过程中对数据进行压缩

r:递归

t:保留修改时间属性

o:保留文件所有者属性

p:保留文件权限属性

g:保留文件所属组属性

a:归档模式,主要保留文件属性,等同于-rlptgoD

--progress:显示数据传输的进度信息

--password-file=FILE:指定密码文件,将密码写入文件,实现非交互式数据同步,这个文件名也需要修改权限为600

--delete:删除那些仅在目标路径中存在的文件(源路径中不存在),在脚本中的数据同步经常加上此参数

--list-only:仅列出服务器模块列表,需要rsync服务器设置list=true

在服务端的同步文件/home/works里创建一个文件。

执行上面的命令,成功后会显示同步了哪些文件,速度多少等信息,在客户端对应的/home/works文件下也会同步更新。

上面已经实现了执行一条命令就可以同步更改的文件,但是如果能自动化就更好了,下面我们引入另一个工具inotify来实现。

4、解决主次的问题

我们刚才实现的是服务端的文件做了改动,在客户端执行拉取命令来同步文件,但实际上经常出现的情况却是服务端做了改动,更希望能从服务端推送到客户端,而不是在客户端去执行命令,这时候有两个解决方案:

a、rsync支持拉取和推送操作,但是需要命令行把目标服务器和源服务器对调,得重新配一遍,还要改一些配置,比如用户权限,是否允许客户端写入到服务端,很麻烦

b、我们尝试通过在服务器端ssh连接到客户端再执行命令,依然是一条命令即可

ssh root@192.168.146.104 "/usr/bin/rsync -vzrtopg --progress --password-file=/etc/rsyncd.secrets tom@192.168.146.103::common /home/works"

ssh链接客户端碰到一个问题,就是需要输入密码,那我们来进行免密设置

cd /root/.ssh/             #【root用户就在root目录下的.ssh目录】

ssh-keygen -t dsa               # 一路回车即可,之后得到id_dsa -->私钥(钥匙) id_dsa.pub -->公钥(锁)

ssh-copy-id -i id_dsa.pub root@192.168.146.104           【使用ssh登录的默认端口22】

ssh-copy-id -i id_dsa.pub –p 666 root@192.168.146.104            【使用ssh登录设置的端口666,好像会有错误】

进入到目标服务器看一下文件ll /root/.ssh/authorized_keys

这时候在执行ssh命令就可以跳过密码直接同步成功了。

5、inotify实现自动化

在服务端安装inotify

选择1、自动安装:

yum install inotify-tools –y

选择2、手动安装:

wget https://newcontinuum.dl.sourceforge.net/project/inotify-tools/inotify-tools/3.13/inotify-tools-3.13.tar.gz 
tar zxvf inotify-tools-3.13.tar.gz 
cd inotify-tools-3.13 
./configure --prefix=/usr/local/inotify 
make
make install

安装后会多以下两个命令 inotifywait inotifywatch

用find查找具体位置,安装方式不同,软件位置不一样。

现在我们先来测试一下,执行inotifywait命令监测/data目录是否有变化

/usr/bin/inotifywait -mrq --format '%w%f' -e close_write,delete /data/

新开一个窗口,在/data目录创建一个测试文件,然后看看另一个窗口inotifywait命令是否监测到了变化,如果有监测到则说明一切正常!

接下来就是正式创建一个监控脚本,vim /server/inotify_104.sh

#!/bin/bash
src=/home/works/  #所要监控的备份目录(此处可以自定义,但是要保证存在)           

/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \
| while read files
do
ssh root@192.168.146.104 "/usr/bin/rsync -vzrtopg --delete --progress --password-file=/etc/rsyncd.secrets tom@192.168.146.103::common /home/works"
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done

保存文件,修改权限

chmod 764 /server/inotify_104.sh

后台运行,sh /server/inotify_104.sh &

测试成功后可以选择不输出日志

nohup sh /server/inotify_104.sh > /dev/null 2>&1 &

现在在服务端的同步文件/hmoe/works下执行创建、修改,删除等操作都会同步到客户端对应的同步文件下。

6、多台配置

上面展示只有一个服务端一个客户端,如果要再添加一个客户端,需要在上面的基础上添加以下几个地方:

1、在服务端的/etc/rsyncd.conf配置文件里hosts allow = ip1 ip2,多个ip用空格隔开。

2、新的客户端也要安装rsync,配置ssh免密码,然后在服务端增加一个/server/inotify_102.sh这样的监控脚本。

3、后台nobub运行。

4、最后,服务端只要有改动,两个客户端都会对应改动,经过测试会有一点延迟。

7、最后

参考:

https://www.jianshu.com/p/59a3ea7c78b9

https://blog.csdn.net/hblfyla/article/details/81093647

https://blog.51cto.com/net881004/2346921

https://blog.csdn.net/hyh9401/article/details/52043134

https://blog.csdn.net/weixin_34245169/article/details/88762728

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐