PersistentVolumeClaim 一直 Pending。describe pvc 的 Events 判断是缺少供应器、容量不匹配还是绑定模式问题。安装 Docker、kind 和 kubectl,kind 版本需支持 hostPath PV(默认都支持)。
kind create cluster --name lab-pvc
kubectl get nodes
kubectl get storageclass
kubectl create namespace lab-pvc
kubectl config set-context --current --namespace=lab-pvc
kind 默认不一定有可用的默认 StorageClass,这正好避免实验被自动供应器“修好”。
创建一个没有对应供应器的 StorageClass,以及引用它的 PVC:
kubectl apply -f - <<'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: lab-static
provisioner: example.com/no-provisioner
volumeBindingMode: Immediate
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lab-pvc
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: lab-static
resources:
requests:
storage: 1Gi
EOF
kubectl get pvc lab-pvc
kubectl describe pvc lab-pvc | sed -n '/Events:/,$p'
kubectl get storageclass lab-static -o yaml
kubectl get pv
kubectl get events --sort-by=.lastTimestamp | tail -20
预期 PVC 状态为 Pending,describe 的 Events 显示等待外部供应器创建卷,例如 waiting for a volume to be created, either by external provisioner "example.com/no-provisioner" or manually created by system administrator;PV 列表为空,因为没有匹配的卷。
describe pvc 的 Events,它通常会直接指出“没有供应器”“没有匹配 PV”或“容量不足”。provisioner 是否有对应控制器运行。storageClassName 是否与现有 PV 匹配。volumeBindingMode: WaitForFirstConsumer 下,PVC 在 Pod 调度前 Pending 是正常设计,不是故障;只要创建使用该 PVC 的 Pod,绑定就会继续。另一个误判是 storageClassName: "",它表示禁用动态供应,只绑定显式空 class 的 PV。storageClassName 创建后通常不可修改,写错后需要删除重建。手工创建一个匹配的静态 PV,让 PVC 完成绑定:
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: PersistentVolume
metadata:
name: lab-pv
spec:
capacity:
storage: 1Gi
accessModes: ["ReadWriteOnce"]
storageClassName: lab-static
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /tmp/lab-pv
type: DirectoryOrCreate
EOF
kubectl get pv lab-pv
kubectl get pvc lab-pvc
两者都应显示 Bound,表示静态绑定完成。需要挂载时,再创建引用该 PVC 的 Pod;hostPath 只适合本地实验,生产应使用 CSI 和真实存储后端。
kubectl delete pvc lab-pvc --ignore-not-found
kubectl delete pv lab-pv --ignore-not-found
kubectl delete storageclass lab-static --ignore-not-found
kubectl delete namespace lab-pvc --ignore-not-found
kind delete cluster --name lab-pvc
先删 Pod 和 PVC,再删 PV,最后删 StorageClass。Retain 策略下 PV 删除后底层数据仍可能保留,本实验的 hostPath 会随 kind 节点一起删除。
WaitForFirstConsumer 的 Pending 是正常状态,排障时要结合 Pod 是否存在判断。WaitForFirstConsumer 模式下 PVC 一直 Pending,是否一定是故障?storageClassName: "" 的 PVC 不会走动态供应?storageClassName 一致,且 PV 处于 Available 状态。