Rsyncd 同步服务
阅读原文时间:2023年07月09日阅读:3

目录

在企业服务器架构中,Rsyncd同步服务常用于数据备份,在提及Rsyncd同步服务之前,我们需要了解三种数据备份区别。

三种数据备份

  • 全量备份:对选择的所有文件进行数据备份,若文件存在则覆盖。
  • 增量备份:针对于上一次备份(无论是哪种备份),备份上一次备份后(包含全量备份、差异备份、增量备份),所有发生变化的文件。
  • 差异备份:针对于上一次完全备份,备份上一次的完全备份后发生变化的所有文件。

三种数据备份的比较(转载)

  • 按备份数据量,从多到少排序:

    全量备份->差异备份->增量备份

  • 按数据恢复速度,从快到慢排序:

    全量备份->差异备份->增量备份

不同数据备份类型组合说明(转载)

  • 全量备份和增量备份结合

    以每周数据备份为例,在星期一进行全量备份,在星期二至星期五进行增量备份。如果在星期五数据被破坏了,则你需要还原星期一的完全备份和从星期二至星期五的所有增量备份。这种策略备份数据需要较少的时间,但还原数据使用较多的时间。还原数据的步骤是这样的:先还原周一的完全备份,然后依次还原周二至周四的增量备份。总共 4 次还原过程。

  • 全量备份和差异备份结合(建议使用)

    以每周数据备份计划为例,在星期一进行全量备份,在星期二至星期五进行差异备份。如果在星期五数据被破坏了,则你只需要还原星期一完全的备份和星期四的差异备份。这种策略备份数据需要较多的时间,但还原数据使用较少的时间。还原的步骤:先还原周一的完全备份,然后直接用周四的差异备份导入。共 2 次还原步骤。

本地传输模式(等同命令cp)

# 语法
Local:  rsync [OPTION...] SRC... [DEST]
## 拷贝文件
[root@backup ~]# rsync /root/rsyncfi /usr/local/src/
## 拷贝目录
[root@backup ~]# rsync -a /etc /usr/local/src/

远程传输模式(等同命令scp)

此模式借助SSH的通道进行传输,一般情况下ssh端口为22,且传输时需要注意连接端的连接用户权限

# 语法
Access via remote shell:
Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
## 拉:rsync [选项...] 用户名@主机IP:路径 本地文件或目录

[root@backup ~]# rsync -avz root@172.16.1.7:/etc/hostname /usr/local/games/

Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
## 推:rsync [选项...] 本地文件或目录 用户名@主机IP:路径

[root@backup ~]# rsync -avz /backup/2020-05-06_web01_etc.tar.gz root@10.0.0.7:/tmp/

配置文件 /etc/rsyncd.conf

此处参考转载了此博客内容,以下是常见的配置项,也算是一个配置示例:

[root@backup ]# cat /etc/rsyncd.conf

######### 全局配置参数 ##########
port=888                                      # 指定rsync端口。默认873
uid = rsync                                   # rsync服务的运行用户,默认是nobody,文件传输成功后属主将是这个uid
gid = rsync                                   # rsync服务的运行组,默认是nobody,文件传输成功后属组将是这个gid
use chroot = no                               # rsync daemon在传输前是否切换到指定的path目录下,no 即将其监禁在path目录下
max connections = 200                         # 指定最大连接数量,0表示没有限制
timeout = 300                                 # 确保rsync服务器不会永远等待一个崩溃的客户端,0表示永远等待
motd file = /var/rsyncd/rsync.motd                           # 客户端连接过来显示的消息
pid file = /var/run/rsyncd.pid                               # 指定rsync daemon的pid文件
lock file = /var/run/rsync.lock                              # 指定锁文件
log file = /var/log/rsyncd.log                               # 指定rsync的日志文件,而不把日志发送给syslog
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2   # 指定哪些文件不用进行压缩传输

