Skip to content

NFS 共享文件系统

NFS(Network File System,网络文件系统)是一种分布式文件系统协议,允许不同计算机系统通过网络共享文件和目录,使客户端能够像访问本地文件一样访问远程服务器上的文件

NFS的基本概念

  • 服务器端:提供共享存储的机器,负责导出(export)目录供客户端访问。
  • 客户端:访问服务器端共享存储的机器,通过挂载(mount)方式使用共享目录。
  • 共享目录:服务器端导出的目录,客户端可以像访问本地文件系统一样访问它

工作原理

mermaid
graph TD
    %% 标题
    T[NFS挂载图] --> A

    %% 服务器节点
    A[NFS server\n共享/video目录] 
    style A fill:#ffffff,stroke:#ff0000,stroke-dasharray: 5 5,stroke-width:2px

    %% 客户端节点
    B[NFS Client\n挂载NFS Server/video目录到本地/video目录]
    C[NFS Client\n挂载NFS Server/video目录到本地/video目录]
    style B fill:#ffffff,stroke:#0000ff,stroke-width:2px
    style C fill:#ffffff,stroke:#0000ff,stroke-width:2px

    %% 连接线
    A --> B
    A --> C
    style T fill:none,stroke:none
    linkStyle 0,1 stroke:#000000,stroke-width:1.5px

NFS本身是没有提供信息传输的协议和功能的,而是将自己的端口报备rpcbind服务,rpcbind服务开放111端口,客户端服务端请求发送到111端口上。rpcbind查看nfs服务在rpcbind记录的开放的端口,将用户请求调度到对应的端口上。

NFS 关键守护进程

进程名端口功能说明
rpc.nfsd2049主服务进程,处理文件操作请求
rpc.mountd随机验证客户端挂载权限(检查/etc/exports)
rpc.statd随机提供文件锁定状态管理
rpc.lockd随机处理文件锁操作

协议依赖关系

版本RPC依赖端口要求
NFSv3必须依赖rpcbind111 + 2049 + 随机端口
NFSv4不依赖rpcbind仅需2049

NFS配置 /etc/exports

配置格式

ini
存储目录 允许的IP(参数)
/data 192.168.1.0/24(rw,sync,all_squash)

参数

参数名称缩写功能描述风险提示
Read-writerw可读写权限不当配置可能导致数据被篡改
Read-onlyro只读权限-
同步写入sync数据实时写入服务器硬盘后才返回性能较低但数据安全
异步写入async数据先写入内存缓冲区,延迟写入磁盘服务器异常关机可能导致数据丢失
保留root权限no_root_squashroot用户保持完整权限高危!可能引发提权攻击
压缩root权限root_squash将root用户权限降级为匿名用户增强安全性但可能影响某些服务运行
强制匿名访问all_squash所有用户权限压缩为匿名用户适用于完全公开目录
匿名用户UIDanonuid指定共享文件所有者UID(如anonuid=12306)需与anongid配合使用
匿名用户GIDanongid指定共享文件所有者GID(如anongid=12306)需确保指定ID在服务端存在

NFS的配置流程

服务端搭建

安装软件包

bash
# CentOS/RHEL
dnf install -y nfs-utils rpcbind
# Ubuntu/Debian
apt-get install nfs-kernel-server

创建共享目录并设置权限

bash
mkdir /data
chmod 755 -R /data
chown -R nobody:nobody /data

