文件共享服务

本文最后更新于:2023年12月5日 晚上

补充知识:iSCSI

概括的说,iSCSI 是一种存储设备远程映射技术,它可以将一个远程服务器上的存储设备映射到本地,并呈现为一个块设备(大白话就是磁盘)。从普通用户的角度,映射过来的磁盘与本地安装的磁盘毫无差异。

这种映射方式基于是基于 SCSI 协议的,SCSI 协议是计算机与外围设备(例如硬盘、光盘等)通信的协议。而 iSCSI 则是通过 TCP 协议对 SCSI 进行封装的一种协议,也就是通过以太网传输 SCSI 协议的内容。

存储类型

存储类型分为三类:

  • 直连式存储:Direct-Attached Storage,简称 DAS

  • 网络附加存储:Network-Attached Storage,简称 NAS

  • 存储区域网络:Storage Area Network,简称 SAN

    FC:Fibre Channel 光纤

三种存储比较

三种存储应用场景

  • DAS 虽然比较古老了,但是还是很适用于那些数据量不大,对磁盘访问速度要求较高的中小企业
  • NAS 多适用于文件服务器,用来存储非结构化数据,虽然受限于以太网的速度,但是部署灵活,成本低
  • SAN 则适用于大型应用或数据库系统,缺点是成本高、较为复杂

FTP 服务

文件传输协议:File Transfer Protocol,基于 C/S 结构

数据传输格式:二进制(默认)和文本

双通道协议:命令和数据传输使用不同的端口

两种模式:从服务器角度命令 主动被动 模式

  • 主动模式:Port Style

    windows 连接 FTP 服务器默认使用主动模式

  • 被动模式:PASV Style

FTP 服务状态码:

1XX:信息   125:数据连接打开
2XX:成功类状态   200:命令OK 230:登录成功
3XX:补充类   331:用户名OK
4XX:客户端错误   425:不能打开数据连接
5XX:服务器错误   530:不能登录

用户认证:

匿名用户:ftp、anonymous,对应Linux用户ftp
系统用户:Linux用户、用户/etc/passwd,密码/etc/shadow
虚拟用户:特定服务的专用用户、独立的用户/密码文件

常见 FTP 相关软件:

  • FTP 服务器端软件

    Wu-ftpd、Proftpd、Pureftpd、Filezilla Server、Serv-U、Wing FTP Server、IIS

    vsftpd:Very Secure FTP Daemon,CentOS 默认 FTP 服务器

  • 客户端软件

    ftp、lftp、lftpget、wget、curl

vsftpd

pureftpd

NFS 服务

工作原理

Network File System:网络文件系统,基于内核的文件系统。通过 NFS,用户和程序可以像访问本地文件一样去访问远端系统上的文件,基于 RPC(Remote Procedure Call Protecol)实现。

上图中的 portmap,自 centos6 之后就被 rpcbind 代替了

优点:节省本地存储空间,将常用的数据,如:/home 目录,存放在 NFS 服务器上且可以通过网络访问,本地终端将可减少自身存储空间的使用

缺点:1. 占用带宽;2. 端口号比较多,而且不固定,防火墙不太好配;所以 nfs 一般不用在互联网,都是用在局域网

nfs 软件介绍

软件包:nfs-utils(包括服务器和客户端相关工具)

相关软件包:rpcbind(必须)、tcp_wrappers

kernel 支持:nfs.ko

端口:2049(nfsd),其他端口由 portmap 分配

nfs 服务主要进程:

  • rpc.nfsd:最主要的 NFS 进程,管理客户端是否可登录
  • rpc.mountd:挂载和卸载 NFS 文件系统,包括权限管理
  • rpc.lockd:非必要,管理文件锁,避免同时写出错
  • rpc.statd:非必要,检查文件一致性,可修复文件

日志:/var/lib/nfs

