📦

NFS 共享存储完全实战手册

手把手部署 NFS 服务端与客户端 / 真实排错全记录 / 用户压缩 / 生产优化
Linux 运维 NFS 共享存储 实战笔记
目录导航
  1. 为什么需要共享存储
  2. NFS 工作原理
  3. 服务端部署(192.168.2.100)
  4. 客户端部署(192.168.2.101)
  5. 排错实录:mount.nfs: No route to host
  6. 客户端永久挂载
  7. 服务端核心配置详解
  8. 用户压缩机制与实战案例
  9. 生产环境安全优化
01

为什么需要共享存储

当网站从单台服务器扩展到多台 Web 节点时,一个现实问题就出现了:用户上传了一张图片,请求落在了 Web-A 上,文件存到了 Web-A 的本地磁盘。下一次请求被负载均衡分到了 Web-B,Web-B 上根本没有这张图片,用户看到的就是一个裂图。

共享存储的目标很简单:让多台服务器像访问本地目录一样,共同读写同一份文件。

NFS(Network File System)就是 Linux 下最经典的共享存储方案。它通过网络把服务端的某个目录「挂载」到客户端的本地路径,对上层应用完全透明,就像操作本地磁盘一样。

02

NFS 工作原理

NFS 依赖 RPC(Remote Procedure Call) 机制工作。NFS 服务启动时会随机分配端口,然后向 RPC 服务(rpcbind)注册自己的端口信息。客户端要访问 NFS 时,先问 rpcbind 拿到端口号,再建立连接传输数据。

简单理解 rpcbind 相当于「前台」,负责告诉客户端「NFS 在几号房间」。NFS 是「后台服务员」,真正干活。所以 rpcbind 必须先于 NFS 启动

NFS 相关文件一览

文件路径角色说明
/etc/exports服务端NFS 主配置文件,定义共享目录和权限
/var/lib/nfs/etab服务端当前运行时生效的完整配置
/etc/fstab客户端永久挂载配置
/etc/rc.local客户端开机自动执行的命令
/proc/mounts通用系统当前实际挂载情况

NFS 的 systemctl 命令背后实际调用的是 exportfs 命令。启动时执行 exportfs -r 加载配置,停止时执行 exportfs -au 卸载所有共享。

03

服务端部署(192.168.2.100)

部署总览

安装软件包 准备目录 修改权限 编辑 exports 启动 RPC 启动 NFS 本地验证
1

安装 rpcbind 和 nfs-utils

bash
yum install -y rpcbind nfs-utils

rpcbind 提供 RPC 端口映射服务,nfs-utils 是 NFS 核心工具集合。

2

创建共享目录并设置权限

bash
# 创建共享目录
mkdir -p /data/

# 设置目录所有者为 nfsnobody
chown -R nfsnobody.nfsnobody /data/
3

编辑配置文件 /etc/exports

/etc/exports
/data/ 192.168.2.0/24(rw)

配置含义:允许 192.168.2.0/24 整个网段以读写权限访问服务端的 /data/ 目录。

4

按顺序启动服务

bash
# 先启动 rpcbind
systemctl enable rpcbind
systemctl start  rpcbind
rpcinfo -p

# 再启动 NFS
systemctl enable nfs
systemctl start  nfs
rpcinfo -p
5

服务端本地测试

bash
# 本地挂载测试
mount -t nfs 192.168.2.100:/data/ /mnt/
reload vs restart 修改 /etc/exports 后,建议使用 systemctl reload nfs 重新加载配置。reload 是优雅重启,不会断开已有客户端连接。而 restart 会导致客户端出现短暂的夯住(卡顿无响应)。
04

客户端部署(192.168.2.101)

客户端只需要安装 nfs-utils,不需要启动 NFS 服务。

bash
# 安装工具包
yum install -y nfs-utils

# 挂载 NFS 共享目录到本地 /mnt
mount -t nfs 192.168.2.100:/data /mnt

挂载成功后,可以通过以下命令确认:

bash
[root@web ~]# grep /mnt /proc/mounts
192.168.2.100:/data /mnt nfs4 rw,relatime,vers=4.1,rsize=262144,
wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,
clientaddr=192.168.2.101,local_lock=none,addr=192.168.2.100 0 0

此时在客户端 /mnt 下读写文件,数据实际存储在服务端 192.168.2.100/data/ 磁盘上。

05

排错实录:mount.nfs: No route to host

在客户端执行挂载命令时,直接报错:

error
[root@web ~]# mount -t nfs 192.168.2.100:/data /mnt
mount.nfs: No route to host

以下是完整的排查过程:

1

第一步:ping 测网络连通性

bash
[root@web ~]# ping 192.168.2.100
64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=0.556 ms
64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.573 ms
64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.501 ms
✓ 能 ping 通,网络层没问题
2

第二步:nc 测端口连通性

bash
[root@web ~]# nc -zv 192.168.2.100 2049
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: No route to host.

✗ 能 ping 通但端口不通 → 高度怀疑防火墙拦截
3

第三步:关闭客户端防火墙

bash
[root@web ~]# systemctl stop    firewalld
[root@web ~]# systemctl disable firewalld
Removed symlink ...firewalld.service

# 关闭后再测 → 仍然不通
[root@web ~]# nc -zv 192.168.2.100 2049
Ncat: No route to host.

客户端防火墙关了还是不通,说明问题在服务端

4

第四步:关闭服务端防火墙

bash
[root@nfs ~]# systemctl stop    firewalld
[root@nfs ~]# systemctl disable firewalld
Removed symlink ...firewalld.service
5

第五步:验证通过

bash
# 端口通了
[root@web ~]# nc -zv 192.168.2.100 2049
Ncat: Connected to 192.168.2.100:2049.

# 挂载成功
[root@web ~]# mount -t nfs 192.168.2.100:/data /mnt
[root@web ~]# 
生产环境注意 直接关防火墙只适合测试环境。生产环境应使用 firewall-cmd --add-service=nfs --permanent 放行 NFS 服务,或针对 111、2049 端口配置白名单。

排错工具速查

命令用途
rpcinfo -p IP检查目标主机的 RPC 注册信息,确认 NFS 是否已注册
showmount -e IP查看 NFS 服务端共享了哪些目录
cat /proc/mounts查看当前系统的真实挂载情况
nc -zv IP 2049测试 NFS 端口连通性
06

客户端永久挂载

直接执行 mount 是临时挂载,服务器重启后就会丢失。要实现开机自动挂载,有两种方式:

方式一:写入 /etc/rc.local

bash
# 先确保 rc.local 有执行权限
chmod +x /etc/rc.d/rc.local

# 追加挂载命令
echo "mount -t nfs 192.168.2.100:/data /mnt" >> /etc/rc.local

方式二:写入 /etc/fstab(推荐)

bash
# 创建挂载点
[root@web ~]# mkdir /upload/

# 编辑 fstab
[root@web ~]# vi /etc/fstab

# 在文件末尾添加以下内容,保存退出(:wq)

fstab 格式说明:

设备挂载点文件系统挂载参数是否备份是否检查
192.168.2.100:/data/ /upload/ nfs defaults 0 0
重要提醒 配置了 NFS 永久挂载后,客户端开机时会尝试连接 NFS 服务端。如果服务端还没启动,客户端会一直等待、卡在挂载阶段无法进入系统,df -h 也会夯住。此时可通过 /proc/mounts 排查失败挂载。

所以请记住:配了永久挂载,未来开机要优先启动 NFS 服务端。
07

服务端核心配置详解

配置文件格式

/etc/exports 每行定义一条共享规则,格式为:

/etc/exports
# 共享目录    网段(选项1,选项2,...)
/data/       192.168.2.0/24(rw,sync)

核心选项

选项说明
rw读写权限,客户端可以读取和写入
ro只读权限(read only),客户端只能读取
sync同步模式。用户上传数据后,NFS 立即写入磁盘,数据安全但性能稍低
async异步模式。数据先缓存在内存中,过一段时间再写入磁盘。高并发性能好,但突然断电可能丢数据
08