编辑配置文件(/etc/exports

bash
/data 192.168.1.0/24(rw,sync,no_root_squash)
  • rw:读写权限。
  • sync:数据同步写入磁盘。
  • no_root_squash:允许客户端root用户保留权限

启动服务

bash
systemctl enable rpcbind nfs --now

检测服务暴露端口

bash
showmount -e

# 正常出现
Export list for nfs-server:
/data 192.168.1.0/24

客户端搭建

安装软件包

bash
# CentOS/RHEL
dnf install -y nfs-utils

# Ubuntu/Debian
apt-get install nfs-common

查看服务端暴露端口

bash
showmount -e 192.168.148.1.100
# 正常出现
Export list for 192.168.148.157:
/data 192.168.1.0/24

挂载共享目录

bash
mount -t nfs 192.168.1.100:/data/share /data

验证挂载

bash
df -h | grep nfs

NFS无敌时间

NFS客户端挂载后,往共享目录写入数据时卡住了。NFS服务端,重启restart服务,客户端如果写入数据卡住了。

解答:

  • nfs服务端重启之后,共享文件夹进入grace time(无敌时间)

  • 客户端在服务端重启后写入数据大概要等90秒

  • nfs配置文件:/etc/sysconfig/nfs

    ini
    sed -n '45,55p' /etc/sysconfig/nfs
    # When there are no active clients, changing these values
    # can be done in a single server restart.
    #
    #NFSD_V4_GRACE=90 # 无敌时间
    #NFSD_V4_LEASE=90 # 无敌时间
    #NLM_GRACE_PERIOD=90 # 无敌时间
    #
    #
    #
    # Optional arguments passed to rpc.mountd. See rpc.mountd(8)
    #RPCMOUNTDOPTS=""
    #说明:
    #NFSD_V4_GRACE=90 <===>/proc/fs/nfsd/nfsv4gracetime
    #NFSD_V4_LEASE=90 <===>/proc/fs/nfsd/nfsv4leasetime
    #NLM_GRACE_PERIOD=90 <===>/proc/fs/nfsd/nfsv4recoverydir
    #这三条是控制无敌时间的,去掉#直接修改时间即可,改后别忘了重启服务。一旦启用了这三条,/proc临时目录下便会生成对应的临时文件

mount -o 参数

参数组参数选项功能描述系统默认值典型应用场景
SUID控制suid允许执行带有SUID权限的程序suid需要特殊权限的程序运行
nosuid禁用SUID程序功能(增强安全性)-公共挂载目录安全防护
读写控制rw允许读写操作rw需要修改数据的共享目录
ro只读访问-静态资源分发(如软件仓库)
设备文件dev允许访问设备文件特殊功能dev需要直接访问硬件的场景
nodev禁用设备文件功能-安全防护(如Web目录)
执行权限exec允许执行二进制文件exec共享可执行程序
noexec禁止执行文件-纯数据存储目录(如图片/附件)
用户操作user允许普通用户挂载/卸载-多用户协作环境
nouser仅root用户可操作nouser生产环境安全防护
自动挂载automount -a时自动挂载auto需要持久化挂载的分区
noauto需手动挂载-临时性挂载或测试环境

生产环境建议组合

bash
mount -t nfs -o rw,nosuid,nodev,noexec 192.168.1.100:/share /mnt
# 或者
mount.nfs -o rw,nosuid,nodev,noexec 192.168.1.100:/share /mnt

NFS 内核优化

参数文件路径参数说明默认值建议值优化目的
/proc/sys/net/core/rmem_default接收套接字缓冲区默认大小(字节)1249288388608提高 TCP 接收性能
/proc/sys/net/core/rmem_max接收套接字缓冲区最大大小(字节)12492816777216支持高吞吐量网络连接
/proc/sys/net/core/wmem_default发送套接字缓冲区默认大小(字节)1249288388608提高 TCP 发送性能
/proc/sys/net/core/wmem_max发送套接字缓冲区最大大小(字节)12492816777216支持高吞吐量网络连接

临时生效

bash
echo 8388608 > /proc/sys/net/core/rmem_default
echo 16777216 > /proc/sys/net/core/rmem_max
echo 8388608 > /proc/sys/net/core/wmem_default
echo 16777216 > /proc/sys/net/core/wmem_max

永久生效

bash
cat >> /etc/sysctl.conf <<EOF
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_default = 8388608
net.core.wmem_max = 16777216
EOF
sysctl -p  # 立即生效

NFS优缺点说明

NFS服务可以让不同的客户端挂载使用同一个共享目录,也就是将其作为共享存储使用,这样可以保证不同节点客户端数据的一致性,在集群架构环境中经常会用到。如果是windowsLinux混合环境的集群系统,可以用samba来实现。

优点

  • 配置简单,容易上手,容易掌握
  • NFS 文件系统内数据是在文件系统之上的,即数据是能看得见的。
  • 支持文件锁。NFSv4+ 内置文件锁机制,避免多客户端同时写入冲突。
  • 高性能。适合并发读取(如web静态资源,数据库备份)

局限

  • 存在单点故障,如果NFS Server宕机了,所有客户端都不能访问共享目录。这个需要负载均衡及高可用来弥补
  • 在大数据高并发的场合,NFS效率,性能有限(2千万/日以下PV(page view)的网站不是瓶颈,除非网站架构设计太差。)
  • 客户端认证是基于IP和主机名的,权限要根据ID识别,安全性一般(用于内网则问题不大)。
  • NFS数据是明文的,NFS本身不对数据完整性做验证。
  • 多台客户机器挂载一个NFS服务器时,连接管理维护麻烦(耦合度高)。尤其NFS服务端出问题后,所有NFS客户端都处于挂掉状态(测试环境可使用autofs自动挂载解决,正式环境可修复NFS服务或强制卸载)
  • 涉及了同步(实时等待)和异步(解耦)的概念,NFS服务端和客户端相对来说就是耦合度有些高。网站程序也是一样,尽量不要耦合度太高,系统及程序架构师的重要职责就是为程序及架构解耦,让网站的扩展性变得更好。

应用建议

大中小型网站(参考点2000万/日PV以下)线上应用,都有用武之地。门户站也会有应用,生产场景应

该多把数据的访问往前推,即尽量把静态存储里的资源通过CDN或缓存服务器提供服务,如果没有缓存

服务或架构不好,存储服务器数量再多也是扛不住压力的,而且用户体验会很差。