配置文件:/etc/exports 和 /etc/exports.d/*.exports

nfs 配置文件

/dir host1(opt1,opt2) host2(opt1,opt2)
  • host 格式:支持通配符 *、ipv4、ipv6、FQDN(全域名)、NIS 域的主机组

  • opt 格式:

    默认选项:(ro,sync,root_squash,no_all_squash)
    ro:只读
    rw:可读可写
    async:异步,数据变化后不立即写磁盘,先写入到缓冲区中,过一段时间再写入磁盘,性能高,安全性低
    sync:1.0.0后为默认,同步,数据在请求时立即写入共享存储磁盘,性能低,安全性高
    root_squash:默认,远程root映射为nobody(CentOS7以前的版本为nfsnobody),UID为65534
    no_root_squash:远程root映射成NFS服务器的root用户,squash的意思是压榨
    all_squash:所有远程用户(包括root)都被压榨
    no_all_squash:默认,保留共享文件的UID和GID,即不压榨
    anonuid和anongid:指明匿名用户映射为特定用户UID和组GID,而非nobody,可配合all_squash使用

  默认把root用户压榨成nobody用户,普通用户不压榨,anonuid和anongid可以设置默认压榨成哪个用户

范例:

​```bash
# vim /etc/exports

/data/script 10.0.0.0/24(ro,async)
/data/script 10.0.0.0/24(rw,async,root_squash,anonuid=1000,anongid=1000,all_squash)

/myshare server.example.com
/myshare *.example.com
/myshare server?.example.com
/myshare server[0-20].example.com
/myshare 172.25.11.10
/myshare 172.25.0.0/16
/myshare 2000:472:18:b51:c32:a21
/myshare 2000:472:18:b51::/64
/myshare *.example.com 172.25.0.0/16
/myshare desktop.example.com(ro)
/myshare desktop.example.com(ro) server[0-20].example.com(rw)
/myshare diskless.example.com(rw,no_root_squash)

nfs 工具

fpcinfo

rpcinfo 工具可以查看 RPC 相关信息

# 查看注册在指定主机的RPC程序
rpcinfo -p hostname

# 查看RPC注册程序
rpcinfo -s hostname

范例:

[root@centos8 ~]#rpcinfo -p
[root@centos8 ~]#rpcinfo -s
[root@centos7 ~]#rpcinfo -p 10.0.0.8 # 查看远程主机
[root@centos7 ~]#rpcinfo -s 10.0.0.8

exportfs

用于管理 NFS 导出的文件系统

exportfs [-avi] [-o options,..] [client:/path ..]
exportfs -r [-v]
exportfs [-av] -u [client:/path ..]
exportfs [-v]
exportfs -f
exportfs -s
  • -v:查看本机所有 NFS 共享
  • -r:重读配置文件,这个选项可以避免重启服务
  • -a:输出本机所有共享
  • -au:停止本机所有共享

showmount

常见用法:查看远程主机的 nfs 共享

showmount -e hostname

范例:

[root@centos7 ~]#showmount -e 10.0.0.8
Export list for 10.0.0.8:
/data/wordpress *

monut

客户端 nfs 挂载

mount [-fnrsvw] -t nfs [-o options] device dir

options:

  • nfsvers=n
  • vers=n
  • soft / hard

范例:

自动挂载 autofs

使用 autofs 服务按需要挂载外围设备,NFS 共享等,并在空闲 5 分钟后后自动卸载

配置文件:/etc/auto.master

案例:

10.0.0.1(ubuntu):nfs server,共享/data/wwwroot/script 目录

10.0.0.71(centos):nfs client

# 10.0.0.1
# 安装nfs服务端软件
lujinkai@Z510:~$ sudo apt -y install nfs-kernel-server
# 修改exports共享设置文件
lujinkai@Z510:~$ vim /etc/exports
/data/wwwroot/script 10.0.0.0/24(rw,async,root_squash,anonuid=1000,anongid=1000,all_squash)
# 重新加载配置文件
lujinkai@Z510:~$ sudo exportfs -r

# 10.0.0.71
# 安装autofs,并设置开机自启
[root@c71 ~]$yum -y install autofs
[root@c71 ~]$systemctl enable --now autofs.service
# 查看10.0.0.1共享的目录
[root@c71 ~]$showmount -e 10.0.0.1
Export list for 10.0.0.1:
/data/wwwroot/script 10.0.0.0/24
# 修改auto.master,注意格式,`man auto.master`可以查看格式
[root@c71 ~]$vim /etc/auto.master
...
/root/www /etc/auto.www
# 编辑/root/www指定的配置文件
[root@c71 ~]$vim /etc/auto.www
script -fstype=nfs 10.0.0.1:/home/lujinkai/www/script
# 重启autofs
[root@c71 ~]$systemctl restart autofs.service
# 查看是否挂载成功
[root@c71 ~]$cd ~/www/
[root@c71 www]$ll # 没有任何东西
总用量 0
[root@c71 www]$df -Th ./
文件系统       类型    容量  已用  可用 已用% 挂载点
/etc/auto.www  autofs     0     0     0     - /root/www
[root@c71 www]$cd script # 直接进入,就会自动挂载
[root@c71 script]$ll
总用量 48
-rwxrwxrwx 1 lujinkai lujinkai  688 1113 21:54 demo.sh
drwxrwxrwx 2 lujinkai lujinkai 4096 1112 10:09 etc
drwxrwxrwx 4 lujinkai lujinkai 4096 1112 16:30 include
drwxrwxrwx 2 lujinkai lujinkai 4096 1112 19:34 ini
drwxrwxrwx 2 lujinkai lujinkai 4096 1111 11:08 init.d
-rwxrwxrwx 1 lujinkai lujinkai 3750 1031 20:11 install.sh
-rwxrwxrwx 1 lujinkai lujinkai 2051 1031 15:52 magedu.sh
-rwxrwxrwx 1 lujinkai lujinkai 1462 1028 15:58 scp_list.sh
-rwxrwxrwx 1 lujinkai lujinkai 1744 1111 10:54 scp_sh.sh
-rwxrwxrwx 1 lujinkai lujinkai 1440 1013 21:57 sftp-config.json
drwxrwxrwx 3 lujinkai lujinkai 4096 1111 11:03 src
-rwxrwxr-x 1 lujinkai lujinkai 1211 1111 10:55 u_scp_sh.sh
[root@c71 script]$df -Th ./
文件系统                           类型  容量  已用  可用 已用% 挂载点
10.0.0.1:/home/lujinkai/www/script nfs4  117G   37G   74G   34% /root/www/script

/etc/fstab 和 autofs

/etc/fstab 设置开机自动挂载,系统开机会去读取这个文件,用于挂载本地固定设备,如硬盘

autofs 设置自动挂载,只有当访问挂载点的时候,autofs 才会挂载,过一段时间没有访问,autofs 就会自动卸载设备,用于挂载动态的设备,如光盘、nfs、smb 等文件系统

SAMBA 服务

官网:https://www.samba.org/

相关包:

  • samba 提供 smb 服务器端
  • samba-client 客户端软件
  • samba-common 通用软件
  • cifs-utils smb 客户端工具
  • samba-winbind 和 AD 相关

相关服务进程:

  • smbd 提供 smb(cifs)服务 TCP:139、445
  • nmbd NetBIOS 名称解析 UDP:137、138,如果不使用计算机名来访问,这个就没用

主配置文件:/etc/samba/smb.conf

语法检查: testparm [-v] [/etc/samba/smb.conf]

客户端工具:smbclient、mount.cifs

samba 服务器配置

/etc/samba/smb.conf 是主配置文件,ini 格式,来自 samba-common 包

分为全局配置[global] 和特定的共享设置,例如[homes]、[printers]等\

smb.conf 中的宏定义

%m 客户端主机的NetBIOS名
%M 客户端主机的FQDN
%H 当前用户家目录路径
%U 当前用户的用户名
%g 当前用户所属组
%h samba服务器的主机名
%L samba服务器的NetBIOS名
%I 客户端主机的IP,是i的大写字母
%T 当前日期和时间
%S 可登录的用户名
...

[global] 全局配置

  • workgroup:指定工作组名称

  • server string:主机注释信息

  • netbios name:指定 NetBIOS 名,可以被 SAMBA 客户端使用,但不支持 ping

    注意:netbios name 需要启动 nmb 服务

    范例:

    [global]
    workgroup = workgroup
    netbios name = smbserver # 此设置需要启动nmb服务才可能生效
  • interfaces:指定服务侦听接口和 IP

  • hosts allow: 允许指定主机访问,可用逗号,空格,或 tab 分隔,默认允许所有主机访问,可以在其他共享独立配置,但是[global]中的设置会覆盖其他共享设置,可以是以下格式:

    172.16.0.0/24
    172.16.0.0/255.255.255.0
    desktop.example.com
    .example.com # 以example.com后缀的主机名
  • hosts deny:拒绝指定主机访问,格式和 hosts allow 相同

  • config file=/etc/samba/conf.d/%U:用户独立的配置文件

  • log file=/var/log/samba/log.%I:不同客户机采用不同日志

  • log level = 2:日志级别,默认为 0,不记录日志

    范例:

    [global]
    Log file=/var/log/samba/log.%I
    log level = 2
  • max log size=50:日志文件达到 50K,将轮循 rotate,单位 KB

  • security=user:认证方式,有三种

    • user:samba 用户(采有 linux 用户,samba 的独立口令)
    • share:匿名(CentOS7 不再支持),已不建议使用
    • server:已不建议使用
  • passdb backend = tdbsam:密码数据库格式

特定共享目录配置

[共享名称]    # 远程网络看到的共享名称
comment   # 注释信息
path    # 所共享的目录路径
public   # 能否被guest访问的共享,默认no,和guest=ok 类似
browsable   # 是否允许所有用户浏览此共享,默认为yes,no为隐藏
writable=yes  # 可以被所有用户读写,默认为no
read only=no  # 和writable=yes等价,如与以上设置冲突,放在后面的设置生效,默认只读
write list  # 可读写的用户,可设置为用户或者组,用空格或逗号分隔,用户组有两种格式:@组名、+组名;如果设置writable=no,那write list中的用户和组可读写
valid users  # 规定合法用户,即能访问该共享的用户,用空格或逗号分隔,如为空,将允许所有
force group  # 指定存取资源时须以此设定的群组使用者进入才能存取(用户名/@组名)
force user  # 指定存取资源时须以此设定的使用者进入才能存取(用户名/@组名)

范例:

[share]
path = /data/dir
valid users=wang,@admins
writeable = no
browseable = no

samba 用户管理

smbpasswd 命令

smbpasswd 用于管理 samba 用户

添加用户:实际上是把把系统用户映射为 samba 用户,所以添加的用户首先必须是 linux 系统用户

smbpasswd -a <user>  # 交互式
pdbedit -a -u <user>

修改用户密码:

smbpasswd <user> # 交互式

删除用户和密码:

smbpasswd -x <user>
pdbedit -x -u <user> # 这个好像权限更大

查看 samba 用户列表:

pdbedit -L -v

范例:

# 为了方便配置,可以将用户指定同一个组
[root@c71 ~]$ groupadd -r smb
[root@c71 ~]$useradd -G smb -s /sbin/nologin smb1
[root@c71 ~]$useradd -G smb -s /sbin/nologin smb2

[root@c71 ~]$smbpasswd -a smb1
New SMB password:
Retype new SMB password:
[root@c71 ~]$smbpasswd -a smb2
New SMB password:
Retype new SMB password:
Added user smb2.

[root@c71 ~]$pdbedit -L
smb1:1001:
smb2:1002:
[root@c71 ~]$pdbedit -L -v
---------------
Unix username:        smb1
NT username:
Account Flags:        [U          ]
User SID:             S-1-5-21-540276018-2794668495-3753694806-1000
Primary Group SID:    S-1-5-21-540276018-2794668495-3753694806-513
Full Name:
Home Directory:       \\c71\smb1
HomeDir Drive:
Logon Script:
Profile Path:         \\c71\smb1\profile
Domain:               C71
Account desc:
Workstations:
Munged dial:
Logon time:           0
Logoff time:          Wed, 06 Feb 2036 23:06:39 CST
Kickoff time:         Wed, 06 Feb 2036 23:06:39 CST
Password last set:    Sat, 14 Nov 2020 17:46:18 CST
Password can change:  Sat, 14 Nov 2020 17:46:18 CST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
---------------
Unix username:        smb2
NT username:
Account Flags:        [U          ]
User SID:             S-1-5-21-540276018-2794668495-3753694806-1001
Primary Group SID:    S-1-5-21-540276018-2794668495-3753694806-513
Full Name:
Home Directory:       \\c71\smb2
HomeDir Drive:
Logon Script:
Profile Path:         \\c71\smb2\profile
Domain:               C71
Account desc:
Workstations:
Munged dial:
Logon time:           0
Logoff time:          Wed, 06 Feb 2036 23:06:39 CST
Kickoff time:         Wed, 06 Feb 2036 23:06:39 CST
Password last set:    Sat, 14 Nov 2020 17:46:24 CST
Password can change:  Sat, 14 Nov 2020 17:46:24 CST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

案例

实现不同 samba 用户访问相同的 samba 共享,实现不同的配置

# 10.0.0.71 服务端
[root@c71 ~]$yum -y install samba
[root@c71 ~]$groupadd -r smb
[root@c71 ~]$useradd -G smb -s /sbin/nologin smb1 # 注意这里是-G,而不是-g
[root@c71 ~]$useradd -G smb -s /sbin/nologin smb2
[root@c71 ~]$smbpasswd -a smb1
[root@c71 ~]$smbpasswd -a smb2
[root@c71 ~]$vim /etc/samba/smb.conf
#在workgroup下加一行
config file= /etc/samba/conf.d/%U
[share]
Path=/data/dir
Read only= NO
Guest ok = yes
write list=@wheel
#针对smb1和smb2用户创建单独的配置文件
[root@c71 ~]$vim /etc/samba/smb.conf/smb1
[share]
Path=/data/dir1
Read only= NO      # 等价于writable = yes
Create mask=0644     # 说明:默认为744
[root@c71 ~]$vim /etc/samba/smb.conf/smb2
[share]
path=/data/dir2
Read only= NO
Create mask=0644
# 重启服务
[root@c71 ~]$systemctl restart smb.service

# 10.0.0.72 客户端
# 用户smb1,smb2访问share共享目录,看到目录是不同目录
[root@c72 ~]$yum -y install samba-client cifs-utils
[root@c72 ~]$smbclient //10.0.0.73/share -U smb1%123456
[root@c72 ~]$smbclient //10.0.0.73/share -U smb2%123456

# windows:文件管理器输入 \\10.0.0.73\share 回车,然后输入账号密码即可

数据的实时同步

实现实时同步的方法:

  • inotify + rsync
  • sersync:国人周洋在 inotify 基础上开发的,功能强大,只是已经不再更新了

inotify

异步的文件系统事件监控机制,利用事件驱动机制,而无须通过诸如 cron 等的轮询机制来获取事件,linux 内核从 2.6.13 起支持 inotify,通过 inotify 可以监控文件系统中添加、删除,修改、移动等各种事件

inotify+rsync 使用方式:

  1. 利用监控服务(inotify),监控同步数据服务器目录中信息的变化
  2. 发现目录中数据产生变化,就利用 rsync 服务推送到备份服务器上
  3. 利用脚本进行结合

inotify 内核参数

  • max_queued_events:inotify 事件队列最大长度,如值太小会出现 Event Queue Overflow 错误,默认值:16384, 生产环境建议调大,比如:327679
  • max_user_instances:每个用户创建 inotify 实例最大值,默认值:128
  • max_user_watches:可以监视的文件的总数量(inotifywait 单进程),默认值:8192,建议调大
[root@data-centos8 ~]#vim /etc/sysctl.conf
fs.inotify.max_queued_events=66666
fs.inotify.max_user_watches=100000
[root@centos8 ~]#sysctl
-p
fs.inotify.max_queued_events = 66666
fs.inotify.max_user_watches = 100000
[root@centos8 ~]#cat /proc/sys/fs/inotify/*
66666
128
100000

inotify-tools

[root@c71 ~]$yum -y install inotify-tools

[root@c71 ~]$rpm -ql inotify-tools
# 在被监控的文件或目录上等待特定文件系统事件(open、close、delete等)发生,常用于实时同步的目录监控
/usr/bin/inotifywait
# 收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计
/usr/bin/inotifywatch
...
inotifywait
inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]

# 常用option
-m, --monitor:   始终保持事件监听
-d, --daemon:   以守护进程方式执行,和-m相似,配合-o使用
-r, --recursive:  递归监控目录数据信息变化
-q, --quiet:   输出少量事件信息
--exclude <pattern>: 指定排除文件或目录,使用扩展的正则表达式匹配的模式实现
--excludei <pattern>: 和exclude相似,不区分大小写
-o, --outfile <file>: 打印事件到文件中,相当于标准正确输出,注意:使用绝对路径
-s, --syslogOutput:  发送错误到syslog相当于标准错误输出
--timefmt <fmt>:  指定时间输出格式
--format <fmt>:   指定的输出格式;即实际监控输出内容
-e:      指定监听指定的事件,如果省略,表示所有事件都进行监听

--timefmt "%Y-%m-%d %H:%M:%S"
%Y  # 年份信息,包含世纪信息
%y  # 年份信息,不包括世纪信息
%m  # 显示月份,范围 01-12
%d  # 每月的第几天,范围是 01-31
%H  # 小时信息,使用 24小时制,范围 00-23
%M  # 分钟,范围 00-59
%S  # 秒,范例 0-60

--format "%T %w%f event: %;e"
%T  # 输出时间格式中定义的时间格式信息,通过 --timefmt option 语法格式指定时间信息
%w  # 事件出现时,监控文件或目录的名称信息,相当于dirname
%f  # 事件出现时,将显示监控目录下触发事件的文件或目录信息,否则为空,相当于basename
%e  # 显示发生的事件信息,不同的事件默认用逗号分隔
%Xe # 显示发生的事件信息,不同的事件指定用X进行分隔

-e create,delete,moved_to,close_write,attrib
create    #文件或目录创建
delete    #文件或目录被删除
modify    #文件或目录内容被写入
attrib    #文件或目录属性改变
close_write  #文件或目录关闭,在写入模式打开之后关闭的
close_nowrite  #文件或目录关闭,在只读模式打开之后关闭的
close    #文件或目录关闭,不管读或是写模式
open    #文件或目录被打开
lsdir    #浏览目录内容
moved_to   #文件或目录被移动到监控的目录中
moved_from   #文件或目录从监控的目录中被移动
move    #文件或目录不管移动到或是移出监控目录都触发事件
access    #文件或目录内容被读取
delete_self  #文件或目录被删除,目录本身被删除
unmount   #取消挂载

范例:

# 监控一次性事件
inotifywait /data/www

# 持续前台监控
inotifywait -mrq /data/www --exclude=".*\.swx|\.swp"

# 持续后台监控,并记录日志
inotifywait -o /root/inotify.log -drq /data/www --timefmt "%Y-%m-%d %H:%M:%S" --format "%T %w%f event: %e"

#持续前台监控特定事件
inotifywait -mrq /data/www --timefmt "%F %H:%M:%S" --format "%T %w%f event:%;e" -e create,delete,moved_to,close_write,attrib
inotifywatch
inotifywatch [ options ] file1 [ file2 ] [ ... ]

rsync

rsync 常用做镜像备份和同步数据,配合计划任务实现定时备份,配合 inotify 可以实现触发式的实时数据同步

官方网站: http://rsync.samba.org/

软件包:rsync、rsync-daemon(CentOS 8)

服务文件:/usr/lib/systemd/system/rsyncd.service

配置文件:/etc/rsyncd.conf

端口:873/tcp

# 1. 源地址 和 目标地址 都在本机
rsync [OPTION]... SRC [SRC]... DEST

# 2. 通过远程shell连接
rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST  # pull 推
rsync [OPTION]... [USER@]HOST:SRC [DEST]   # push 拉

# 3. 连接到rsync守护进程
rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST      # pull 推
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST  # pull 推
rsync [OPTION]... [USER@]HOST::SRC [DEST]       # push 拉
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]    # push 拉

The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect to an rsync daemon, and require SRC or DEST to start with a module name.

前两种的本质是通过本地或远程 shell,而第 3 种方式则是让远程主机上运行 rsyncd 服务,使其监听在一个端口上,等待客户端的连接

范例:备份服务器启动 rsync 的守护进程,然后数据服务器去连接,再进行数据的推送和拉取

# 备份服务器 10.0.0.71
[root@c71 ~]$systemctl start rsyncd.service
[root@c71 ~]$ss -ntl
State      Recv-Q Send-Q      Local Address:Port                     Peer Address:Port
LISTEN     0      5                       *:873                                 *:*
LISTEN     0      5                    [::]:873                              [::]:*

[root@c71 ~]$vim /etc/rsyncd.conf
...
[backup]    # bachup 模块
path = /data/backup  # 备份路径
read only = no   # 设置可写,默认只读

# 查看设置的模块
[root@c71 ~]$rsync 127.0.0.1::
backup
[root@c71 ~]$rsync rsync://127.0.0.1
backup

# 默认用户以nobody访问此目录,所以给nobody设置读写权限
[root@c71 ~]$setfacl -m u:nobody:rwx /data/backup/

# 数据服务器 10.0.0.1
lujinkai@Z510:~$ rsync rsync://10.0.0.71
backup
lujinkai@Z510:~$ rsync 10.0.0.71::
backup

# 推送,将本机的u_script目录备份到10.0.0.71的/data/backup目录(rsyncd.conf中backup模块设置)
lujinkai@Z510:~/www$ rsync -av ./u_script/ root@10.0.0.71::backup
lujinkai@Z510:~/www$ rsync 10.0.0.71::backup
drwxrwxr-x          4,096 2020/11/14 22:38:48 .
-rwxrwxr-x            319 2020/11/14 22:38:48 demo.sh
drwxrwxr-x          4,096 2020/11/09 14:52:39 include
# 拉取
lujinkai@Z510:~/www$ rsync -av root@10.0.0.71::backup ./u_script/

rsyncd.conf 的格式 参考 man rsyncd.conf 或者 https://linux.die.net/man/5/rsyncd.conf

上面的过程都是免密的,我们也可以设置认证

# 备份服务器 10.0.0.71
[root@c71 ~]$echo "rsyncuser:123456" > /etc/rsync.pas
[root@c71 ~]$chmod 600 /etc/rsync.pas
[root@c71 ~]$vim /etc/rsyncd.conf
...
[backup]
path = /data/backup
read only = no
auth users = rsyncuser # 默认anonymous可以访问rsync服务器,这里设置只能虚拟用户rsyncuser访问
secrets file = /etc/rsync.pas # 认证文件
...
[root@c71 ~]$systemctl restart rsyncd.service # 也可以不重启

# 数据服务器 10.0.0.1
# 将秘密写入到/etc/rsync.pas,也可以赋值给环境变量 export RSYNC_PASSWORD=123456
lujinkai@Z510:~/www$ echo 123456 > /etc/rsync.pas
# 测试,注意这里一定要指定用户名 rsyncuser
lujinkai@Z510:~/www$ rsync rsyncuser@10.0.0.71::backup
Password:
drwxrwxr-x          4,096 2020/11/14 22:38:48 .
-rwxrwxr-x            319 2020/11/14 22:38:48 demo.sh
drwxrwxr-x          4,096 2020/11/09 14:52:39 include

inotify+rsync+shell 脚本 实现实时数据同步

备份数据库是:10.0.0.71,inotifywait 监控文件变化,rsync 负责同步数据

SRC='/data/www/' #注意最后的/
DEST='rsyncuser@10.0.0.71::backup'
rpm -q rsync &>/dev/null || yum install rsync
inotifywait \
    -mrq \
    --exclude=".*\.swp" \
    --timefmt '%Y-%m-%d %H:%M:%S' \
    --format '%T %w %f' \
    -e create,delete,moved_to,close_write,attrib ${SRC} |
    while read DATE TIME DIR FILE; do
        FILEPATH=${DIR}${FILE}
        rsync \
            -az \
            --delete \
            -password-file=/etc/rsync.pas $SRC $DEST &&
            echo "At ${TIME} on ${DATE}, file $FILEPATH was backuped up via rsync" >>/var/log/changelist.log
    done

sersync 实现实时数据同步

sersync 虽然快 10 年没更新了,但是还是比较好用的

sersync 项目地址: https://code.google.com/archive/p/sersync/
sersync 下载地址: https://code.google.com/archive/p/sersync/downloads

sersync 类似于 inotify,同样用于监控,但它克服了 inotify 的缺点

inotify 最大的不足是会产生重复事件,或者同一个目录下多个文件的操作会产生多个事件,例如,当监控目录中有 5 个文件时,删除目录时会产生 6 个监控事件,从而导致重复调用 rsync 命令。另外比如:vim 文件时,inotify 会监控到临时文件的事件,但这些事件相对于 rsync 来说是不应该被监控的

sersync 优点:

  • c++编写,速度快
  • 对 linux 系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合 rsync 同步的时候,节省了运行时耗和网络资源
  • 配置很简单,其中提供了静态编译好的二进制文件和 xml 配置文件,直接使用即可
  • 使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态
  • 有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步
  • 不仅可以实现实时同步,另外还自带 crontab 功能,只需在 xml 配置文件中开启,即也可以按要求隔一段时间整体同步一次,而无需再额外配置 crontab 功能
  • 可以二次开发

sersync 只有两个文件:

  • 二进制程序文件 sersync2

    lujinkai@Z510:/usr/local/sersync$ ./sersync2 -h
    set the system param
    execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
    sh: 1: cannot create /proc/sys/fs/inotify/max_user_watches: Permission denied
    execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
    sh: 1: cannot create /proc/sys/fs/inotify/max_queued_events: Permission denied
    parse the command param
    _______________________________________________________
    参数-d:启用守护进程模式
    参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍
    c参数-n: 指定开启守护线程的数量,默认为10个
    参数-o:指定配置文件,默认使用confxml.xml文件
    参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块
    参数-m:单独启用其他模块,使用 -m socket 开启socket模块
    参数-m:单独启用其他模块,使用 -m http 开启http模块
    不加-m参数,则默认执行同步程序
    
  • 配置文件 confxml.xml

    lujinkai@Z510:/usr/local/sersync$ vim confxml.xml
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <head version="2.5">
        <host hostip="localhost" port="8008"></host>
        <debug start="false"/>  # 是否开启调试模式
        <fileSystem xfs="false"/>
        <filter start="false"> # 是否开启文件过滤功能
      <exclude expression="(.*)\.svn"></exclude>
      <exclude expression="(.*)\.gz"></exclude>
      <exclude expression="^info/*"></exclude>
      <exclude expression="^static/*"></exclude>
        </filter>
        <inotify> # 监控的事件
      <delete start="true"/>
      <createFolder start="true"/>
      <createFile start="false"/>
      <closeWrite start="true"/>
      <moveFrom start="true"/>
      <moveTo start="true"/>
      <attrib start="false"/>  # 修改此行为true,文件属性变化后也会同步
      <modify start="false"/>
        </inotify>
    
        <sersync> # rsync命令的配置段
     <localpath watch="/opt/tongbu">  # 同步的目录
      # name是远程rsyncd的模块名,如果下面ssh标签开启了start,name则为远程sehll方式运行的目标目录
         <remote ip="127.0.0.1" name="tongbu1"/>
         <!--<remote ip="192.168.8.39" name="tongbu"/>-->
         <!--<remote ip="192.168.8.40" name="tongbu"/>-->
     </localpath>
     <rsync>
         <commonParams params="-artuz"/>  # 指定rsync选项
         <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
         <userDefinedPort start="false" port="874"/><!-- port=874 -->
         <timeout start="false" time="100"/><!-- timeout=100 -->
         <ssh start="false"/> # 默认使用rsync daemon运行rsync命令,true为使用远程shell模式
     </rsync>
     # 错误重传及日志文件路径,默认60分钟
     <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/>
     <crontab start="false" schedule="600"> # 定时,默认600分钟
         <crontabfilter start="false"> # 是否开启定时
      <exclude expression="*.php"></exclude>
      <exclude expression="info/*"></exclude>
         </crontabfilter>
     </crontab>
     <plugin start="false" name="command"/>
        </sersync>
    #####################################以下行不需要修改####################################
        <plugin name="command">
     <param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
     <filter start="false">
         <include expression="(.*)\.php"/>
         <include expression="(.*)\.sh"/>
     </filter>
        </plugin>
    
        <plugin name="socket">
     <localpath watch="/opt/tongbu">
         <deshost ip="192.168.138.20" port="8009"/>
     </localpath>
        </plugin>
        <plugin name="refreshCDN">
     <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
         <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
         <sendurl base="http://pic.xoyo.com/cms"/>
         <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
     </localpath>
        </plugin>
    </head>

基于 rsync daemon 实现 sersync

# 下载
lujinkai@Z510:~/www/script/src$ wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5.4_64bit_binary_stable_final.tar.gz
# 解压,可以看到,sersync只有两个文件:二进制程序文件和xml配置文件
lujinkai@Z510:~/www/script/src$ tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz
lujinkai@Z510:~/www/script/src$ sudo mv GNU-Linux-x86/ /usr/local/sersync
# 添加到环境变量PATH,过程略...
# 修改配置文件
lujinkai@Z510:~/www/script/src$ cd /usr/local/sersync/
lujinkai@Z510:/usr/local/sersync$ vim confxml.xml # 过程略...
# 确认安装rsync客户端工具
lujinkai@Z510:/usr/local/sersync$ apt -y install rsync
# 创建连接rsynd服务器的用户密码文件,并必须修改权限
lujinkai@Z510:~$ echo 123456 > /etc/rsync.pas
lujinkai@Z510:~$ chmod 600 /etc/rsync.pas
# 以后台方式执行同步
lujinkai@Z510:~$ sersync2 -dro /usr/local/sersync/confxml.xml
# 如果同步失败,可以手动执行下面命令,观察过程
lujinkai@Z510:~$ cd /data/www && rsync -artuz -R --delete ./rsyncuser@10.0.0.71::backup --password-file=/etc/rsync.pas >/dev/null 2>&1

# sersync支持多实例,监控多个目录时,只需分别配置不同配置文件,然后使用sersync2指定对应配置文件运行
lujinkai@Z510:~$ sersync2 -rd -o /etc/sersync.d/nginx.xml

基于远程 shell 实现 sersync

# 首先配置ssh基于key的自动验证,过程略...
# 修改配置文件 confxml.xml
<localpath watch="/data/www">
<remote ip="备份服务器IP" name="/data/backup"/> #修改此行指定备份服务器地址和备份目标目录
</localpath>
...
<ssh start="true"/>  # 开启ssh

# 不需要配置/etc/rsync.pas,其他步骤和上面一样

文件共享服务
http://blog.lujinkai.cn/运维/网络文件共享/网络文件共享服务/
作者
像方便面一样的男子
发布于
2020年12月9日
更新于
2023年12月5日
许可协议