尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Kubernetes生产运维09:PVC一直Pending或挂载失败,怎么分清是制备、绑定还是挂载的问题

Kubernetes生产运维09:PVC一直Pending或挂载失败,怎么分清是制备、绑定还是挂载的问题 Kubernetes生产运维09PVC一直Pending或挂载失败怎么分清是制备、绑定还是挂载的问题写在前面存储出问题时常见的两种现象是PVC一直Pending或者Pod卡在ContainerCreating报FailedMount。很多人不区分这两者一律去删PVC重建结果可能触发数据回收风险很大。其实这两种现象位于存储链路的不同阶段PVC PendingPVC还没绑定到PV。可能是StorageClass的provisioner异常、动态制备失败、没有匹配的静态PV或者绑定模式在等Pod调度。问题在制备和绑定阶段。挂载失败FailedMountPVC已经绑定但Pod所在节点挂载卷失败。可能是AccessMode冲突、CSI驱动异常、卷已被其他节点占用或权限问题。问题在挂载阶段。先区分是Pending还是挂载失败就能把排查分成绑定前和绑定后两大类。因此存储排查沿着这条链路逐段确认存储报错 → 先看PVC是Pending还是Bound → Pending查StorageClass、provisioner、PV匹配和绑定模式 → Bound但Pod挂载失败查AccessMode、CSI、拓扑和权限 → 结合PVC事件、PV和节点事件定位 → 针对性修复并验证 → 补存储监控与配置校验本文按照Kubernetes官方机制和命令参考整理。由于当前没有连接可验证的实验集群命令没有在统一版本的真实集群完整执行案例和终端输出均为C级生产化重建不是生产原始记录。不同Kubernetes版本、CSI驱动、云厂商存储和拓扑配置可能改变字段、事件和行为执行前应以目标集群和CSI文档为准。存储操作风险高删除PVC或PV前务必确认数据和回收策略。一、先理解PVC到卷的链路1.1 动态制备的过程大多数生产集群用动态制备Pod引用PVC → PVC引用StorageClass → StorageClass的provisioner动态创建后端卷 → 生成PV并与PVC绑定 → Pod调度到节点后CSI在节点上挂载卷 → 容器使用挂载点任何一步断了都可能报错但PVC状态和事件会提示位置。1.2 PVC Pending和挂载失败的分工现象大致含义断点位置PVC Pending未绑定PV制备器、StorageClass、PV匹配、绑定模式Pod ContainerCreating FailedMountPVC已绑定但节点挂载失败AccessMode、CSI、拓扑、权限Pod ContainerCreating FailedAttachVolume卷附加到节点失败CSI attach、云盘限制、节点先看PVC是Pending还是Bound就能确定往绑定前还是绑定后查。1.3 绑定模式决定绑定时机StorageClass的volumeBindingMode是PVC问题里最容易踩的点ImmediatePVC创建后立即绑定或制备PV。在多可用区环境卷可能落在一个区而Pod被调度到另一个区造成volume node affinity conflict。WaitForFirstConsumer延迟到Pod首次被调度时才绑定让存储拓扑跟随Pod位置。更适合多可用区但如果目标区没有容量或CSI异常PVC仍会Pending。看到PVC Pending时先看StorageClass的绑定模式能快速判断是等Pod调度还是真的制备不出来。1.4 AccessMode决定谁能挂载ReadWriteOnce卷只能被单个节点读写挂载。多个Pod如果被调度到不同节点争用同一个RWO卷后来的会挂载失败。ReadOnlyMany、ReadWriteMany可多节点但要求后端存储支持。ReadWriteOncePod只能被单个Pod使用。很多FailedMount是RWO卷被多节点争用或后端不支持声明的AccessMode导致的。二、存储排查决策树存储报错 │ ├─ PVC是Pending还是Bound │ ├─ Pending → 绑定前问题 │ │ ├─ StorageClass不存在或provisioner异常 │ │ ├─ WaitForFirstConsumer在等Pod调度 │ │ ├─ 没有匹配的静态PV容量、AccessMode、selector │ │ ├─ 拓扑冲突或目标区无容量 │ │ └─ ResourceQuota限制存储 │ └─ Bound但Pod起不来 → 绑定后问题 │ ├─ FailedMountAccessMode冲突、CSI、权限 │ ├─ FailedAttachVolumeCSI attach、云盘数量上限 │ └─ volume node affinity conflict卷拓扑与节点不符 │ ├─ 结合PVC、PV和节点事件定位 │ ├─ 针对性修复并验证 │ └─ 补存储监控与校验先看PVC状态NSnamespacePVCpvc-namekubectl get pvc$PVC-n$NS-owide kubectl describe pvc$PVC-n$NSSTATUS是Pending往绑定前查是Bound但Pod报FailedMount往绑定后查。三、取证Pending分支3.1 看PVC事件和StorageClasskubectl get pvc$PVC-n$NS\-ojsonpath{status}{.status.phase}{\nsc}{.spec.storageClassName}{\naccessModes}{.spec.accessModes}{\nrequest}{.spec.resources.requests.storage}{\n}SCstorage-classkubectl get storageclass$SC-oyaml关注PVC事件里的具体原因如waiting for first consumer、provisioning failed、no persistent volumes availableStorageClass是否存在provisioner是什么volumeBindingMode是Immediate还是WaitForFirstConsumer3.2 区分Pending的几种原因PVC事件线索更可能的原因优先检查waiting for first consumer to be created绑定模式是WaitForFirstConsumerPod是否已创建并可调度failed to provision volumeprovisioner制备失败CSI控制器日志、云配额、权限no persistent volumes available for this claim无匹配静态PV或动态制备未触发PV容量、AccessMode、StorageClassstorageclass not foundStorageClass名写错或不存在PVC的storageClassName、集群StorageClassexceeded quotaResourceQuota限制存储命名空间存储配额WaitForFirstConsumer模式下PVC在Pod调度前保持Pending是正常的不是故障。要先确认引用这个PVC的Pod是否已经创建。如果Pod也Pending比如调度不上PVC自然一直等。3.3 查provisioner和PV# 动态制备时看CSI控制器kubectl get pods-ncsi-namespace-owide kubectl logs-ncsi-namespacecsi-controller-pod--tail100# 静态PV时看是否有匹配的可用PVkubectl getpv动态制备失败看CSI controller日志常见云配额不足、权限缺失、参数错误静态PV确认有Available状态、容量足够、AccessMode匹配、无claimRef冲突的PV3.4 边界WaitForFirstConsumer的Pending可能是正常等待不要误判为故障CSI命名空间和Pod名因驱动而异需按实际调整provisioner日志可能包含云凭据和内部信息分享前脱敏四、取证挂载失败分支PVC已Bound但Pod起不来时看Pod事件PODpod-namekubectl describe pod$POD-n$NS关注Events里的挂载相关错误事件线索更可能的原因优先检查FailedMountMulti-Attach errorRWO卷被多节点争用卷AccessMode、旧Pod是否还占用FailedMounttimeoutCSI node挂载慢或异常CSI node Pod、节点日志FailedAttachVolume卷附加失败CSI attach、云盘数量上限volume node affinity conflict卷拓扑与节点不符PV NodeAffinity、Pod调度区permission denied相关权限或fsGroupsecurityContext、fsGroup、后端权限4.1 Multi-Attach是最常见的挂载失败RWO卷同一时刻只能挂在一个节点。滚动发布或Pod重建时如果旧Pod还没完全释放卷、新Pod又被调度到另一个节点就会出现Multi-Attach error。这在RWO卷加RollingUpdate时尤其常见。处理方向让新旧Pod调度到同一节点或用Recreate策略或使用支持多节点的存储而不是简单删PVC。4.2 查CSI和PVkubectl get pods-ncsi-namespace-lcsi-node-label-owide kubectl getpvpv-name-oyamlCSI node Pod要在目标节点上正常运行PV的NodeAffinity要和Pod调度的节点一致确认卷没有卡在被其他节点占用的状态五、C级生产化重建案例多可用区下PVC一直Pending5.1 先说明哪些是真的哪些是重建的下面不是作者声称亲历的生产事故而是根据Kubernetes存储绑定模式和拓扑机制构造的生产化重建用于展示从PVC Pending走到可验证根因的取证过程。内容证据属性PVC、StorageClass、绑定模式和拓扑绑定的机制Kubernetes官方机制StatefulSet的PVC在多可用区一直Pending机制一致的重建场景Namespace、资源名、可用区、容量和终端输出为讲解构造的说明性信息StorageClass用Immediate且卷落在无节点的可用区模拟根因不是作者生产记录改绑定模式后验证PVC绑定受控验证设计不声称已在当前集群执行所有输出按真实对象关系编排但没有连接实际集群采集读者不能把下面的可用区、容量或输出引用为真实事故数据。5.2 现场卡片一个StatefulSet在多可用区集群里部署部分副本的PVC一直PendingPod卡在Pending起不来。团队最初怀疑存储配额不够。重建的相对时间线相对时间观察或动作当时能够得出的结论T00部分副本Pod和PVC都Pending只能确认存储未就绪原因未知T03怀疑存储配额不足待验证假设T06PVC事件提示无法在目标区制备卷转向拓扑和绑定模式T09发现StorageClass是Immediate得到可验证的主假设T验证改用WaitForFirstConsumer后观察PVC绑定单变量验证相对时间只表示排查顺序不代表真实数值。5.3 先确认PVC是PendingNSexample-prodPVCdata-web-2 kubectl get pvc$PVC-n$NS-owide机制一致的说明性输出NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE>5.4 看PVC事件和StorageClasskubectl describe pvc$PVC-n$NSkubectl get storageclass fast-ssd-ojsonpath{provisioner}{.provisioner}{\nbindingMode}{.volumeBindingMode}{\n}机制一致的说明性输出PVC Events节选 ProvisioningFailed failed to provision volume: requested zone has no available capacity provisionerebs.csi.aws.com bindingModeImmediate关键发现绑定模式是ImmediatePVC创建即尝试在某个区制备卷事件提示目标区没有可用容量provisioner本身正常是拓扑选择问题5.5 确认节点分布与拓扑kubectl get nodes-Ltopology.kubernetes.io/zone kubectl getpv|grepfast-ssd机制一致的说明性输出NAME ZONE node-a us-east-1a node-b us-east-1a node-c us-east-1b发现集群节点主要在1a和1b而Immediate模式把这个PVC的卷制备请求落到了没有可用节点或容量的区。因为Immediate在Pod调度前就绑定无法感知Pod最终会去哪个区。证据链PVC Pending未绑定卷 事件提示目标区无容量 provisioner正常 StorageClass是Immediate绑定早于调度 节点集中在特定区卷落到了不匹配的区 强烈支持Immediate绑定模式在多可用区导致拓扑不匹配这仍是主假设验证前不写成根因已闭环。5.6 止损与单变量验证不要删除已有PVC来重试,StatefulSet的PVC删除可能触发数据回收。正确做法是修正StorageClass的绑定模式。注意StorageClass的多数字段不可变,通常需要新建一个WaitForFirstConsumer的StorageClass,让新PVC使用,而不是原地改。单变量验证只改绑定模式这一项新建StorageClassapiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:fast-ssd-topologyprovisioner:ebs.csi.aws.comvolumeBindingMode:WaitForFirstConsumerparameters:type:gp3让新的StatefulSet或PVC模板引用fast-ssd-topology其余配置不变。验证并保存修复后证据kubectl apply-ffast-ssd-topology-sc.yaml# 新PVC使用新StorageClass后观察kubectl get pvc-n$NS-owide kubectl describe pvcnew-pvc-n$NS机制一致的说明性输出NAME STATUS VOLUME CAPACITY STORAGECLASS AGE>5.7 根因闭环条件修正版与问题版只有绑定模式这一项主要差异。修正后PVC按Pod所在区制备并Bound。provisioner在修正前后都正常排除制备器本身故障。Pod从Pending变为正常调度启动。观察窗口内新副本PVC稳定绑定没有反复Pending。如果改成WaitForFirstConsumer仍Pending就要停止把绑定模式当作唯一原因转查目标区容量、CSI和配额。六、修复方案要分六层层次本文场景中的动作关键边界应急止损为新工作负载切换到拓扑感知的StorageClass不删除已有PVC避免数据风险现场取证保存PVC、StorageClass、PV、CSI日志和节点拓扑provisioner日志可能含凭据需脱敏根因验证只改绑定模式一个变量并观察PVC绑定不同时改容量、provisioner和AccessMode永久修复在源配置使用WaitForFirstConsumer的StorageClassStorageClass多数字段不可变需新建监控预防监控PVC Pending时长、制备失败和挂载失败区分正常等待和真实失败运行治理存储类规范、拓扑约定、容量基线和Runbook多可用区默认用拓扑感知绑定删除PVC或PV是高风险操作可能触发回收策略删除底层数据。任何重建都必须先确认ReclaimPolicy、数据所有权、备份和快照。临时恢复不等于根因确认PVC绑定成功只说明变更与故障相关仍需拓扑证据和单变量验证支撑。七、可直接使用的只读存储采集脚本脚本只读取对象和事件不删除PVC或PV、不改StorageClass、不重启CSI。#!/usr/bin/env bashset-uset-opipefailNS${1:?用法:$0 namespace pvc-name[pod-name]}PVC${2:?用法:$0 namespace pvc-name[pod-name]}POD${3:-}STAMP$(date%Y%m%d-%H%M%S)OUTpvc-evidence-${NS}-${PVC}-${STAMP}mkdir-p$OUTumask077capture(){localfile$1shiftprintf采集 %s\n$fileif!$$OUT/$file2$OUT/$file.err;thenprintf失败: %s查看 %s.err\n$file$file2fi}capture context.txt kubectl config current-context capture version.txt kubectl version capture pvc.yaml kubectl get pvc$PVC-n$NS-oyaml capture pvc-describe.txt kubectl describe pvc$PVC-n$NScapture storageclasses.yaml kubectl get storageclass-oyaml capture pv.txt kubectl getpv-owide capture nodes-zone.txt kubectl get nodes\-Ltopology.kubernetes.io/zone capture events.txt kubectl get events-n$NS\--field-selectorinvolvedObject.kindPersistentVolumeClaim,involvedObject.name$PVC\--sort-by.metadata.creationTimestampSC$(kubectl get pvc$PVC-n$NS-ojsonpath{.spec.storageClassName}2/dev/null||true)if[[-n$SC]];thencapturestorageclass-${SC}.yamlkubectl get storageclass$SC-oyamlfiif[[-n$POD]];thencapture pod-describe.txt kubectl describe pod$POD-n$NScapture pod-events.txt kubectl get events-n$NS\--field-selectorinvolvedObject.kindPod,involvedObject.name$POD\--sort-by.metadata.creationTimestampfiprintf采集完成: %s\n$OUTprintfCSI控制器和节点日志请按实际驱动命名空间另行采集\nprintf删除PVC或PV属高风险操作本脚本不执行\nprintf分享前请检查地址、凭据和配置引用中的敏感信息\n使用方式bashcollect-pvc-evidence.shnamespacepvc-namepod-name脚本边界CSI控制器和节点日志命名空间因驱动而异脚本不猜测需另行采集WaitForFirstConsumer的Pending可能是正常等待脚本只做只读采集不涉及任何删除操作脚本用于保存首轮现场不能替代按状态选择下一步八、监控、容量与治理8.1 监控什么PVC处于Pending的时长和数量动态制备失败和挂载失败事件各可用区的存储容量和配额CSI控制器和节点Pod健康卷Multi-Attach和FailedAttach事件告警要区分正常等待和真实失败。WaitForFirstConsumer的短暂Pending是正常的应按持续时长和事件类型判断。8.2 配置规范多可用区默认使用WaitForFirstConsumer的StorageClassAccessMode与后端存储能力和工作负载匹配RWO卷避免多节点争用RWO卷配合Recreate或同节点调度减少Multi-AttachStorageClass、provisioner参数纳入模板校验8.3 容量与数据安全监控各区存储容量避免制备时无容量明确PV的ReclaimPolicy重要数据用Retain并有备份删除PVC或PV走审批确认数据和快照CSI驱动升级走灰度和验证九、常见误区误区1PVC Pending就删了重建删除PVC可能触发回收删除数据先看是不是WaitForFirstConsumer的正常等待。误区2把WaitForFirstConsumer的等待当故障这种模式下Pod调度前PVC保持Pending是正常的。误区3多可用区用ImmediateImmediate在Pod调度前绑定容易造成卷和节点区不匹配。误区4RWO卷用RollingUpdate新旧Pod在不同节点会Multi-Attach冲突考虑Recreate或同节点。误区5挂载失败只看Pod不看CSIFailedMount和FailedAttach常需要看CSI节点和控制器。误区6声明后端不支持的AccessMode后端不支持RWX却声明RWX挂载会失败。误区7忽略PV的NodeAffinity卷拓扑和Pod节点不符会volume node affinity conflict。误区8改StorageClass期望原地生效StorageClass多数字段不可变通常要新建再让新PVC引用。十、面试怎么说60秒版本存储问题我先看PVC是Pending还是Bound。Pending是绑定前问题查StorageClass、provisioner、PV匹配和绑定模式注意WaitForFirstConsumer在Pod调度前Pending是正常的。Bound但Pod起不来是挂载问题查AccessMode冲突、CSI、拓扑和权限最常见的是RWO卷被多节点争用的Multi-Attach。修复只改一个变量并验证绝不轻易删PVC因为可能触发数据回收。最后按Pending时长和挂载失败事件分层监控。3分钟场景版本假设StatefulSet在多可用区部署部分PVC一直Pending。我先确认PVC是Pending没绑卷属绑定前问题。看PVC事件提示目标区没容量StorageClass是Immediate。再看节点拓扑节点集中在特定区而Immediate在Pod调度前就绑卷无法感知Pod最终去哪个区导致卷落到不匹配的区。根因是绑定模式不适合多可用区。我不会删PVC而是新建一个WaitForFirstConsumer的StorageClass让新PVC引用只改绑定模式这一个变量。新PVC先等Pod调度再按Pod所在区制备卷最终Bound、Pod启动。这样我能区分是绑定模式问题而不是配额或制备器故障也避免了删PVC带来的数据风险。十一、延伸问答1. PVC Pending一定是故障吗不一定。WaitForFirstConsumer模式下Pod调度前PVC保持Pending是正常的。2. Immediate和WaitForFirstConsumer怎么选多可用区优先WaitForFirstConsumer让卷跟随Pod单区或需要提前制备可用Immediate。3. Multi-Attach error是什么RWO卷同一时刻只能挂在一个节点多节点争用时报此错常见于RWO加RollingUpdate。4. 为什么不能随便删PVC删除可能触发PV的回收策略删除底层数据属高风险要先确认ReclaimPolicy和备份。5. StorageClass能原地改绑定模式吗多数字段不可变通常要新建StorageClass让新PVC引用。6. volume node affinity conflict怎么处理卷拓扑和Pod节点区不符检查PV的NodeAffinity和Pod调度约束或用拓扑感知绑定。7. 挂载失败怎么区分是CSI还是权限看Pod事件Multi-Attach和attach类多是卷占用或CSIpermission类多是fsGroup和后端权限。8. 制备失败先看什么看CSI控制器日志常见云配额不足、权限缺失或参数错误。小结存储问题先分PVC是Pending还是Bound定位绑定前还是绑定后。Pending查StorageClass、provisioner、PV匹配和绑定模式。WaitForFirstConsumer的Pending可能是正常等待。多可用区优先用WaitForFirstConsumer避免拓扑不匹配。挂载失败常见RWO卷Multi-Attach、CSI和权限问题。StorageClass多数字段不可变改绑定模式通常要新建。绝不轻易删PVC或PV可能触发数据回收。长期治理覆盖拓扑感知存储类、AccessMode规范、容量监控和数据安全。下一篇预告下一篇进入Node NotReady与节点异常。我们会沿着kubelet、容器运行时、磁盘、网络、证书和节点压力区分节点失联、组件异常和资源耗尽并整理一份节点恢复流程。参考资料Kubernetes官方文档Persistent VolumesKubernetes官方文档Storage ClassesKubernetes官方文档Dynamic Volume ProvisioningKubernetes官方文档VolumesKubernetes官方文档Storage CapacityKubernetes官方文档Node-specific Volume LimitsKubernetes官方文档Configure a Pod to Use a PersistentVolume for StorageKubernetes官方文档Change the Reclaim Policy of a PersistentVolumeKubernetes官方文档Debug PodsKubernetes CSI官方文档
返回列表