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=3
或vers=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
)
- NFSv4 (
- NFSv3 (
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 目录,可能的问题在:
- 客户端未正确安装
nfs-utils
或nfs-common
- 客户端的 NFS 版本不匹配(尝试
vers=3
或vers=4
挂载) - 防火墙阻挡了 111、2049、20048 端口
- SELinux 阻止 NFS 访问(尝试
setenforce 0
) - 检查
/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,不强制映射为匿名用户 |
这意味着什么?
- 任何在
192.168.80.0/24
、192.168.88.0/24
、192.168.192.0/24
网络内的机器,以及192.168.48.8
单独的 IP,都可以访问/data/nfs-fileshare
目录。 - 这些客户端可以 读写 该目录,而不会受到
root
权限限制(因为no_root_squash
)。 - 由于
async
,写入操作可能会被缓存,而不会立即写入磁盘(提升性能但有风险)。 insecure
选项 允许客户端使用端口号大于 1024(某些 Kubernetes NFS 挂载需要)。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