1 前言
1.1 概述
本文介绍使用rsync和 inotify-tools,实现linux 上的本地定时同步和远程定时同步的方法。
1.2 实验环境
服务器两台
操作系统: CentOS-7.4
软件:
rsync.x86_64 3.0.9-18.el7
inotify-tools.x86_64 3.14-9.el7
xinetd.x86_64 2:2.3.15-13.el7
本地同步环境信息:
源目录: /root/data/
目的目录:/root/backup/
远程同步环境信息:
源主机(即原始文件所在的服务器)的ip地址:10.40.239.234
目标主机(存放备份文件的服务器)的ip地址:10.40.239.236
源目录: /root/data/
目的目录:/root/backup/
1.3 软件介绍
1.3.1 rsync
rsync是linux系统下的数据镜像备份工具。使用快速增量备份工具Remote Sync可以远程同步,支持本地复制,或者与其他SSH、rsync主机同步。
它有如下特性:
- 可以镜像保存整个目录树和文件系统。
- 可以很容易做到保持原来文件的权限、时间、软硬链接等等。
- 无须特殊权限即可安装。
- 快速:第一次同步时 rsync 会复制全部内容,但在下一次只传输修改过的文件。rsync 在传输数据的过程中可以实行压缩及解压缩操作,因此可以使用更少的带宽。
- 安全:可以使用scp、ssh等方式来传输文件,当然也可以通过直接的socket连接。
支持匿名传输,以方便进行网站镜像。
1.3.2 inotify-tools
inotify-tools 是为linux下inotify文件监控工具提供的一套c的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。inotify-tools提供两种工具,一是inotifywait,它是用来监控文件或目录的变化,二是inotifywatch,它是用来统计文件系统访问的次数。
2 定时同步
定时同步可由rsync和操作定时任务实现。
2.1 本地定时同步
本地定时同步的操作如下:
- 安装 rsync。执行命令:
yum install rsync
- 配置 rsync 参数文件 /etc/rsyncd。执行命令:
vi /etc/rsyncd
输入如下内容:
\# /etc/rsyncd: configuration file for rsync daemon mode
\# See rsyncd.conf man page for more options.
\# configuration example:
uid = nobody
gid = nobody
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
read only = false
list = false
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
- 重启 rsync:
systemctl restart rsync
- 创建同步的定时任务,这里我们设置每5分钟同步一次:
crontab –e “*/5 * * * * rsync -avz --delete /root/data/ /root/backup/”
这里,
rsync -avz --delete /root/data/ /root/backup/
表示从将 /root/data/ 的内容同步到 /root/backup/ 中。其中,
-a 表示归档模式,表示以递归方式传输文件,并保持所有属性;
-v 表示打印详细信息;
-z 表示在传输过程中压缩。
这样就实现了本地计算机上的文件定时同步。
2.2远程定时同步
基于rsync 的远程同步有两种模式,一种是使用远程shell程序(如rsh、ssh)来实现文件同步的方式,一种是使用后台进程(daemon)的模式。
两台服务器的交互方式有两种。一种是源主机主动将文件的差异部分发送给目标主机;另一种是目标主机向源主机请求文件。
2.2.1 shell模式
远程shell方式默认是调用ssh进行文件同步。
2.2.1.1 源主机主动发送文件
- 在目标主机和服务器端都安装rsync:
yum install rsyncd
-
在源主机配置 rsync 参数文件
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
uid = nobody
gid = nobody
use chroot = no
max connections = 200
timeout = 300
port = 873
read only = false
list = false
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 -
在源主机上重启 rsync:
systemctl restart rsync
-
如果要求源主机主动将文件的差异部分发送给目标主机, 那么源主机需要通过免密认证,连接到目标主机。
在源主机生成公钥和私钥,命令如下:
ssh-keygen -t rsa
输入命令后只需要一直点击enter键即可。成功后会出现如图下所示的界面。
如图,私钥的位置在/root/.ssh/id_rsa,公钥的位置在/root/.ssh/id_rsa.pub。
-
打开公钥文件/root/.ssh/id_rsa.pub,复制它的内容。
-
在目标主机中,编辑文件 /root/.ssh/authorized_keys,将源主机公钥的内容粘贴到文件末尾。
-
在目标主机重启ssh:
systemctl restart sshd
- 在源主机验证能否免密登录
如果出现如下的提示信息,表示免密登录成功:
9. 完成免密认证的配置后,在源主机创建定时任务,它是5分钟同步一次的:
crontab –e “*/5 * * * * rsync -avz --delete /root/data/ [email protected]:/root/backup/”
2.2.1.2 目标主机请求文件
- 在目标主机和服务器端都安装rsync:
yum install rsyncd
-
在目标主机配置 rsync 参数文件
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
uid = nobody
gid = nobody
use chroot = no
max connections = 200
timeout = 300
port = 873
read only = false
list = false
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 -
在目标主机上重启 rsync:
systemctl restart rsync
- 目标主机需要通过免密认证连接到源主机。在目标主机生成公钥和私钥,命令如下:
ssh-keygen -t rsa
-
打开公钥文件/root/.ssh/id_rsa.pub,复制它的内容
-
在源主机中,编辑文件 /root/.ssh/authorized_keys,将目标主机的公钥的内容粘贴到文件末尾。
-
在源主机重启ssh:
systemctl restart sshd
- 完成免密认证的配置后,在目标主机创建定时任务,它是5分钟同步一次的
crontab –e “*/5 * * * * rsync -avz --delete [email protected]:/root/data/ /root/backup/”
2.2.2 后台进程模式
CentOS中是以xinetd来管理Rsync服务的,因此我们需要安装 rsync 和 xinetd。
2.2.2.1 目标主机请求文件
-
在源主机和目标主机都安装 rsync:
yum install rsync
并在源主机中安装 xinetd:
yum install xinetd -
安装rsync 和xinetd后,在源主机配置 rsync 参数文件。将相关参数放在一个模块中。下面的例子中,模块名是backup。
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log[backup] #模块名
path = /root/data/
comment = backup
uid = nobody
gid = nobody
use chroot = no
max connections = 200
timeout = 300
port = 873
read only = false
list = false
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
hosts allow = 10.40.239.236/24
secrets file = /etc/rsync.pass
auth users = rsync_user
这里的auth users不需要是操作系统用户。
3. 在源主机创建密码文件 /etc/rsync.pass,写入源主机用户的用户名(即rsyncd.conf中的auth users的一个值)和密码,格式是用户:密码。这里我们创建的内容是:
rsync_user:!QAZ2wsx
- 设置此密码文件的权限,即rsync.pass认证文件是600权限。
chmod 600 /etc/rsync.pass
- 在源主机上重启rsync
systemctl restart rsyncd
-
在源主机上新建或编辑文件 /etc/xinetd.d/rsync,配置rsync相关参数:
# default: off
# description: The rsync server is a good addition to an ftp server, as it
# allows crc checksumming etc.
service rsync
{
disable = no #由默认的yes改为no,设置开机启动rsync
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
} -
重新启动xinetd:
systemctl restart xinetd -
在目标主机上,创建一个密码文件,内容只有密码,和源主机的密码文件中的密码相同。这里,我设置的密码文件的位置是 /etc/rsync.pass,内容是 !QAZ2wsx。并修改其权限:
chmod 600 /etc/rsync.pass -
在目标主机上创建定时任务,它每5分钟从源主机同步一次文件:
crontab –e “*/5 * * * * rsync –avz --delete [email protected]::backup /root/backup/ --password-file=/etc/rsync.pass”
2.2.2.2 源主机主动发送文件
-
在源主机和目标主机都安装 rsync:
yum install rsync
并在目标主机中安装 xinetd:
yum install xinetd -
安装rsync 和xinetd后,在目标主机配置 rsync 参数文件。将相关参数放在一个模块中。下面的例子中,模块名是backup。
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log[backup]
path = /root/backup/
comment = backup
uid = root
gid = root
use chroot = no
max connections = 200
timeout = 300
port = 873
read only = false
list = false
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
hosts allow = 10.40.239.234/24
secrets file = /etc/rsync.pass
auth users = rsync_user
注意:这种方法需要在 /etc/rsyncd.conf 中 将 uid,gid配置为目标主机中备份目录的所属用户和用户组,不能配置为nobody和其他用户。
- 在目标主机创建密码文件/etc/rsync.pass
写入源主机用户的用户名和密码,格式是用户:密码。这里,它的内容是:
rsync_user:!QAZ2wsx
- 设置rsync.pass认证文件的权限为600!
chmod 600 /etc/rsync.pass
- 在目标主机上重启rsync
systemctl restart rsyncd
-
在目标主机新建或编辑 /etc/xinetd.d/rsync,配置rsync相关参数:
# default: off
# description: The rsync server is a good addition to an ftp server, as it
# allows crc checksumming etc.
service rsync
{
disable = no #由默认的yes改为no,设置开机启动rsync
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
} -
在目标主机上重新启动xinetd:
systemctl restart xinetd
- 在源主机上,创建一个密码文件,内容只有密码,和源主机的密码文件中的密码相同。这里,我设置的密码文件的位置是 /etc/rsync.pass,内容是 !QAZ2wsx。并修改其权限,这是必要的:
chmod 600 /etc/rsync.pass
- 在目标主机和源主机关闭防火墙和selinux,这是必要的。
systemctl stop firewalld
setenforce 0
- 在目标主机上创建定时任务,它每5分钟向目标主机发送一次文件:
crontab –e “*/5 * * * * rsync –avz --delete –r /root/data/ [email protected]::backup --password-file= /etc/rsync.pass”
参考
[1] rsync. rsyncd.conf.2018-01-28
[2]百度百科. rsync
[3] 十五十六. rsync搭建部署和配置文件详解. 2018-05-29
[4] wc1695040842. rsync+inotify实时同步文件. 2019-06-03
[5] 王晓冬. Rsync故障排查整理. 2017-03-14
附:Rsyncd.conf 配置参数
模块参数
主要是定义服务器哪个目录要被同步。其格式必须为“[module]”形式,这个名字就是在rsync 客户端看到的名字,其实有点象Samba服务器提供的共享名。而服务器真正同步的数据是通过 path 来指定的。我们可以根据自己的需要,来指定多个模块,模块中可以定义以下参数:
comment
给模块指定一个描述,该描述连同模块名在客户连接得到模块列表时显示给客户。默认没有描述定义。
path
指定该模块的供备份的目录树路径,该参数是必须指定的。
use chroot
如果" use chroot" 指定为true,那么rsync在传输文件以前首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但是缺点是需要以roots权限,并且不能备份指向外部的符号连接所指向的目录文件。默认情况下chroot值为true。
uid
该选项指定当该模块传输文件时,守护进程应该具有的uid,配合gid选项使用可以确定哪些可以访问怎么样的文件权限,默认值是" nobody" 。
gid
该选项指定当该模块传输文件时,守护进程应该具有的gid。默认值为" nobody" 。
max connections
指定该模块的最大并发连接数量以保护服务器,超过限制的连接请求将被告知随后再试。默认值是0,也就是没有限制。
list
该选项设定当客户请求可以使用的模块列表时,该模块是否应该被列出。如果设置该选项为false,可以创建隐藏的模块。默认值是true。
read only
该选项设定是否允许客户上载文件。如果为true那么任何上载请求都会失败,如果为false并且服务器目录读写权限允许那么上载是允许的。默认值为true。
exclude
用来指定多个由空格隔开的多个文件或目录(相对路径),并将其添加到exclude列表中。这等同于在客户端命令中使用–exclude来指定模式,一个模块只能指定一个exclude选项。但是需要注意的一点是该选项有一定的安全性问题,客户很有可能绕过exclude列表,如果希望确保特定的文件不能被访问,那就最好结合uid/gid选项一起使用。
exclude from
指定一个包含exclude模式的定义的文件名,服务器从该文件中读取exclude列表定义。
include
用来指定不排除符合要求的文件或目录。这等同于在客户端命令中使用–include来指定模式,结合include和exclude可以定义复杂的exclude/include规则。
include from
指定一个包含include模式的定义的文件名,服务器从该文件中读取include列表定义。
auth users
该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。这里的用户和系统用户没有任何关系。如果" auth users" 被设置,那么客户端发出对该模块的连接请求以后会被rsync请求challenged进行验证身份这里使用的challenge/response认证协议。用户的名和密码以明文方式存放在" secrets file" 选项指定的文件中。默认情况下无需密码就可以连接模块(也就是匿名方式)。
secrets file
该选项指定一个包含定义用户名:密码对的文件。只有在" auth users" 被定义时,该文件才有作用。文件每行包含一个username:passwd对。一般来说密码最好不要超过8个字符。没有默认的secures file名,需要限式指定一个(例如:/etc/rsyncd.passwd)。注意:该文件的权限一定要是600,否则客户端将不能连接服务器。
strict modes
该选项指定是否监测密码文件的权限,如果该选项值为true那么密码文件只能被rsync服务器运行身份的用户访问,其他任何用户不可以访问该文件。默认值为true。
hosts allow
该选项指定哪些IP的客户允许连接该模块。客户模式定义可以是以下形式:
单个IP地址,例如:192.167.0.1
整个网段,例如:192.168.0.0/24,也可以是192.168.0.0/255.255.255.0
多个IP或网段需要用空格隔开,“*”则表示所有,默认是允许所有主机连接。
hosts deny
指定不允许连接rsync服务器的机器,可以使用hosts allow的定义方式来进行定义。默认是没有hosts deny定义。
ignore errors
指定rsyncd在判断是否运行传输时的删除操作时忽略server上的IO错误,一般来说rsync在出现IO错误时将将跳过–delete操作,以防止因为暂时的资源不足或其它IO错误导致的严重问题。
ignore nonreadable
指定rysnc服务器完全忽略那些用户没有访问权限的文件。这对于在需要备份的目录中有些文件是不应该被备份者得到的情况是有意义的。
lock file
指定支持max connections参数的锁文件,默认值是/var/run/rsyncd.lock。
transfer logging
使rsync服务器使用ftp格式的文件来记录下载和上载操作在自己单独的日志中。
log format
通过该选项用户在使用transfer logging可以自己定制日志文件的字段。其格式是一个包含格式定义符的字符串,可以使用的格式定义符如下所示:
%h 远程主机名
%a 远程IP地址
%l 文件长度字符数
%p 该次rsync会话的进程id
%o 操作类型:" send" 或" recv"
%f 文件名
%P 模块路径
%m 模块名
%t 当前时间
%u 认证的用户名(匿名时是null)
%b 实际传输的字节数
%c 当发送文件时,该字段记录该文件的校验码
默认log格式为:" %o %h [%a] %m (%u) %f %l" ,一般来说,在每行的头上会添加" %t [%p] " 。在源代码中同时发布有一个叫rsyncstats的perl脚本程序来统计这种格式的日志文件。
timeout
通过该选项可以覆盖客户指定的IP超时时间。通过该选项可以确保rsync服务器不会永远等待一个崩溃的客户端。超时单位为秒钟,0表示没有超时定义,这也是默认值。对于匿名rsync服务器来说,一个理想的数字是600。
refuse options
通过该选项可以定义一些不允许客户对该模块使用的命令参数列表。这里必须使用命令全名,而不能是简称。但发生拒绝某个命令的情况时服务器将报告错误信息然后退出。如果要防止使用压缩,应该是:" dont compress = *" 。
dont compress
用来指定那些不进行压缩处理再传输的文件,默认值是*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz