一、问题背景
服务端路径:/NFS/1 作为主共享目录,该目录下存在子目录单独挂载磁盘 / 其他存储,形成本地嵌套挂载 ;服务端把 /NFS/1 整个目录共享给 NFS 客户端。 客户端挂载服务端 IP:/NFS/1 到本地挂载点后,只能看到父目录原生文件,嵌套挂载的子目录空白,读取不到真实数据。
二、完整现象
- 挂载流程无报错 客户端执行
mount -t nfs 192.168.46.xxx:/NFS/1 /mnt/nfs命令正常执行,无报错,mount、df -h能查看到 NFS 挂载记录,父目录普通文件、未嵌套的文件夹读写完全正常。 - 嵌套子目录异常 进入嵌套挂载的子文件夹,目录是空文件夹,看不到服务端该目录下的任何文件,无法写入、读取;
- 服务端本地正常,仅客户端异常 在 NFS 服务器本机直接进入
/NFS/1/嵌套子目录,所有文件完整、读写正常,证明磁盘和数据无损坏,问题只出在 NFS 远程共享层面; - 补充衍生现象(多层嵌套) 若存在多层嵌套挂载,部分环境会出现
Input/output errorIO 读写报错,无法 cd 进入子目录; - 日志特征 服务端 / 客户端系统日志无致命报错,容易误以为是文件丢失、权限问题,排查权限、防火墙、exports 权限均无效。
三、底层根本原因
NFS 服务默认行为:仅导出共享目录挂载时的顶层文件系统,不会自动穿透目录下的子挂载点。
- Linux 中 mount 挂载是内核层隔离,父目录
/NFS/1是一个文件系统,子目录单独挂载分区后,子目录属于另一个独立文件系统; - NFS 服务读取
/etc/exports共享目录时,只会导出共享目录初始文件系统,对子目录后续新增的挂载点默认屏蔽,不会把子挂载的文件系统同步给客户端; - 简单理解:NFS 只会共享挂载那一刻
/NFS/1本身的内容,看不见子目录后来单独挂载的磁盘数据。
四、全套解决办法(分方案,优先推荐方案 1)
方案 1:exports 配置添加 nohide 参数(最简,推荐)
1. 修改服务端 NFS 配置文件
编辑 /etc/exports,原配置示例:
/NFS/1 *(rw,sync,no_subtree_check)
修改后增加 nohide 参数:
/NFS/1 *(rw,sync,no_subtree_check,nohide)
nohide 作用:允许 NFS 穿透共享目录下所有子挂载点,客户端能正常读取嵌套挂载目录内容。
2. 重载 NFS 配置,无需重启服务
exportfs -r
3. 客户端重新挂载生效
先卸载旧挂载,再重新挂载:
umount /mnt/nfs
mount -t nfs 192.168.46.xxx:/NFS/1 /mnt/nfs
补充:配套隐藏参数 hide
hide 是默认开启状态,作用就是屏蔽子挂载目录,写了 nohide 等价关闭 hide。
方案 2:多层目录分开导出(无嵌套场景备选)
如果不方便使用 nohide,可把父目录、嵌套子目录分别配置 exports 共享:
/NFS/1 *(rw,sync,no_subtree_check)
/NFS/1/subdir *(rw,sync,no_subtree_check)
客户端分别挂载两层目录,缺点:客户端需要维护多个挂载点,管理麻烦,多层嵌套不适用。
方案 3:客户端挂载参数调整(辅助,不能单独解决)
仅加客户端挂载参数无法穿透子挂载,只能配合 nohide 使用;若挂载后权限异常,可追加参数:
mount -t nfs 192.168.46.xxx:/NFS/1 /mnt/nfs -o rw,sync
五、踩坑排查补充
- 修改 exports 后不执行
exportfs -r:配置不生效,依旧看不到嵌套目录; - 只改配置不重新挂载客户端:内核缓存旧挂载逻辑,修改参数不生效,必须 umount 再 mount;
- 混淆本地挂载与 NFS 共享权限:目录空白不是文件权限问题,chmod/chown 修改文件权限无法解决;
- 多层嵌套叠加:nohide 支持无限层级子挂载,无需额外配置。
六、永久优化方案(开机自启稳定)
-
/etc/exports 永久写入 nohide 参数;
-
NFS 服务开机自启:
systemctl enable --now nfs-server; -
客户端写入 fstab 自动挂载,避免每次手动挂载:
192.168.46.xxx:/NFS/1 /mnt/nfs nfs defaults,_netdev 0 0
_netdev 标识网络挂载,系统开机等网卡就绪后再挂载,防止启动失败。