用户压缩机制与实战案例

NFS 客户端挂载共享目录后,客户端用户在目录中创建文件,这个文件在服务端上属于谁?这就是用户压缩(Squash)要解决的问题。

简单说:客户端用户 → 经过 NFS 映射 → 变成服务端上的某个用户。默认情况下,客户端 root 用户会被「压缩」为服务端的 nfsnobody 用户。

用户压缩选项

选项说明
root_squash客户端 root 到服务端变成 nfsnobody(默认开启
no_all_squash客户端非 root 用户保持原始身份不压缩(默认开启
all_squash所有用户都压缩为匿名用户
anonuid指定匿名用户的 UID(默认 65534 即 nfsnobody)
anongid指定匿名用户的 GID(默认 65534 即 nfsnobody)
默认映射关系 客户端 root → 服务端 nfsnobody
客户端普通用户 → 服务端保持原用户(前提是服务端存在相同 UID 的用户)

实战案例:自定义匿名用户 whqzn

需求:新建 /nfsdata 共享目录,所有客户端用户创建的文件都归属 whqzn 用户(UID=1999, GID=1999),客户端挂载到 /upload-video/

1

所有主机统一创建用户(UID/GID 必须一致)

服务端 + 客户端都执行
groupadd -g 1999 whqzn
useradd  -u 1999 -g whqzn -s /sbin/nologin -M whqzn
2

服务端配置 /etc/exports

/etc/exports
/data/    192.168.2.0/24(rw)
/nfsdata/ 192.168.2.0/24(rw,all_squash,anonuid=1999,anongid=1999)

关键配置解读:all_squash 把所有用户都压缩,anonuid=1999,anongid=1999 指定压缩后的身份为 whqzn。

3

客户端挂载并验证

bash
# 挂载
mount -t nfs 192.168.2.100:/nfsdata /upload-video/

# 创建测试文件
touch /upload-video/test.txt

# 查看文件属主 → 应该是 whqzn
ll /upload-video/
-rw-r--r-- 1 whqzn whqzn 0 Apr 26 10:00 test.txt
09

生产环境安全优化

客户端安全挂载选项

生产环境中,NFS 共享目录通常只用来存储上传文件(图片、视频等),不应该允许执行程序。通过挂载选项加固安全:

bash
mount -o noexec,nosuid,nodev -t nfs 192.168.2.100:/data /video/
选项作用
noexec目录中的可执行文件无法运行,防止上传恶意脚本被执行
nosuid忽略文件的 SUID 权限位,防止通过共享目录提权
nodev忽略设备文件,防止利用特殊设备文件攻击系统

NFS 的局限与替代方案

NFS 最大的问题是单点故障:服务端宕机,所有客户端的共享目录都不可用。在生产环境中,根据业务规模可以考虑以下替代方案:

  • 公有云对象存储:如阿里云 OSS、腾讯云 COS,通过 SDK 在代码中直接调用,天然高可用
  • 分布式存储:GlusterFS(GFS)、MinIO 等,数据分布在多个节点,没有单点问题
  • 硬件优化:如果坚持用 NFS,建议使用物理服务器 + SSD 磁盘,提升 IO 性能
终极优化思路 尽可能让用户的请求在到达后端之前就被解决掉 —— 静态资源走 CDN,动态请求才回源。把用户请求往前推,后端压力自然就小了。

全文核心总结

部署五步走 安装软件包(rpcbind + nfs-utils) → 准备共享目录与权限 → 编辑 /etc/exports → 启动 RPC 和 NFS → 客户端 mount 挂载
排错三板斧 ping 测网络 → nc 测端口 → 检查双端防火墙
三个必须记住的核心知识
  • 服务端配置文件 /etc/exports 的格式和选项
  • 客户端永久挂载的两种方式(rc.local / fstab),以及永久挂载后要优先启动服务端
  • 用户压缩机制:all_squash + anonuid/anongid 控制文件归属