###########下面指定模块,并设定模块配置参数,可以创建多个模块###########
[longshuai]                                    # 模块ID
path = /longshuai/                             # 指定该模块的路径,该参数必须指定。启动rsync服务前该目录必须存在。rsync请求访问模块本质就是访问该路径。
ignore errors                                  # 忽略某些IO错误信息
read only = false                              # 指定该模块是否可写,即能否上传文件,false表示可读写(可上传),true表示可读不可写(不可上传),所有模块默认为 true,不可上传
write only = false                             # 指定该模式是否可读,即能否支持下载,false表示可读写(可下载),ture表示可写不可读(不可下载),所有模块默认为 false,可下载
list = false                                   # 客户端请求显示模块列表时,该模块是否显示出来,设置为false则该模块为隐藏模块,默认为 true
hosts allow = 10.0.0.0/24                         # 指定允许连接到该模块的机器,多个ip用空格隔开或者设置区间
hosts deny = 0.0.0.0/32                           # 指定不允许连接到该模块的机器
auth users = rsync_backup                         # 指定连接到该模块的用户列表,只有列表里的用户才能连接到模块,用户名和对应密码保存在secrts file中,
                                                  # 这里使用的不是系统用户,而是虚拟用户。不设置时,默认所有用户都能连接,但使用的是匿名连接
secrets file = /etc/rsyncd.passwd                 # 保存 auth users 用户列表的用户名和密码,每行包含一个 auth users:password
                                                  # 由于 strict modes 默认为true,所以此文件要求非rsync daemon用户不可读写。只有启用了auth users该选项才有效。
[xiaofang]                                     # 其他模块ID
path=/xiaofang/
read only = false
ignore errors
comment = anyone can access

守护进程模式

## 语法:
Access via rsync daemon:
Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
## 拉:rsync [-avz] zls_bak@10.0.0.41::[模块] 源文件 目标
rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST](忘记它)

Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
## 推:rsync [-avz] 源文件 zls_bak@10.0.0.41::[模块] 目标
rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST(忘记它)

## 注意:推和拉的区别,就是源文件的位置在哪里,拉:源文件在后面。
## 同时,推 和 拉 都是在客户端的角度操作的,从客户端 推 到服务端, 从服务端 拉 到客户端

## rsync 重要选项
-a                  # 归档模式传输, 等于-tropgDl
-v                  # 详细模式输出, 打印速率, 文件数量等
-z                  # 传输时进行压缩以提高效率
--bwlimit=KBPS      # 限制I/O带宽,KBytes Per Second,默认单位KB/s,也可以指定其他单位
--delete            # 无差异同步,让目标目录和源目录数据保持一致,多余的文件会删除(少的依旧会补充)
--password-file=xxx # 指定密码文件路径

------------------- -a 包含 ------------------
-r                 # 递归传输目录及子目录,即目录下得所有目录都同样传输
-t                 # 保持文件时间信息
-o                 # 保持文件属主信息
-p                 # 保持文件权限
-g                 # 保持文件属组信息
-l                 # 保留软连接
-D                 # 保持设备文件信息
----------------------------------------------

-L                  # 保留软连接指向的目标文件(会取消软链接指向,改变软连接文件属性,变成普通文件)
-e                  # 使用的信道协议
--exclude=PATTERN   # 指定排除不需要传输的文件格式规则(想指定多个格式规则,需要多个 "--exclude" 选项)
--exclude-from=file # 一个"--exclude"选项只能指定一条规则,可以将排除规则写入到文件中,然后使用"--exclude-from"选项读取该规则文件

# rsync 服务端 开启服务
[root@backup ~]# systemctl start rsyncd
# 观察 rsync服务端 配置文件
[root@backup ~]# vi /etc/rsyncd.conf
[root@backup ~]# cat /etc/rsyncd.conf
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[ansibletest]
comment = ansible test
path = /ansible

# 需要创建 rsync 用户及用户组 和  secrets file 和共享存储目录 path=/ansible 并指定其属主和属组为 rsync (省略)

# 客户端
[root@nfs ~]# ll -d /data
drwxr-xr-x 2 www www 21 Jun 10 09:02 /data
[root@nfs ~]# ll /data
total 0
-rw-r--r-- 1 www www 0 Jun 10 09:02 123.txt

# 客户端根据模块推送
[root@nfs ~]# rsync -avz /data rsync_backup@172.16.1.41::ansibletest --password-file=/etc/rsync.password

# 服务端结果(观察属主和属组 为 rsync)
[root@backup ~]# cd /ansible/
[root@backup ansible]# ll
total 0
drwxr-xr-x 2 rsync rsync 21 Jun 10 09:02 data
[root@backup ansible]# ll data/
total 0
-rw-r--r-- 1 rsync rsync 0 Jun 10 09:02 123.txt

# 需要根据 配置文件 创建 服务的执行用户(默认rsync),密码文件(权限 600/700)
# 需要创建 模块指定的 path路径,并指定属主为 服务的执行用户(默认rsync)
# 密码文件内容 格式为 auth user:password

守护进程模式报错

# failed to connect xxxx(IP): No route to host
# connection refused

# 1.网络
[root@web01 ~]# ping 172.16.1.41
# 2.端口
[root@web01 ~]# telnet 172.16.1.41 873
# 3.防火墙
[root@backup ~]# systemctl status firewalld
# 4.selinux
[root@backup ~]# getenforce


# auth failed on xxx(module)

## 服务端排错
# 1.检查配置文件的认证用户
[root@backup ~]# vi /etc/rsyncd.conf
auth user = rsync_backup

# 2.检查配置文件模块名是否正确
[root@backup ~]# vi /etc/rsyncd.conf
[xxx]

# 3.检查密码文件是否存在,不存在需要创建;若存在密码文件,检查 密码文件内容 、密码文件权限(600/700)
[root@backup ~]# cat /etc/rsyncd.conf
secrets file = /etc/rsync.passwd
[root@backup ~]# ll /etc/rsync.passwd
-rw------- 1 root root 17 May  6 19:43 /etc/rsync.passwd
[root@backup ~]# cat /etc/rsync.passwd
rsync_backup:123

## 客户端排错
# 检查 rsync 命令是否指定了密码文件;若存在密码文件,检查 密码文件内容 、密码文件权限(600/700)
[root@nfs ~]# ll /etc/rsync.password
-rw------- 1 root root 4 May  9 12:37 /etc/rsync.password
[root@nfs ~]# cat /etc/rsync.password
123


# invalid uid rsync

# rsync服务 需要用 rsync用户 传输文件
[root@backup ~]# cat /etc/rsyncd.conf
uid = rsync
gid = rsync

# 检查系统中是否有 rsync用户,没有则需要创建
[root@backup ~]# id rsync
[root@backup ~]# useradd rsync -r -s /sbin/nologin -M


# Permission denied

# 检查 服务端配置文件 指定的路径
[root@backup ~]# cat /etc/rsyncd.conf
[backup]
path = /backup

# 需要将 /backup 的属主和属组 指定为 rsync服务 的操作用户,即 rsync
[root@backup ~]# ll /backup/ -d
drwxr-xr-x 2 rsync rsync 140 May  9 15:24 /backup/

守护进程模式的工作流程

  • 执行rsync -avz /etc 172.16.1.41::backup命令
  • 连接 172.16.1.41 服务端,需要 网络畅通,873端口可连接,服务端关闭防火墙和Selinux
  • 检查 认证用户(auth user),模块 参数是否正确匹配;若匹配,则检验密码;密码文件必须为 600/700 权限
  • 检查 服务端是否有 rsyncd 服务 执行传输命令的用户(默认为rsync)
  • 检查 服务端 模块路径的属主和属组,应该制定为 rsyncd 服务 执行传输命令的用户 (默认为rsync)

Rsyncd服务的 客户端web01,客户端web02 每天晚上23:00备份,给etc目录打包,

推送到 backup服务端 的/backup目录下,文件名:2020-05-06_web01_etc.tar.gz 2020-05-06_web02_etc.tar.gz

服务端需求实现

## 服务端backup
# 1.编辑 服务端 配置文件 /etc/rsyncd.conf
[root@backup ]# vim /etc/rsyncd.conf
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false                    # 可写,即可客户端可以上传
list = false
auth users = rsync_backup            # 此用户不需要创建,客户端连接时,作为连接的用户名
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
comment = web01bak and web02bak
path = /backup

# 2.创建好 rsync用户、/backup目录 , 指定 /backup目录的属主和属组
[root@backup ]# useradd rsync -s /sbin/nologin -M
[root@backup ]# mkdir /backup
[root@backup ]# chown rsync.rsync /backup

# 3.编辑密码文件,服务端密码文件需要写成 `auth users:password`,客户端只需要写入 `passord`
[root@backup ]# cat /etc/rsync.passwd
rsync_backup:123
[root@backup ]# chmod 600 /etc/rsync.passwd

# 4.重启服务、开机自启
[root@backup ]# systemctl restart rsyncd
[root@backup ]# systemctl enable rsyncd

# 5.检查端口是否开启
[root@backup ~]# netstat -lntp | grep 873
tcp        0      0 0.0.0.0:873             0.0.0.0:*               LISTEN      10986/rsync
tcp6       0      0 :::873                  :::*                    LISTEN      10986/rsync

客户端需求实现(方式一)

