Linux 网络服务架设学习笔记(第三期)——文件共享服务(上篇):NFS 与 Rsync——网络文件系统与数据同步
Linux 网络服务架设学习笔记(第三期)——文件共享服务(上篇):NFS 与 Rsync——网络文件系统与数据同步
本系列更多内容可见:Linux常见服务器配置
Linux系统管理入门系列更多文章欢迎访问:
Linux入门——系统管理1、Linux入门——系统管理2
我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~
引言:从“U 盘拷贝”到“网络共享”——让数据在服务器之间“流动”
如果你有多台 Linux 服务器,你可能会遇到这样的场景:Web 服务器需要读取图片服务器上的静态资源;日志服务器需要集中收集所有服务器的日志;备份服务器需要定时从各台服务器拉取数据。如果每次都用 U 盘拷贝或 scp 手动传输,效率低下且容易出错。
Linux 提供了两种经典的解决方案:
- NFS(Network File System):就像把一个文件夹“共享”到网络上,客户端可以像访问本地目录一样远程访问服务器上的文件,适合实时共享访问的场景。
- Rsync(Remote Synchronize):就像一位“智能搬运工”,它能比较源和目的地的文件差异,只传输变化的部分,适合定期备份和同步的场景。
NFS 和 Rsync 的角色不同,但它们共同构成了 Linux 环境下文件共享和数据同步的基础设施。
本期将系统学习:
- NFS 服务器:配置导出目录、客户端挂载、用户映射与权限控制
- Rsync 工具:Shell 模式(通过 SSH)和 Daemon 模式(rsyncd 服务)的同步方案
读完这一期,你将具备在多台 Linux 服务器之间实现文件共享与远程同步的完整能力。
目录
- NFS 网络文件系统
- 1.1 NFS 概述与架构
- 1.2 部署 NFS 服务器
- 1.3 配置 NFS 导出(/etc/exports)
- 1.4 客户端挂载 NFS 共享
- 1.5 用户映射与权限控制
- 1.6 持久化挂载与自动挂载
- Rsync 远程同步工具
- 2.1 Rsync 概述与特点
- 2.2 Shell 模式(基于 SSH)
- 2.3 Daemon 模式(rsyncd 服务)
- 2.4 配置 rsyncd 服务端
- 2.5 客户端同步与密码认证
- 2.6 同步策略:增量、删除与排除
- NFS vs Rsync:选型对比
- 总结与速查手册
1. NFS 网络文件系统
1.1 NFS 概述与架构
NFS(Network File System,网络文件系统)最早由 Sun 公司开发,用于在 UNIX/Linux 系统之间通过网络共享文件和目录。
NFS 的架构是典型的C/S(客户端/服务器)模式:
┌─────────────────┐ ┌─────────────────┐ │ NFS 服务器 │ │ NFS 客户端 │ │ /shares/nfs │ ──────▶ │ /mnt/nfs │ │ 导出目录 │ 网络 │ 挂载点 │ │ 192.168.1.10 │ │ 192.168.1.20 │ └─────────────────┘ └─────────────────┘NFS 依赖RPC(Remote Procedure Call,远程过程调用)协议来通信。RPC 负责将 NFS 服务端的端口信息注册并告知客户端。因此,NFS 服务需要与 RPC 服务协同工作。
💡白话理解:NFS 让远程目录看起来像是本地的目录。你在客户端执行
ls /mnt/nfs,实际上是在访问服务器上的/shares/nfs目录,就像插入了一个网络版的 U 盘。
1.2 部署 NFS 服务器
安装软件包:
[root@server ~]# yum install -y nfs-utils创建共享目录并设置权限:
# 创建共享目录[root@server ~]# mkdir -p /shares/nfs# 为了演示,创建一个测试用户[root@server ~]# useradd -u 1000 whisky[root@server ~]# echo redhat | passwd --stdin whisky# 将目录所有者改为 whisky,方便测试[root@server ~]# chown whisky /shares/nfs启动 NFS 服务:
[root@server ~]# systemctl enable nfs-server --now# 查看服务状态[root@server ~]# systemctl status nfs-server# 查看 RPC 服务注册的端口[root@server ~]# rpcinfo -p | grep nfs1000033tcp2049nfs1000034tcp2049nfs1000033udp2049nfs配置防火墙:
NFS 需要放行多个服务,包括nfs、rpc-bind和mountd:
[root@server ~]# firewall-cmd --permanent --add-service=nfs \--add-service=rpc-bind --add-service=mountd[root@server ~]# firewall-cmd --reload1.3 配置 NFS 导出(/etc/exports)
NFS 通过/etc/exports文件定义哪些目录可以被哪些客户端访问,以及访问权限。
基本语法:
<导出目录> <客户端1>(选项1,选项2) <客户端2>(选项3,选项4)客户端表示方式:
| 方式 | 示例 | 说明 |
|---|---|---|
| 主机名 | client.whisky.cloud | 通过 DNS 解析 |
| 通配符域名 | *.whisky.cloud | 匹配域内所有主机 |
| IPv4 地址 | 10.1.8.11 | 单个 IP |
| IPv4 网段 | 10.1.8.0/24 | 网段内所有主机 |
| IPv6 地址/网段 | fde2:6494:1e09:2::20 | 单个或网段 |
常用导出选项:
| 选项 | 含义 |
|---|---|
rw | 允许读写访问 |
ro | 只读访问(默认) |
no_root_squash | 客户端 root 用户保持 root 权限(不安全) |
root_squash | 客户端 root 用户映射为nobody(默认,推荐) |
sync | 同步写入(数据写入磁盘后返回) |
async | 异步写入(性能更高,但数据可能丢失) |
编辑/etc/exports:
[root@server ~]# vim /etc/exports/shares/nfs10.1.8.0/24(rw)使配置生效:
修改/etc/exports后,使用exportfs命令重新加载:
# 重新加载所有导出[root@server ~]# exportfs -r# 查看当前导出状态[root@server ~]# exportfs -v/shares/nfs10.1.8.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)1.4 客户端挂载 NFS 共享
客户端安装软件包:
[root@client ~]# yum install -y nfs-utils查看服务器导出的共享:
[root@client ~]# showmount -e server.whisky.cloudExport listforserver.whisky.cloud: /shares/nfs10.1.8.0/24挂载 NFS 共享:
# 创建挂载点[root@client ~]# mkdir /mnt/nfs# 挂载 NFS(-t nfs 可省略)[root@client ~]# mount -t nfs server.whisky.cloud:/shares/nfs /mnt/nfs# 验证挂载[root@client ~]# df -h /mnt/nfsFilesystem Size Used Avail Use% Mounted on server.whisky.cloud:/shares/nfs 20G1.2G 19G6% /mnt/nfs测试读写:
# 以 root 用户尝试写入(默认 root_squash,会被映射为 nobody)[root@client ~]# touch /mnt/nfs/root-filetouch: cannottouch'/mnt/nfs/root-file':Permission denied# 以 whisky 用户写入(UID 1000 匹配)[whisky@client ~]$touch/mnt/nfs/whisky-file[whisky@client ~]$ls-l/mnt/nfs -rw-rw-r--1whisky whisky0Aug514:30 whisky-file1.5 用户映射与权限控制
NFS 的权限基于UID/GID进行映射,而不是用户名。
| 场景 | 行为 |
|---|---|
| 客户端 UID 与服务器端 UID 相同 | 以对应用户身份访问(如 whisky 可以读写) |
| 客户端 root(UID=0) | 默认被映射为nobody(root_squash) |
| 客户端 UID 在服务器端不存在 | 显示为数字 UID(如uid=1005) |
解决用户映射不一致的方法:
- 保持 UID 一致:在所有客户端和服务器上使用相同的 UID(如
useradd -u 1000 whisky) - 使用
no_root_squash(不推荐):允许客户端 root 拥有 root 权限 - 使用 NFS v4 的
idmapd:将用户名映射到 UID(需配置)
⚠️生产环境警告:除非绝对必要,不要使用
no_root_squash,这会让客户端 root 用户在 NFS 共享上拥有完全控制权,存在严重安全风险。
1.6 持久化挂载与自动挂载
在/etc/fstab中添加条目:
[root@client ~]# echo 'server.whisky.cloud:/shares/nfs /mnt/nfs nfs defaults 0 0' >> /etc/fstab# 测试挂载[root@client ~]# mount -a/etc/fstabNFS 挂载常用选项:
| 选项 | 含义 |
|---|---|
defaults | 使用默认选项 |
rw/ro | 读写/只读 |
_netdev | 网络可用后再挂载(推荐) |
bg | 后台重试(如果服务器暂时不可用) |
timeo=60 | 超时时间(秒) |
retrans=3 | 重传次数 |
2. Rsync 远程同步工具
2.1 Rsync 概述与特点
Rsync(Remote Synchronize)是一款开源的、快速的、多功能的远程数据同步备份工具。
核心优势:
| 特性 | 说明 |
|---|---|
| 增量同步 | 只传输文件的变化部分(“quick check”算法),而非完整文件 |
| 高效压缩 | 支持在传输过程中压缩数据,节省带宽 |
| 灵活传输 | 既支持本地同步,也支持远程同步(通过 SSH 或 rsync 服务) |
| 保留属性 | 可保留文件权限、时间戳、所有者、ACL 等 |
| 删除同步 | 支持--delete,使目标与源完全一致 |
Rsync 的“quick check”算法:
Rsync 默认仅同步大小或最后修改时间发生变化的文件。它不会逐字节比较文件内容,而是通过元数据快速判断是否需要传输。
源文件 → 比较大小和 mtime → 目标文件 ├─ 相同 → 跳过 └─ 不同 → 传输变更部分2.2 Shell 模式(基于 SSH)
Rsync 的shell 模式基于 SSH 协议传输数据,无需额外配置服务端。
基本语法:
# 推(从本地上传到远程)rsync[选项]源路径[user@]host:目标路径# 拉(从远程下载到本地)rsync[选项][user@]host:源路径 目标路径常用选项:
| 选项 | 含义 |
|---|---|
-a | 归档模式(保留权限、时间戳、所有者等) |
-v | 显示详细过程 |
-z | 传输时压缩 |
-n | 空运行(dry-run,仅显示将要执行的操作) |
-P | 显示进度 + 支持断点续传 |
--delete | 删除目标中源没有的文件 |
--exclude | 排除特定文件或目录 |
实战示例:
# 在客户端和服务端都要安装 rsync[root@client ~]# yum install -y rsync[root@server ~]# yum install -y rsync# 准备测试数据[whisky@client ~]$mkdirbackup[whisky@client ~]$touchbackup/file-{1..5}[whisky@client ~]$echo"hello">backup/file-1# 首次同步(推)[whisky@client ~]$rsync-avbackup/ root@server.whisky.cloud:/backup/ sending incrementalfilelist ./ file-1 file-2 file-3 file-4 file-5 sent344bytes received115bytes918.00bytes/sec total size is5speedup is0.01# 再次同步(无变化)[whisky@client ~]$rsync-avbackup/ root@server:/backup/ sending incrementalfilelist sent142bytes received17bytes318.00bytes/sec total size is5speedup is0.03# 修改文件后同步(只传输变化的文件)[whisky@client ~]$touchbackup/file-1[whisky@client ~]$rsync-avbackup/ root@server:/backup/ sending incrementalfilelist file-1 sent232bytes received55bytes574.00bytes/sec total size is5speedup is0.02路径末尾斜杠的陷阱:
| 写法 | 行为 |
|---|---|
rsync -av backup/ root@host:/dest/ | 只复制目录内容到/dest/ |
rsync -av backup root@host:/dest/ | 复制目录本身到/dest/backup |
💡建议:使用
rsync -av source/ dest/时,注意末尾斜杠决定了是否包含目录本身。
2.3 Daemon 模式(rsyncd 服务)
Daemon 模式需要配置 rsync 服务端(rsyncd),客户端通过 rsync 协议(端口 873)连接,无需 SSH 支持。
适用场景:
- 不需要 SSH 密钥或密码(客户端可使用密码文件)
- 可精细控制每个模块的读写权限、IP 限制
- 适合大规模备份和自动化同步
2.4 配置 rsyncd 服务端
安装 rsync-daemon(CentOS 7 中需要安装rsync-daemon子包):
[root@server ~]# yum install -y rsync-daemon配置文件/etc/rsyncd.conf:
该文件分为全局配置和模块配置两部分。
[root@server ~]# vim /etc/rsyncd.conf# 全局配置port=873uid=root gid=root usechroot=no max connections=200pidfile=/var/run/rsyncd.pid lockfile=/var/run/rsync.lock logfile=/var/log/rsyncd.log# 模块配置:data[data]comment=public data path=/datareadonly=no hosts allow=10.1.8.0/24 hosts deny=0.0.0.0/32 authusers=rsyncsecretsfile=/etc/rsyncd.secrets参数说明:
| 参数 | 作用 |
|---|---|
path | 共享目录的路径 |
read only | 只读(yes)或可读写(no) |
write only | 只允许上传(yes)或允许下载 |
hosts allow | 允许访问的客户端 IP 网段 |
auth users | 认证用户名(多个用逗号分隔) |
secrets file | 密码文件路径(格式:用户名:密码) |
list | 是否显示在模块列表中(默认 true) |
ignore errors | 忽略 I/O 错误继续同步 |
timeout | 连接超时时间(秒) |
创建密码文件:
[root@server ~]# echo 'rsync:redhat' > /etc/rsyncd.secrets[root@server ~]# chmod 400 /etc/rsyncd.secrets准备共享目录:
[root@server ~]# mkdir -p /data[root@server ~]# chmod 777 /data启动服务:
[root@server ~]# systemctl enable rsyncd --now# 查看端口监听[root@server ~]# ss -lntp | grep 873LISTEN05*:873 *:* users:(("rsync",pid=1234,fd=4))# 防火墙放行[root@server ~]# firewall-cmd --add-service=rsyncd --permanent[root@server ~]# firewall-cmd --reload2.5 客户端同步与密码认证
查看服务端模块列表:
[root@client ~]# rsync server.whisky.cloud::data public data查看特定模块内容:
[root@client ~]# rsync server.whisky.cloud::data/上传文件到服务端:
# 交互式输入密码[root@client ~]# rsync -av backup/ rsync@server.whisky.cloud::data/Password:`redhat`sending incrementalfilelist ./ file-1... sent344bytes received115bytes918.00bytes/sec使用密码文件(非交互):
# 创建客户端密码文件[root@client ~]# echo 'redhat' > /etc/rsyncd.secrets[root@client ~]# chmod 400 /etc/rsyncd.secrets# 使用 --password-file 选项[root@client ~]# rsync -av --password-file=/etc/rsyncd.secrets \backup/ rsync@server.whisky.cloud::data/从服务端下载文件:
[root@client ~]# rsync -av --password-file=/etc/rsyncd.secrets \rsync@server.whisky.cloud::data/file-1 ./downloaded-file-1同步删除(使目标与源完全一致):
# 客户端删除本地文件后,同步到服务端[whisky@client backup]$rm-ffile-2# 不加 --delete:服务端仍保留 file-2[whisky@client backup]$rsync-av./ rsync@server::data/# 加 --delete:服务端也会删除 file-2(与源保持一致)[whisky@client backup]$rsync-av--delete./ rsync@server::data/ deleting file-22.6 同步策略:增量、删除与排除
| 场景 | 命令示例 |
|---|---|
| 增量备份(保留旧文件) | rsync -av source/ dest/ |
| 完全镜像(删除多余文件) | rsync -av --delete source/ dest/ |
| 排除特定文件 | rsync -av --exclude='*.log' source/ dest/ |
| 排除多个文件 | rsync -av --exclude={'*.log','tmp/'} source/ dest/ |
| 空运行测试 | rsync -avn --delete source/ dest/ |
| 限速传输 | rsync -av --bwlimit=1000 source/ dest/(限制 1000 KB/s) |
| 保留 ACL 和 SELinux 属性 | rsync -avAX source/ dest/ |
排除文件示例:
# 同步 /var/www 但排除 logs 目录和 .tmp 文件[root@client ~]# rsync -av --exclude='logs/' --exclude='*.tmp' \/var/www/ root@server:/backup/www/3. NFS vs Rsync:选型对比
| 维度 | NFS | Rsync |
|---|---|---|
| 使用场景 | 实时共享访问 | 定期同步备份 |
| 文件访问方式 | 客户端像本地目录一样读写 | 通过命令手动或定时同步 |
| 传输方式 | 内核级 RPC 通信 | 用户态(SSH 或 rsync 协议) |
| 增量传输 | ❌ 每次读写都是完整 I/O | ✅ 只传输变化部分 |
| 保留属性 | 需 UID 一致 | 可保留属主、权限、时间戳 |
| 双向同步 | 两端均可读写(需配置) | 单向同步(源→目标) |
| 网络依赖 | 持续连接(类似本地文件系统) | 连接仅在同步时建立 |
| 适用场景 | Web 共享存储、NFS 家目录 | 数据备份、日志归档、镜像站点 |
💡选型建议:
- 需要实时访问远程文件(如 Web 服务器共享图片目录)→NFS
- 需要定时备份或同步数据(如每天凌晨备份数据库)→Rsync
- 两者也可组合使用:NFS 提供实时共享,Rsync 用于备份 NFS 中的数据
4. 总结与速查手册
4.1 核心知识点一览
| 主题 | 关键点 |
|---|---|
| NFS 概念 | 基于 RPC 的网络文件系统,实现远程目录挂载 |
| NFS 服务端 | nfs-utils、/etc/exports、exportfs -r |
| NFS 客户端 | showmount -e查看导出,mount -t nfs挂载 |
| NFS 权限 | 基于 UID 映射,root_squash默认将 root 映射为 nobody |
| Rsync 特点 | 增量同步(quick check),支持 SSH 和 daemon 模式 |
| Rsync Shell 模式 | rsync -av source/ user@host:/dest/ |
| Rsync Daemon 模式 | /etc/rsyncd.conf,认证用户+密码文件,端口 873 |
| 同步策略 | --delete完全镜像,--exclude排除文件 |
4.2 NFS 命令速查表
| 命令 | 作用 |
|---|---|
exportfs -r | 重新加载/etc/exports |
exportfs -v | 查看当前导出的目录及选项 |
showmount -e host | 查看服务器导出的共享 |
mount -t nfs host:/path /local | 挂载 NFS 共享 |
umount /local | 卸载 NFS 共享 |
rpcinfo -p | 查看 RPC 服务注册信息 |
systemctl status nfs-server | 查看 NFS 服务状态 |
4.3 Rsync 命令速查表
| 命令 | 作用 |
|---|---|
rsync -av source/ dest/ | 本地/远程同步(增量) |
rsync -avn source/ dest/ | 空运行,预览操作 |
rsync -av --delete source/ dest/ | 完全镜像(删除多余文件) |
rsync -av --exclude='*.log' source/ dest/ | 排除日志文件 |
rsync -avz source/ user@host:/dest/ | 压缩传输 |
rsync host::module | 查看 daemon 模块列表 |
rsync user@host::module/ | 列出模块内容 |
rsync -av --password-file=passfile source/ user@host::module/ | 使用密码文件同步 |
4.4/etc/exports选项速查
| 选项 | 含义 | 推荐 |
|---|---|---|
rw/ro | 读写/只读 | rw(按需) |
root_squash/no_root_squash | root 映射为 nobody / 保持 root | root_squash✅ |
sync/async | 同步/异步写入 | sync(安全) |
no_subtree_check | 不检查子目录(提高性能) | ✅ 建议加 |
all_squash | 所有用户映射为 nobody | 高安全场景 |
推荐配置:
/shares/nfs 10.1.8.0/24(rw,sync,root_squash,no_subtree_check)4.5/etc/rsyncd.conf配置速查
| 参数 | 作用 |
|---|---|
port | 监听端口(默认 873) |
uid/gid | 访问目录时使用的身份 |
path | 共享目录路径 |
read only | 只读/读写 |
auth users | 认证用户名 |
secrets file | 密码文件(权限 400) |
hosts allow | 允许的 IP 网段 |
4.6 常见错误排查
| 错误 | 原因 | 解决方案 |
|---|---|---|
mount.nfs: access denied | 客户端不在exports允许列表中 | 修改/etc/exports,exportfs -r |
mount.nfs: Permission denied | root_squash 导致 | 使用非 root 用户访问,或使用no_root_squash(慎用) |
rsync: connection refused | rsyncd 未启动或防火墙拦截 | 启动rsyncd,放行 873 端口 |
@ERROR: auth failed on module | 用户名或密码错误 | 检查auth users和secrets file |
rsync: ERROR: cannot read password file | 密码文件权限过松 | chmod 400密码文件 |
| NFS 挂载卡住/超时 | NFS 服务器不可达或 RPC 服务问题 | 检查网络和rpcinfo -p |
| Rsync 同步时文件属主丢失 | 非 root 运行 rsync | 使用 root 权限或确保 UID 一致 |
4.7 思考与拓展
- NFS 导出目录时,为什么推荐使用
root_squash?
→ 防止客户端 root 用户获得共享目录的完全控制权,减少安全风险。如果确实需要 root 权限,应使用no_root_squash但需评估安全后果。 - Rsync 的
--delete选项有什么风险?
→ 如果源目录意外删除了重要文件,同步后目标也会被删除。建议先使用-n(dry-run)预览操作,确认无误后再执行。 - NFS 和 Rsync 在性能上有什么区别?
→ NFS 是实时文件访问,每次操作都涉及网络 I/O,适合少量但高频的读写;Rsync 是批量同步,只传输变化部分,适合大量数据的周期性传输。 - Rsync 的 shell 模式和 daemon 模式分别适用什么场景?
→ shell 模式基于 SSH,适合小规模、临时同步;daemon 模式适合大规模、自动化备份场景,可配置认证、IP 限制和独立日志。
4.8 生产环境最佳实践
| 场景 | 建议 |
|---|---|
| NFS 共享目录 | 使用sync保证数据一致性;root_squash必须保留 |
| NFS 性能优化 | 在/etc/fstab中添加noatime选项,减少访问时间更新 |
| Rsync 备份脚本 | 加入--delete前先做-n试运行,确认无误后再正式执行 |
| Rsync 密码管理 | 密码文件权限设为 400,并存储在安全目录 |
| 定时同步 | 使用crontab定时执行 Rsync,如0 2 * * * rsync -av /data/ user@backup:/backup/ |
| NFS 高可用 | 配合 Keepalived 或 DRBD 实现 NFS 服务的高可用 |
下期预告:NFS 和 Rsync 解决了 Linux 系统间的文件共享和同步问题,但如果你的网络中有 Windows 客户端呢?或者你需要更复杂的用户权限控制?下一期我们将学习SMB(Samba)服务器——让 Linux 与 Windows 无缝共享文件,以及VSFTPD——一款安全、高效的 FTP 服务器。敬请期待第四期!