NFS 环境搭建

发布时间: 更新时间: 总字数:2116 阅读时间:5m 作者: IP上海 分享 网址

网络文件系统(NFS, Network File System) 是一种分布式文件系统,目的是让客户端主机访问服务器端文件,并且过程时与访问本地存储是一样。

NFSv4 介绍

NFSv4 (Network File System version 4) 是网络文件系统协议的一个重大版本更新。与之前的版本(NFSv2 和 NFSv3)相比,它不仅是功能的增强,更是一次架构上的重构

NFSv4 由 IETF(互联网工程任务组)标准化(RFC 3530, RFC 5661 等),旨在解决旧版本在互联网环境下的性能、安全性和跨平台兼容性问题。

核心特点与改进

单一端口与防火墙友好 (Firewall Friendly)

  • 旧版本痛点: NFSv3 依赖 portmapper (rpcbind),使用随机端口传输数据,导致配置防火墙极其困难。
  • NFSv4 改进: 仅使用 TCP 2049 端口。所有的操作(包括挂载、锁定、数据传输)都在这一个端口上通过 TCP 连接完成。这使得在防火墙后配置 NFS 变得非常简单。

有状态协议 (Stateful)

  • 旧版本痛点: NFSv3 是无状态的。服务器不知道客户端打开了哪些文件。为了实现文件锁,它不得不依赖辅助协议(NLM, NSM),这增加了复杂性。
  • NFSv4 改进: NFSv4 是有状态的。协议本身集成了文件锁定(Locking)和挂载(Mounting)功能。服务器维护客户端的状态(通过租约机制),这大大提高了数据的一致性和文件锁的可靠性。

复合操作 (Compound Operations)

  • 性能提升: NFSv4 允许客户端将多个请求(例如:查找文件 LOOKUP、打开文件 OPEN、读取属性 GETATTR)打包成一个数据包发送给服务器。
  • 优势: 减少了网络往返次数(RTT),显著降低了在高延迟网络(如广域网 WAN)下的延迟。

安全性增强 (Security)

  • 强制安全: NFSv4 强制要求支持 RPCSEC_GSS 框架。
  • Kerberos 集成: 原生支持 Kerberos 身份验证,不再仅依赖弱不禁风的 IP 地址或 UID/GID 验证。
  • ACL 支持: 支持类似 Windows NTFS 的丰富访问控制列表 (NFS4 ACLs),比传统的 POSIX 读/写/执行权限更细粒度。

伪文件系统 (Pseudo File System)

  • 统一命名空间: 服务器导出一个目录(fsid=0),所有共享的目录都作为这个根目录下的子目录呈现。客户端只需要挂载这个根,就可以浏览所有导出的共享,而不需要像 v3 那样单独挂载每一个共享目录。

客户端缓存委托 (Delegation)

  • 机制: 服务器可以将文件的管理权暂时委托给客户端。客户端可以在本地进行读写操作,而无需频繁与服务器通信。
  • 回收: 当其他客户端请求访问该文件时,服务器会召回委托。这极大地提高了单一客户端频繁操作文件时的性能。

NFSv4 的子版本演进

NFSv4 并不是一成不变的,它有几个重要的次级版本:

  • NFSv4.0 (RFC 3530): 基础版本,确立了上述的有状态、单一端口等特性。
  • NFSv4.1 (RFC 5661):
    • pNFS (Parallel NFS): 这是最大的革新。允许客户端直接并行地从多个存储设备(Data Servers)读取数据,而元数据(Metadata)仍由管理服务器处理。解决了单服务器的 I/O 瓶颈。
    • 会话层 (Session trunking): 提供了仅执行一次的语义,增强了网络断连后的恢复能力。
  • NFSv4.2 (RFC 7862):
    • 服务器端复制 (Server-Side Copy): 允许在服务器内部复制文件,无需数据先流向客户端再流回服务器。
    • 稀疏文件 (Sparse Files) 与 空间预留: 支持更现代的存储特性。
    • 安全性增强: 支持 SELinux 标签传输等。

NFSv3 vs NFSv4 对比总结

特性 NFSv3 NFSv4
协议状态 无状态 (Stateless) 有状态 (Stateful)
传输协议 UDP 或 TCP TCP (强制)
端口使用 随机端口 (依赖 rpcbind) 固定端口 (TCP 2049)
文件锁 依赖外部协议 (NLM) 协议集成
性能机制 单次 RPC 请求 复合 RPC (Compound)
用户验证 信任 UID/GID (较弱) 支持 Kerberos (强)
挂载方式 单独挂载每个 Export 挂载伪根 (Pseudo-fs)
缓存机制 较弱 Delegation (委托)
并行访问 不支持 支持 pNFS (v4.1+)

