深色模式
K8s 存储挂载失败排查
摘要:存储挂载失败分三类:PVC 一直 Pending(供不出卷)、挂载超时(卷存在但挂不上)、挂载成功但读写报错(权限问题)。本文分别给出定位命令与典型成因。
适用环境
bash
kubectl version --short 2>/dev/null || kubectl version
kubectl get sc
kubectl -n kube-system get pod | grep -iE 'provisioner|csi'1
2
3
2
3
排障步骤
第 1 步:看 PVC 状态与事件
bash
kubectl get pvc -n <ns>
kubectl describe pvc <pvc> -n <ns>1
2
2
Pending 且事件中出现 Waiting for a volume to be created 说明动态供给未成功。
第 2 步:确认 StorageClass 与 Provisioner
bash
kubectl get sc
kubectl describe sc <storageclass>
kubectl get pvc <pvc> -n <ns> -o jsonpath='{.spec.storageClassName}'1
2
3
2
3
PVC 未指定 storageClassName 时,会使用该命名空间的默认 SC;没有默认 SC 时会一直 Pending。
第 3 步:看 Provisioner / CSI 组件
bash
kubectl -n kube-system get pod | grep -iE 'provisioner|csi|snapshot'
kubectl -n kube-system logs -l app=csi-provisioner --tail=501
2
2
供给失败的真实原因(配额、API 限流、参数不合法)都在这些组件的日志中。
第 4 步:检查 AccessMode 与容量
bash
kubectl get pvc <pvc> -n <ns> -o jsonpath='{.spec.accessModes} {.spec.resources.requests.storage}'
kubectl get pv1
2
2
AccessMode 不匹配导致无限 Pending
请求 ReadWriteMany 但后端只支持 ReadWriteOnce 时永远不会绑定;反过来请求过大容量会一直等可用卷。
第 5 步:挂载超时与可用区问题
bash
kubectl describe pod <pod> -n <ns> | sed -n '/Events/,$p'
kubectl get node <node> -o jsonpath='{.metadata.labels}' | tr ',' '\n' | grep -i zone
kubectl get pv <pv> -o jsonpath='{.metadata.labels}' | tr ',' '\n' | grep -i zone1
2
3
2
3
卷在可用区 A、Pod 调度到可用区 B,会表现为挂载一直超时。
第 6 步:挂载成功但无写权限
bash
kubectl exec -it <pod> -n <ns> -- id
kubectl exec -it <pod> -n <ns> -- ls -ldn /data
kubectl get pod <pod> -n <ns> -o jsonpath='{.spec.securityContext}'1
2
3
2
3
容器内用户与卷属主不一致
以非 root(runAsUser)运行,而卷属主为 root 且权限 755 时,写入会报 Permission denied。需要用 fsGroup 让 kubelet 修改卷的属组。
第 7 步:多 Pod 抢占同一卷
bash
kubectl get pod -n <ns> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.volumes[*].persistentVolumeClaim.claimName}{"\n"}{end}'1
ReadWriteOnce 卷被两个 Pod 挂载时,第二个会报 Multi-Attach error。
验证
bash
kubectl get pvc -n <ns>
kubectl exec -it <pod> -n <ns> -- sh -c 'touch /data/.w && echo writable && rm /data/.w'1
2
2
常见坑
PV 存在但 PVC 不绑定
PV 与 PVC 的 storageClassName、accessModes、容量需同时满足,任一不匹配都不会绑定。
subPath 挂载不会随 ConfigMap/Secret 更新
使用 subPath 的挂载是文件级绑定,源更新后容器内不变,需重启 Pod。
删除 PVC 不等于删除数据
取决于 PV 的 persistentVolumeReclaimPolicy,Retain 策略下数据仍在,误判会造成数据"消失"的错觉。
直接删除 PV 或强行 detach
生产卷强删会导致数据丢失或文件系统损坏。操作前必须确认已有备份,并先停止写入方。