Kubernetes 排障实战:PVC 一直 Pending 的原因与解决方案

在 K8s 里,Pod 看起来没问题、Deployment 也正常,但 Pod 就是不启动,事件里还反复出现:

  • pod has unbound immediate PersistentVolumeClaims
  • failed to provision volume
  • PVC 状态卡在 Pending

大概率不是调度、不是镜像、不是容器启动参数------而是存储链路有问题


1. 先把概念讲清:PVC Pending 到底说明了什么?

PVC 处于 Pending 的本质含义只有一句话:

集群目前找不到可绑定的 PV,或者无法按 StorageClass 动态创建 PV。

不是"应用错了",而是"存储还没准备好"。K8s 会主动阻塞依赖该 PVC 的 Pod,避免"半启动、写坏数据"。


2. 必须了解的存储链路(排障核心)

你可以把 K8s 持久化存储理解成一条链路:
Pod → PVC → PV → 后端存储(云盘/NFS/分布式存储)

只要中间任何一环对不上,Pod 就会一直等,无法启动。


3. PVC Pending 的 3 类根因(99% 都在这里)

下面按 K8s 控制器实际决策顺序讲,排障更快。

根因 A:没有可匹配的 PV(静态供给/绑定条件不满足)

当你用的是"预创建 PV(静态)"或集群动态供给失效时,K8s 会尝试找一个满足条件的 PV:

  • 容量 ≥ PVC 请求值(如 20Gi)

  • StorageClass 匹配(或双方都不指定/同一类)

  • 访问模式匹配(如 ReadWriteOnce

  • PV 处于 Available、未被占用

典型现象

  • kubectl get pv 看不到符合条件的 Available PV

  • PVC Events 里提示找不到匹配卷(或一直无事件)

常见原因

  • 你写了 storageClassName: fast-ssd,但集群里根本没有这个 StorageClass

  • PV 有但已被绑定/处于 Released 等状态

  • PVC 请求 RWO,但后端或 PV 定义不支持

根因 B:动态路径断了(StorageClass/Provisioner/CSI 不工作)

如果 PVC 指定了 StorageClass(或走默认 StorageClass),K8s 会尝试按 StorageClass 描述去"自动创建卷"。这依赖:

  • StorageClass 存在且配置正确

  • provisioner 正确(一般是 CSI 驱动的 provisioner)

  • CSI 驱动已安装且控制面组件正常

典型现象

  • PVC Events 里出现 ProvisioningFailedfailed to provision volume

  • StorageClass 看起来"名字在",但实际不产出 PV(最迷惑)

根因 C:K8s 申请了,但后端存储拒绝了(配额/权限/后端故障)

这一类是"链路都对,但后端不让创建/创建失败",常见包括:

  • 云盘配额不足(quota exceeded)

  • 权限不足(如云厂商 IAM、vSphere 权限)

  • CSI controller 异常、组件 CrashLoop

  • 存储后端不可用(控制面能看到失败,但 PVC 仍 Pending 等待)

典型现象

  • kubectl describe pvc 的 Events 明确写了失败原因(这一步最关键)

4. 标准化排障 SOP(按这个走,基本不绕路)

Step 1:先看 PVC 的事件(不要先看 Pod 日志)

bash 复制代码
kubectl get pvc -A
kubectl describe pvc -n <namespace> <pvc-name>

重点看 Events 段,通常能直接定位到:

  • 找不到 StorageClass

  • provisioner 不存在

  • ProvisioningFailed

  • failed to provision volume

Step 2:确认 StorageClass 是否存在、是否为默认

bash 复制代码
kubectl get storageclass
kubectl get storageclass -o wide

排查点:

  • PVC 里写的 storageClassName 是否拼对、是否存在

  • 如果 PVC 没写 storageClassName:集群是否设置了默认 StorageClass((default) 标识)

  • 默认 StorageClass 的机制依赖注解 storageclass.kubernetes.io/is-default-class

典型坑(迁移/改造后高发):旧 StorageClass 名称被删了,但历史 YAML 还在引用旧名字,导致新建 PVC 全 Pending。

Step 3:检查 PV 是否存在且可绑定

bash 复制代码
kubectl get pv
kubectl get pv -o wide

你要看到的是:有 PV 处于 Available,并且它的容量/访问模式/StorageClass 能满足 PVC。

Step 4:确认 CSI 驱动与控制器日志(动态供给必做)

不同集群组件名字不一样,但思路一致:在存储相关命名空间(常见 kube-system)查看 CSI controller / provisioner 的日志。

bash 复制代码
kubectl get pods -n kube-system | grep -i csi
kubectl logs -n kube-system <csi-controller-pod>
kubectl get events -n <namespace> --sort-by=.metadata.creationTimestamp

你要找的是"后端明确拒绝"的证据:权限、配额、参数不支持、后端不可达等。


5. 对症下药修复清单(最常见、最有效)

修复 1:StorageClass 名称不对/不存在

现象 :PVC 指定了 storageClassName,但集群没有该 StorageClass。
处理

  • 改 PVC 使用正确的 StorageClass

  • 或补齐对应 StorageClass(并确保 provisioner/CSI 可用)

修复 2:集群没有默认 StorageClass(PVC 未指定时)

现象 :PVC 没写 storageClassName,集群也没有 (default) StorageClass,PVC 可能一直 Pending。
处理:设置/切换默认 StorageClass(按官方文档流程)。

修复 3:CSI 未安装或 controller 异常

现象 :Events 报 provisioning 失败,或 StorageClass 存在但"完全不出卷"。
处理

  • 确认 CSI 驱动安装完成(controller、node 组件都正常)

  • 查 controller 日志定位后端错误

修复 4:后端拒绝创建(配额/权限/后端故障)

现象failed to provision volume,日志提示 quota/permission/backend unavailable。
处理

  • 云盘配额:扩容配额或换规格/换区域策略

  • 权限:补齐 IAM/存储平台权限

  • 后端:恢复存储服务、修复 CSI controller 稳定性


6. 生产级经验:为什么"应用没动,突然全 Pending"?

一个很典型的生产事故模型:

  • 集群迁移/重装/版本升级

  • 旧 StorageClass 名称被替换或删除

  • 业务 YAML(PVC/StatefulSet)仍引用旧 storageClassName

  • 结果:新 Pod 全卡住,业务看起来像"发布失败",但根因是存储链路断了

建议做法(工程化)

  • 把 StorageClass 名称当成"接口契约",变更要做全量影响评估

  • 上线前做一条"PVC 动态供给冒烟测试"(创建一个临时 PVC 看能否自动绑定 PV)


7. 一页速查(拿去就能用)

bash 复制代码
# 1) 先看 PVC 事件(最关键)
kubectl describe pvc -n <ns> <pvc>

# 2) StorageClass 是否存在/默认是否正确
kubectl get sc
kubectl get sc -o wide

# 3) 有没有可绑定的 PV
kubectl get pv -o wide

# 4) 动态供给:查 CSI
kubectl get pods -n kube-system | grep -i csi
kubectl logs -n kube-system <csi-controller-pod>

# 5) 补充:按时间看事件流
kubectl get events -n <ns> --sort-by=.metadata.creationTimestamp
相关推荐
Linux运维技术栈2 小时前
Magento 2.3.5 宝塔Linux环境完整安装指南(避坑版+图文详解)
linux·运维·服务器
今天你TLE了吗2 小时前
JVM学习笔记:第一章——JVM&Java体系结构
java·jvm·笔记·学习
酣大智2 小时前
FTP--文件传输协议
运维·网络·网络协议·tcp/ip·华为
古月-一个C++方向的小白2 小时前
Linux——命令行参数与环境变量
linux·运维
qinyia2 小时前
使用AI助手完成服务器系统备份迁移任务
linux·运维·服务器
知行合一。。。2 小时前
Linux--10---crontab -e定时任务
java·linux·运维
德迅云安全—珍珍2 小时前
如何去判断高防服务器的防御能力是否真实可靠?
运维·服务器
后来后来啊2 小时前
2026.2.2 & 2.3学习笔记
数据结构·笔记·学习·算法·leetcode
AI视觉网奇2 小时前
ue5 绑定 鞋子 blender绑定
笔记·学习·ue5