NFS 服务部署

NFS 服务端和客户端服务均依赖于 rpcbindrpcbind 是一个将 RPC(Remote Procedure Call,远程过程调用) 程序编号转换为通用地址的服务,RPC 调用依赖 rpcbind 服务。

服务:

  • rpc.nfsd NFS 主进程,通过 systemctl start nfs-utils.service 启动,监听 TCP/UDP 2049 端口
  • rpc.mountd 监听在 TCP/UDP 20048 端口
  • rpc.lockd(可选,防止多个客户端同时写入一个文件)
  • rpc.statd(可选,负责数据的状态及一致性检查)
  • rpcbind 依赖进程,通过 systemctl start rpcbind.service 启动,监听在 TCP/UDP 20048 端口

配置文件:

  • /etc/nfs.conf
  • /etc/nfsmount.conf

准备

本次部署直接关闭防火墙:

systemctl stop firewalld
systemctl disable firewalld

服务端安装

# CentOS
yum install -y nfs-utils

# Ubuntu
apt install nfs-kernel-server

注意:安装 nfs-utils 时,会自动安装 rpcbind

  • 启动
systemctl enable rpcbind.service
systemctl enable nfs-server.service

systemctl start rpcbind.service
systemctl start nfs-server.service
  • 配置共享目录

/etc/exports 文件中一行表示一个共享目录。格式如下:

共享目录路径   IP或主机名1(选项1,选项2,...)  IP或主机名2(选项1,选项3,...)   ...

选项说明:

选项 功能
ro 以只读方式共享(默认)
rw 以读写方式共享
sync 客户端写入的数据立即写入到磁盘中(默认)
async 客户端写入的数据先写入到内存中,再写入磁盘中
root_squash 把 root 用户映射为匿名用户(默认)
no_root_squash 允许使用 root 用户
all_squash 把所有用户映射为匿名用户
anonuid=<UID> 指定匿名用户的 UID
anongid=<GID> 指定匿名用户的 GID
secure 允许客户端使用小于 1024 的端口连接
insecure 允许客户端使用大于 1024 的端口连接
subtree_check 共享子目录时,强制检查父目录权限(默认)
no_subtree_check 不检查父目录权限
wdelay 多个用户要写入 NFS 目录,则归组写入(默认)
no_wdelay 多个用户要写入 NFS 目录,则立即写入,当使用 async 时,无需此设置

示例:

$ cat /etc/exports
/home *(rw,no_subtree_check,fsid=10,no_root_squash)
/opt 10.0.0.1(rw,all_squash) 10.0.0.2(ro,no_root_squash)

注意:

  • 配置后需要重启 systemctl restart nfs-server 或执行 exportfs -rv 或执行 exportfs -a
  • 查看 nfs 暴露的端口
$ showmount -e <nfs-server>

$ showmount -e 172.20.100
Export list for 172.20.100:
/home *
/opt  10.0.0.2,10.0.0.1

k8s 部署

使用

客户端

  • 依赖包按照
yum install nfs-utils
  • 临时 mount
mount.nfs 172.20.0.100:/home /mnt/
  • 通过 fstab 挂载
echo "172.20.0.100:/home /home nfs nfsvers=3,nodev,nosuid 0 0" >> /etc/fstab
mount -a

配置基于 RDMA 的 NFS 服务

# 加载rdma内核模块
# 服务端
modprobe xprtrdma

# 客户端
modprobe svcrdma

# 服务端监听 RDMA 传输端口
$ echo 'rdma 20049' | tee /proc/fs/nfsd/portlist
$ cat /proc/fs/nfsd/portlist
rdma 20049
rdma 20049
udp 2049
tcp 2049
udp 2049
tcp 2049

# 挂载
$ mount -t nfs <nfs-server-ip>:/ /mnt/ -o vers=4.1,_netdev,rdma,port=20049,hard,intr,noatime,nodiratime,async,nolock,noacl,sec=sys,noresvport

k8s 使用

  • nfs-subdir-external-provisioner 是 k8s 中,支持在一个远程 NFS 服务器上的动态子目录卷供应器
    • PV 以目录名为 ${namespace}-${pvcName}-${pvName} 的格式在 NFS 服务器上创建
    • 回收的格式为 archieved-${namespace}-${pvcName}-${pvName}

F&Q

Unable to mount network drive in Debian; error is “mount(2) system call failed: No route to host.”

sudo apt-get install keyutils cifs-utils
本文总阅读量 次 本站总访问量 次 本站总访客数
Home Archives Categories Tags Statistics