pvc 卡在 pending 是因 storageclass 未创建或 provisioner 指向不存在的 csi 驱动;需检查 sc 是否存在、provisioner 名称是否匹配、对应 driver pod 是否就绪,nfs 需额外部署 nfs-subdir-external-provisioner。

StorageClass 不配对,PVC 就永远卡在 Pending 状态——这不是配置遗漏,而是动态供给链路断了。
为什么 PVC 一直 Pending,却查不到 PV 创建日志?
常见现象是:你写了 storageClassName: standard 的 PVC,apply 后状态始终是 Pending,kubectl get pv 也空空如也。这不是 PV 没匹配上,而是根本没触发动态创建。
根本原因在于:StorageClass 对象本身未被正确创建,或其 provisioner 字段指向了一个集群里不存在的 CSI 驱动插件。
- 检查
StorageClass是否存在:kubectl get sc;若为空,说明没部署 - 检查
provisioner值(如ebs.csi.aws.com、nfs.csi.k8s.io)是否与已安装的 CSI Driver 名称完全一致(大小写敏感) - 确认对应 CSI Driver 的
StatefulSet已就绪:kubectl -n kube-system get pods -l app.kubernetes.io/name=<driver-name></driver-name> - 如果用的是本地开发集群(如 kind / minikube),默认不带任何 CSI Driver,必须手动装
local-path-provisioner或启用内置插件
如何为 NFS 配置一个可用的 StorageClass?
NFS 本身不支持原生动态供给,必须依赖 nfs-subdir-external-provisioner 这类第三方 provisioner。它不是 Kubernetes 内置组件,不能靠改 YAML 就生效。
实操要点:
- 先部署 provisioner:从官方仓库(
kubernetes-sigs/nfs-subdir-external-provisioner)获取 Helm chart 或 manifests,确保serviceAccount有cluster-admin权限(或最小化 RBAC) -
StorageClass的provisioner必须设为nfs-subdir-external-provisioner(注意连字符,不是下划线) -
parameters中的archiveOnDelete推荐设为"true",否则删 PVC 会直接 rm -rf 数据目录 - 不要在
parameters里写死 NFS server 地址——那是 Provisioner Deployment 的环境变量(NFS_SERVER和NFS_PATH)该管的事
示例关键字段:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-client provisioner: nfs-subdir-external-provisioner parameters: archiveOnDelete: "true"
云厂商 StorageClass 的常见陷阱
公有云(AWS EBS / Azure Disk / GCP PD)通常预装了对应 CSI Driver,但默认 StorageClass 往往不满足生产要求:
- AWS
gp2已废弃,新集群应使用gp3并显式设置iopsPerGB和throughput,否则默认吞吐仅 125 MiB/s - Azure
managed-csi默认是 HDD,需加skuname: StandardSSD_LRS才是 SSD - GCP
standard-rwo是 pd-standard,要高性能得用premium-rwo(pd-ssd) - 所有云厂商的默认 SC 都设了
reclaimPolicy: Delete,误删 PVC = 数据彻底丢失,生产环境务必改成Retain
如何验证 StorageClass 真正生效?
光看 kubectl get sc 显示 Available 不代表能用。必须走通“PVC → PV 创建 → Pod 挂载”全链路:
- 创建一个最小 PVC:
storageClassName指向目标 SC,accessModes匹配(如ReadWriteOnce) - 等 5–10 秒,执行
kubectl get pvc,pv;若 PVC 状态变Bound且出现新 PV,则供给成功 - 立刻删掉这个测试 PVC,观察 PV 状态:如果是
Retain策略,PV 应变为Released而非消失;此时kubectl get pv <name> -o yaml</name>查看spec.claimRef是否清空 - 最后一步常被跳过:起一个 Pod 挂载该 PVC,写入文件后 exec 进容器确认路径可读写
真正麻烦的从来不是写 YAML,而是 provisioner 的权限、网络连通性、NFS export 权限、云盘 I/O 配额这些看不见的依赖。一旦卡在 Pending,优先查 CSI Driver 日志,而不是反复改 PVC。











