Skip to content

NFS Mount Failed

背景

香蕉集群的 PV 持载 NFS xxx.xxx.xx.xx 失败,报错。

bash
Mounting arguments: -t nfs xxx.xxx.xx.xx:/foobar-scan-download-custom-data-pvc /var/lib/kubelet/pods/45c7c6e4-d9de-4c3c-8e6e-41cc1d7ed036/volumes/kubernetes.io~nfs/pvc-minsheng-bank-foobar-scan-download-custom-data
Output: mount: wrong fs type, bad option, bad superblock on xxx.xxx.xx.xx:/foobar-scan-download-custom-data-pvc,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
  Warning  FailedMount  26s (x234 over 18h)  kubelet  Unable to attach or mount volumes: unmounted volumes=[foobar-scan-download-data foobar-scan-download-custom-data], unattached volumes=[skywalking-agent foobar-scan-download-data foobar-scan-download-custom-data kube-api-access-vgnx2]: timed out waiting for the condition

排查思路

  • NFS 服务是否可用 (showmount -e xxx.xxx.xx.xx)
  • 检查 /etc/exports,确保目录已正确导出
  • NFS客户端 nfs-utils 是否安装
  • 手动挂载测试 (mount -t nfs)
  • 尝试指定 NFS 版本 (vers=3vers=4)
  • 检查防火墙和 SELinux 配置

NFS 服务是否可用

showmount

你的 NFS 服务器是 xxx.xxx.xx.xx,要确认它是否正在运行:

bash
showmount -e xxx.xxx.xx.xx
bash
Exports list on xxx.xxx.xx.xx:
/data/nfs-fileshare  192.168.192.0/24 192.168.88.0/24 192.168.48.8/32
  • 192.168.192.0/24 → 允许 192.168.192.0 - 192.168.192.255 访问
  • 192.168.48.8/32 → 只允许 192.168.48.8 访问

如果没有返回可用的 NFS 共享目录,说明NFS 服务器未正确导出目录,需要检查 exports 配置。

rpcinfo

如果 showmount 失败,你可以尝试 rpcinfo,显示的是 xxx.xxx.xx.xx 这台服务器上运行的 RPC(远程过程调用)服务,包括 NFS 相关的端口和协议。

bash
rpcinfo -p xxx.xxx.xx.xx
bash
   program vers proto   port
    100000    4   tcp    111  rpcbind
    100000    3   tcp    111  rpcbind
    100000    2   tcp    111  rpcbind
    100000    4   udp    111  rpcbind
    100000    3   udp    111  rpcbind
    100000    2   udp    111  rpcbind
    100024    1   udp  34853  status
    100024    1   tcp  51365  status
    100005    1   udp  20048  mountd
    100005    1   tcp  20048  mountd
    100005    2   udp  20048  mountd
    100005    2   tcp  20048  mountd
    100005    3   udp  20048  mountd
    100005    3   tcp  20048  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  30547  nlockmgr
    100021    3   udp  30547  nlockmgr
    100021    4   udp  30547  nlockmgr
    100021    1   tcp  36867  nlockmgr
    100021    3   tcp  36867  nlockmgr
    100021    4   tcp  36867  nlockmgr

端口映射服务 (portmapper)

bash
program vers proto   port  service
100000    4   tcp    111  portmapper
100000    3   tcp    111  portmapper
100000    2   tcp    111  portmapper
100000    4   udp    111  portmapper
100000    3   udp    111  portmapper
100000    2   udp    111  portmapper
  • portmapper 运行在 TCP 和 UDP 的 111 端口
  • 作用:管理所有 RPC 服务的端口映射,客户端查询 portmapper 以获取 NFS 等服务的端口号。

status 服务

bash
100024    1   udp  34853  status
100024    1   tcp  51365  status
  • status 服务 用于 NFS 文件锁状态管理

mountd 服务

bash
100005    1   udp  20048  mountd
100005    1   tcp  20048  mountd
100005    2   udp  20048  mountd
100005    2   tcp  20048  mountd
100005    3   udp  20048  mountd
100005    3   tcp  20048  mountd
  • mountd 运行在 UDP/TCP 20048 端口
  • 作用:
    • 处理客户端的 mount 请求,即客户端尝试挂载 NFS 目录时,会先与 mountd 交互。
      • mountd 确认客户端有权限后,返回 NFS 目录的详细信息。

nfs 服务

txt
yaml
CopyEdit
100003    3   tcp   2049  nfs
100003    4   tcp   2049  nfs
100227    3   tcp   2049  nfs_acl
100003    3   udp   2049  nfs
100003    4   udp   2049  nfs
100227    3   udp   2049  nfs_acl
  • NFS 服务器的核心服务,运行在 2049 端口
  • nfs 支持多个协议版本:
    • NFSv3 (100003, vers=3)
      • NFSv4 (100003, vers=4)
  • nfs_acl 处理 ACL(访问控制列表),NFSv4 需要它来管理文件权限。

nlockmgr(文件锁管理)

bash
100021    1   udp  30547  nlockmgr
100021    3   udp  30547  nlockmgr
100021    4   udp  30547  nlockmgr
100021    1   tcp  36867  nlockmgr
100021    3   tcp  36867  nlockmgr
100021    4   tcp  36867  nlockmgr
  • nlockmgr 负责 NFS 客户端的文件锁管理
  • NFS 允许多个客户端同时访问同一个共享目录,所以 nlockmgr 用来协调文件锁定。