### 方式一,写密码文件,在执行 rsync 命令时,指定密码文件路径(必须是 600/700 权限)
## 客户端web01
# 1.编写一个脚本文件 /scripts/backup.sh
[root@web01 scripts]# pwd
/scripts
[root@web01 scripts]# vim backup.sh
#!/bin/bash
tar zcf $(date +%F)_$(hostname)_etc.tar.gz /etc
rsync -avz $(date +%F)_$(hostname)_etc.tar.gz rsync_backup@10.0.0.41::backup --password-file=/etc/rsync.passwd
rm -rf $(date +%F)_$(hostname)_etc.tar.gz

# 2.编写客户端密码文件,并改变其权限
[root@web01 scripts]# echo 123 > /etc/rsync.passwd
[root@web01 scripts]# chmod 600 /etc/rsync.passwd

# 3.添加定时执行脚本
[root@web01 scripts]# crontab -e
00 23 * * * /bin/bash /scripts/backup.sh &>/dev/null

## 客户端web02
# 1.将脚本文件用 scp/rsync 传输到客户端web02
[root@web01 ~]# scp -r /scripts root@10.0.0.8:/

# 2.编写客户端密码文件,并改变其权限
[root@web02 scripts]# echo 123 > /etc/rsync.passwd
[root@web02 scripts]# chmod 600 /etc/rsync.passwd

# 3.添加定时执行脚本
[root@web02 scripts]# crontab -e
00 23 * * * /bin/bash /scripts/backup.sh &>/dev/null

客户端需求实现(方式二)

### 方式二,不写密码文件,将密码添加到环境变量 RSYNC_PASSWORD
## 客户端web01
# 1.编写一个脚本文件 /scripts/backup.sh
[root@web01 scripts]# pwd
/scripts
[root@web01 scripts]# vim backup.sh
#!/bin/bash
export RSYNC_PASSWORD=123
tar zcf $(date +%F)_$(hostname)_etc.tar.gz /etc
rsync -avz $(date +%F)_$(hostname)_etc.tar.gz rsync_backup@10.0.0.41::backup
rm -rf $(date +%F)_$(hostname)_etc.tar.gz

# 2.添加定时执行脚本
[root@web01 scripts]# crontab -e
00 23 * * * /bin/bash /scripts/backup.sh &>/dev/null

## 客户端web02
# 1.将脚本文件用 scp/rsync 传输到客户端web02
[root@web01 ~]# scp -r /scripts root@10.0.0.8:/

# 2.添加定时执行脚本
[root@web02 scripts]# crontab -e
00 23 * * * /bin/bash /scripts/backup.sh &>/dev/null

Rsync备份案例,使用3台服务器主机名分别为web01、backup 、nfs主机信息见下表

角色

外网IP(WAN)

内网IP(LAN)

主机名

Rsync

eth0:10.0.0.41

eth1:172.16.1.41

backup

NFS

eth0:10.0.0.31

eth1:172.16.1.31

nfs01

WEB

eth0:10.0.0.7

eth1:172.16.1.7

web01

WEB

eth0:10.0.0.8

eth1:172.16.1.8

web02

客户端需求

1.客户端提前准备存放的备份的目录,目录规则如下:/backup/nfs_172.16.1.31_2018-09-02

2.客户端在本地打包备份(系统配置文件、应用配置等)拷贝至/backup/nfs_172.16.1.31_2018-09-02

3.客户端最后将备份的数据进行推送至备份服务器

4.客户端每天凌晨1点定时执行该脚本

5.客户端服务器本地保留最近7天的数据, 避免浪费磁盘空间

服务端需求

1.服务端部署rsync,用于接收客户端推送过来的备份数据

2.服务端需要每天校验客户端推送过来的数据是否完整

3.服务端需要每天校验的结果通知给管理员

4.服务端仅保留6个月的备份数据,其余的全部删除

客户端需求实现

web01客户端

## 编写 web01客户端 脚本文件
[root@web01 ~]# vi rsync_backup.sh
#!/bin/bash
export RSYNC_PASSWORD=123
local_dir="/backup"
hostname="$(hostname)"
date="$(date +%F)"
ip="$(/usr/bin/hostname -I | awk '{print$2}')"
fullbackup_dir="${local_dir}/${hostname}_${ip}_${date}"
fullfilename="${hostname}_${ip}_${date}.tgz"
# 创建备份目录
if [ ! -d $fullbackup_dir ];then
  mkdir -p $fullbackup_dir
  echo "创建备份目录..."
else
  echo "备份目录存在..."
