事情本身不复杂,线索都在日志里。自建 K8s 1.25,Ubuntu 20.04,nfs-subdir-external-provisioner 提供 StorageClass,Pod 以 runAsUser 1000 运行,挂载 PVC 后写文件报 Permission denied,同一目录在节点上用 root 可以写。

第一反应是「Pod 的 securityContext 指定了非 root 用户,与目录属主不一致」,验证下来不成立。

原因不止一个,得分开看。NFS 导出没有开 no_root_squash,容器里的 uid 被映射成 nobody。还有一种是PVC 目录由 provisioner 以 root 创建,权限是 755。

不容易想到的是,NFS 服务端配了 all_squash,所有访问都压成匿名用户。

上来先看挂载目录的属主和当前用户

kubectl exec -it web -- ls -ld /data && id

然后在服务端确认导出参数

exportfs -v | grep /data/nfs

给 PVC 目录设置组权限和组写位

kubectl exec -it web -- chgrp 1000 /data && chmod 775 /data

给 Pod 补上 fsGroup

kubectl patch deploy web -p '{"spec":{"template":{"spec":{"securityContext":{"fsGroup":1000}}}}'

隔了一天再看,现象没变,说明不是偶发。

那几天正好在做别的变更,先把时间线对齐才敢动手。

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

改完先别撤,确认这几项。Pod 内 touch /data/test 成功,文件属主是 1000,重启 Pod 后目录依然可写。

容易忽略的是,root squash 是服务端行为,容器里 chown 再多次也没用,权限要在导出配置和 fsGroup 两侧对齐。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189