Kubernetes 中的持久化卷声明(PVC)是用户请求存储资源的方式。当 PVC 持续处于 Pending 状态时,意味着系统未能成功找到或动态创建匹配的持久化卷(PV)。理解 PV 和 PVC 之间的绑定逻辑是解决问题的关键。
1. PV 与 PVC 的绑定逻辑核心
PV 与 PVC 之间的绑定过程,无论是静态(管理员预先创建 PV)还是动态(StorageClass 自动创建 PV),都依赖于几个关键匹配条件:
- StorageClass 匹配: PVC 必须引用一个存在的 StorageClass。如果 PVC 没有指定,则尝试匹配没有指定 StorageClass 的 PV(仅用于静态绑定),或者匹配集群默认的 StorageClass。
- 访问模式(Access Modes)匹配: PV 提供的访问模式(如 ReadWriteOnce、ReadOnlyMany、ReadWriteMany)必须包含 PVC 请求的模式。
- 资源大小(Capacity)匹配: PV 的容量必须大于或等于 PVC 请求的容量。
如果这三项中的任何一项不匹配,PVC 将保持 Pending 状态。
2. 常见问题排查清单
当 PVC 处于 Pending 状态时,应立即使用 kubectl describe 命令查看详细事件。
# 查看 PVC 状态和事件
kubectl describe pvc my-pvc-name
# 查看 PV 状态
kubectl get pv
以下是导致 Pending 的最常见原因及排查方法:
陷阱 1:StorageClass 名称不匹配或不存在
如果 PVC 引用了一个不存在的 StorageClass,动态创建将失败。
如何排查:
- 检查 PVC 定义中的 storageClassName。
- 检查集群中是否存在该 StorageClass。
kubectl get sc
如果输出中没有找到 PVC 请求的 StorageClass,则 PVC 无法被动态满足。
陷阱 2:访问模式要求不匹配
这是静态绑定中最容易出错的地方。PV 必须完全满足 PVC 所有的访问模式要求。
例如,如果一个 PV 仅支持 ReadWriteOnce,而 PVC 明确要求 ReadWriteMany,则它们无法绑定。
错误的示例配置 (PV 无法满足 PVC 要求):
假设我们有一个 PV,只能被单个节点读写:
# persistent-volume-rwo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv-rwo
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
storageClassName: manual
hostPath:
path: "/mnt/data"
---
# persistent-volume-claim-rwx.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc-rwx
spec:
accessModes:
# PVC 要求 ReadWriteMany,但 PV 仅支持 ReadWriteOnce
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: manual
执行 kubectl apply -f . 后,my-pvc-rwx 将会处于 Pending 状态,并且 kubectl describe pvc 会显示类似 waiting for first consumer to bind 或 no volume found for claim 的信息(取决于 K8s 版本和配置)。
3. 陷阱 3:动态 Provisioner 失败 (针对 StorageClass)
如果使用了 StorageClass 进行动态创建,但 PVC 仍然 Pending,通常是由于 Provisioner(如 CSI 驱动程序)配置错误或其 Pod 崩溃。
如何排查:
- 检查 StorageClass 引用的 Provisioner 名称。
- 检查 Provisioner 相关的 Pod/Deployment/DaemonSet 的日志和状态。
# 检查存储驱动相关的 Pod 状态
kubectl get pods -n kube-system | grep csi
# 检查 Provisioner 的日志
kubectl logs -f <provisioner-pod-name> -n kube-system
4. 陷阱 4:容量不足或碎片化
对于静态绑定,如果 PVC 请求 10Gi,而集群中最大的可用 PV 只有 8Gi,则 PVC 无法被满足。
对于动态绑定,如果底层存储系统(如云盘或 Ceph 集群)的空间耗尽,Provisioner 将无法创建新的 PV,导致 PVC Pending。
3. 解决 PVC Pending 的标准步骤
- 描述 PVC: 运行 kubectl describe pvc
,仔细阅读 Events 部分,这是解决问题的最直接线索。 - 检查 StorageClass: 确认请求的 storageClassName 存在且配置正确。
- 检查 PV 匹配条件(静态): 如果使用静态 PV,确保 PV 的容量、accessModes 和 storageClassName 与 PVC 的请求完全匹配。
- 检查 Provisioner (动态): 如果是动态分配,确认 Provisioner Pod 健康且日志中没有创建失败的错误信息。
通过系统性地检查这些匹配条件和底层组件状态,可以快速定位并解决 PVC 持续 Pending 的问题。
汤不热吧