fi
# 打包/etc/passwd文件
cd /etc && \
tar zcf ${fullbackup_dir}/passwd_${fullfilename} ./passwd
# 创建 md5 校验文件,用于服务端校验
md5sum ${fullbackup_dir}/passwd_${fullfilename} > ${fullbackup_dir}/checkfile.txt
# 只保留最近 7 天的备份文件
find /backup/ -type d -name "${hostname}*" ! -mtime -7 | xargs rm -rf
# 将备份文件目录推送到 rsync服务端
rsync -az $fullbackup_dir rsync_backup@172.16.1.41::backup

## 添加定时任务
[root@web01 backup]# crontab -e
# 每天凌晨1点执行推送备份文件
00 01 * * * /bin/bash /root/rsync_backup.sh &>/dev/null

web02客户端/nfs客户端 实现

## 将 web01客户端 的脚本文件远程传输到 web02客户端/nfs客户端
[root@web01 ]# scp /root/rsync_backup.sh root@10.0.0.8:/root/
The authenticity of host '10.0.0.8 (10.0.0.8)' can't be established.
ECDSA key fingerprint is SHA256:WFgahcXxlCAx/kG3fb3EIro7viCM8aLChyV9GpVZgy4.
ECDSA key fingerprint is MD5:c4:a8:54:b4:32:88:3c:c4:2d:98:c0:74:b0:c5:8c:68.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.8' (ECDSA) to the list of known hosts.
root@10.0.0.8's password:
rsync_backup.sh                                                                          100%  712   340.3KB/s   00:00
[root@web01 ]# scp /root/rsync_backup.sh root@10.0.0.31:/root/
root@10.0.0.31's password:
rsync_backup.sh                                                                          100%  712   397.0KB/s   00:00    

## 添加定时任务
[root@web02 ]# crontab -e
# 每天凌晨1点执行推送备份文件
00 01 * * * /bin/bash /root/rsync_backup.sh &>/dev/null

## 添加定时任务
[root@nfs ]# crontab -e
# 每天凌晨1点执行推送备份文件
00 01 * * * /bin/bash /root/rsync_backup.sh &>/dev/null

服务端需求实现

backup服务端

# 1. 安装邮件服务
[root@backup ~]# yum -y install mailx

# 2. 修改邮箱配置文件,添加以下内容
[root@backup ~]# vim /etc/mail.rc
# 发件人
set from=XXX@126.com
# 邮件服务器
set smtp=smtp.126.com
# 发件人用户名
set smtp-auth-user=XXX@126.com
# 发件人密码(授权码,从邮箱设置中获取)
set smtp-auth-password=XXXXXXXX
# 登录方式
set smtp-auth=login

# 3. 编写 backup服务端 脚本文件
[root@backup ~]# vi backup_server.sh
#!/bin/bash
date="$(date +%F)"
# 检查备份文件数据是否完整
find /backup/ -name "checkfile.txt" | xargs md5sum -c | mail -s "${date}_backuprecord" XXX@126.com
# 只保留 180 天的备份文件,以防/backup被删除,更新一下/backup时间戳
touch /backup && \
find /backup/ -type d ! -mtime -180 | xargs rm -rf

# 4. 添加定时任务
[root@backup ~]# crontab -e
00 08 * * * /bin/bash /root/backup_server.sh &>/dev/null

Rsync与inotify结合实现实时同步

# inotifywait命令 的选项和参数

-m             # 持续监控
-r             # 递归
-q            # 静默,仅打印时间信息
--timefmt            # 指定输出时间格式
--format             # 指定事件输出格式
    %Xe             # 事件
    %w          # 目录
    %f          # 文件
-e                    # 指定监控的事件

    access          # 访问
    modify          # 内容修改
    attrib          # 属性修改
    close_write     # 修改真实文件内容
    open            # 打开
    create          # 创建
    delete          # 删除
    umount          # 卸载

# 安装 inotify-tools 软件包(使用 inotifywait命令)
[root@nfs ~]# yum install -y inotify-tools
# 监控 /data目录
[root@nfs ~]# inotifywait -mrq  --format '%Xe  %w  %f' -e create,modify,delete,attrib,close_write /data
# 编写脚本,实现 inotify 与 rsyncd 结合的实时同步
[root@nfs scripts]# vi /scripts/inotify.sh
#!/bin/bash
export RSYNC_PASSWORD=123
dir=/data
/usr/bin/inotifywait  -mrq  --format '%w %f' -e create,modify,delete,attrib,close_write  $dir | while read line;do
  cd  $dir  && rsync -az -R  --delete  .  rsync_backup@172.16.1.41::backup  >/dev/null 2>&1
done  &