总结

  • NFS 服务器在 xxx.xxx.xx.xx 上正常运行,并监听以下关键端口:
    • 111(portmapper):提供 RPC 端口映射
      • 20048(mountd):处理 NFS 挂载请求
      • 2049(nfs):核心 NFS 读写服务
      • 30547/36867(nlockmgr):管理 NFS 文件锁

你的 NFS 服务器 进程是正常的,但如果 Kubernetes 仍然无法挂载 NFS 目录,可能的问题在:

  1. 客户端未正确安装 nfs-utilsnfs-common
  2. 客户端的 NFS 版本不匹配(尝试 vers=3vers=4 挂载)
  3. 防火墙阻挡了 111、2049、20048 端口
  4. SELinux 阻止 NFS 访问(尝试 setenforce 0
  5. 检查 /etc/exports 是否正确,并重新执行 exportfs -rv

你可以手动测试挂载:

bash
mount -t nfs -o vers=3 xxx.xxx.xx.xx:/data/nfs-fileshare /mnt/test

如果仍然报错,运行:

bash
dmesg | tail -n 20

查看详细错误信息。

检查 /etc/exports

在 NFS 机器上运动命令

bash
cat /etc/exports
bash
/data/nfs-fileshare 192.168.80.0/24(rw,async,insecure,fsid=0,no_auth_nlm,no_subtree_check,no_root_squash,no_all_squash)
/data/nfs-fileshare 192.168.48.8/32(rw,async,insecure,fsid=0,no_auth_nlm,no_subtree_check,no_root_squash,no_all_squash)
/data/nfs-fileshare 192.168.88.0/24(rw,async,insecure,fsid=0,no_auth_nlm,no_subtree_check,no_root_squash,no_all_squash)
/data/nfs-fileshare 192.168.192.0/24(rw,async,insecure,fsid=0,no_auth_nlm,no_subtree_check,no_root_squash,no_all_squash)

共享的目录

/data/nfs-fileshare

  • 这是 NFS 服务器上要共享的目录,允许指定的 IP 地址范围访问。

允许访问的客户端

  • 192.168.80.0/24 → 允许 192.168.80.0 - 192.168.80.255 访问
  • 192.168.48.8/32 → 只允许 192.168.48.8 访问
  • 192.168.88.0/24 → 允许 192.168.88.0 - 192.168.88.255 访问
  • 192.168.192.0/24 → 允许 192.168.192.0 - 192.168.192.255 访问
选项作用
rw允许客户端 读写 共享目录
async允许 NFS 服务器在 未完成写入 时先响应,提高性能,但可能会导致数据丢失
insecure允许客户端使用 非特权端口(端口号 >1024) 访问 NFS(适用于某些 Kubernetes Pod)
fsid=0设定为 NFS 根目录,客户端可以通过 192.168.x.x:/ 直接挂载
no_auth_nlm禁用 NLM(Network Lock Manager)身份验证
no_subtree_check关闭 子树检查,提高性能,避免权限问题
no_root_squash允许客户端的 root 用户在 NFS 服务器上也拥有 root 权限(⚠️ 可能带来安全风险
no_all_squash保留所有用户的原始 UID/GID,不强制映射为匿名用户

这意味着什么?

  1. 任何在 192.168.80.0/24192.168.88.0/24192.168.192.0/24 网络内的机器,以及 192.168.48.8 单独的 IP,都可以访问 /data/nfs-fileshare 目录。
  2. 这些客户端可以 读写 该目录,而不会受到 root 权限限制(因为 no_root_squash)。
  3. 由于 async,写入操作可能会被缓存,而不会立即写入磁盘(提升性能但有风险)。
  4. insecure 选项 允许客户端使用端口号大于 1024(某些 Kubernetes NFS 挂载需要)。
  5. no_subtree_check 选项 避免了子目录权限检查,提高访问效率。

NFS客户端 nfs-utils 是否安装

在 NFS 客户端(即你的 Kubernetes 节点)上,确保 nfs-utils 已安装:

bash
rpm -qa | grep nfs
  • rpm:RPM 包管理工具
  • q:查询(query)
  • a:查询所有已安装的软件包(all)
bash
libnfsidmap-0.25-19.el7.x86_64
nfs-utils-1.3.0-0.68.el7.2.x86_64

如果没有任何输出,则表示没有安装。

bash
yum install -y nfs-utils

手动挂载测试

在 Kubernetes 节点上手动尝试挂载:

bash
mkdir -p /mnt/test-nfs
mount -t nfs xxx.xxx.xx.xx:/foobar-scan-download-custom-data-pvc /mnt/test-nfs

如果失败,运行:

bash
dmesg | tail -n 20

查看更详细的错误日志。

检查 NFS 版本兼容性

可以尝试指定 NFS 版本:

bash
mount -t nfs -o vers=3 xxx.xxx.xx.xx:/foobar-scan-download-custom-data-pvc /mnt/test-nfs

如果 vers=3 失败,可以尝试:

bash
mount -t nfs -o vers=4 xxx.xxx.xx.xx:/foobar-scan-download-custom-data-pvc /mnt/test-nfs

在 Kubernetes 中,可以在 PersistentVolume (PV) 里加上 nfsvers 选项:

yaml
mountOptions:
  - vers=3

确保 NFS 端口未被防火墙阻挡

在 NFS 服务器上:

bash
iptables -L -n
firewall-cmd --list-all

如果有防火墙,允许 NFS 相关端口:

bash
firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload

或者临时关闭防火墙进行测试:

bash
systemctl stop firewalld

检查 SELinux

如果启用了 SELinux,可以尝试临时关闭:

bash
setenforce 0

如果这样可以挂载,说明可能需要 setsebool 配置:

bash
setsebool -P virt_use_nfs on