7 月云原生存储故障复盘:那三次 PVC 挂载失败的根本原因

📅 2026/7/27 12:12:00
7 月云原生存储故障复盘:那三次 PVC 挂载失败的根本原因
7 月云原生存储故障复盘那三次 PVC 挂载失败的根本原因一、三次故障同一个信号存储层成了最薄弱的一环七月发生了三次 PVC 挂载失败的生产故障每次都表现为 Pod 卡在 ContainerCreating 状态Events 中报出Unable to attach or mount volumes。三次故障总共造成了 58 分钟的停机时间影响到 4 个推理服务和 2 个微服务。表面上看是三个独立事件但深挖后发现它们共享同一个根因模式存储容量规划和 QoS 策略跟不上工作负载的变化速度。本月的故障复盘不只是记录发生了什么更要说明为什么之前没发现和怎么保证不再发生。二、三次故障的全链条分析故障一CSI Driver 超时导致 Pod 挂载失败22 分钟时间线7 月 12 日 14:03运维部署新版 CodeLlama-34B 推理服务。Pod 卡在 ContainerCreating 21 分钟。14:24 干预后恢复。直接原因新版模型权重文件从 8GB 膨胀到 35GB。EBS CSI Driver 执行NodeStageVolume时需要将 EBS 卷从当前节点 detach 再 attach 到目标节点。35GB 的 EBS 卷 attach 耗时约 35 秒加上文件系统检查和格式化总耗时约 48 秒。但 Kubelet 的默认 volume mount 超时时间是 120 秒——看起来足够但在节点 EBS 连接数默认上限 28 个接近饱和时每个 attach 操作还需要额外的排队时间。实测排队最长达到了 95 秒加上 48 秒的操作时间总耗时 143 秒超过了 120 秒超时。为什么之前没发现旧的模型权重文件都在 10GB 以下attach 操作能在 30 秒内完成从未触发超时。因此没人注意到这个隐性约束。修复短期——将 Kubelet 的--volume-plugin-dir超时参数从 120s 调整到 300s同时在节点上限制单节点 EBS 挂载数不超过 20留出 burst 空间。长期——将模型权重存储从 PVC 挂载方案迁移到基于对象存储的缓存方案避免每次部署都挂载大卷。故障二PVC 配额不足阻塞新模型部署18 分钟时间线7 月 18 日 10:15团队部署一个新的内部微调模型需要 50GB 存储空间。PVC 一直处于 Pending 状态。10:33 排查到 StorageClass 默认配额限制后调整恢复。直接原因集群的默认 StorageClass 通过 ResourceQuota 限制了单 PVC 最大 40GB。新模型需要 50GB但 PVC 的 Events 只显示failed to provision volume with StorageClass ebs-gp3没有明确提示是配额不足还是其他原因。操作人员误以为是 CSI Driver 故障花了 15 分钟排查 CSI 日志方向才发现是配额问题。为什么之前没发现这套配额规则是年初设定的当时最大模型只有 15GB。半年来模型体积持续增长但配额从未更新。修复过程# 修复前的 ResourceQuota仅限制总数未限制单卷 apiVersion: v1 kind: ResourceQuota metadata: name: storage-quota namespace: model-serving spec: hard: persistentvolumeclaims: 20 requests.storage: 500Gi # 修复后增加突发弹性上限同时添加告警 --- apiVersion: v1 kind: ResourceQuota metadata: name: storage-quota namespace: model-serving spec: hard: persistentvolumeclaims: 30 requests.storage: 1000Gi # 增加 gp3 单卷上限到 100Gi ebs-gp3.storageclass.storage.k8s.io/requests.storage: 100Gi同时添加了 Prometheus 告警规则当 PVC 请求大小达到配额上限的 70% 时触发预警避免将来再次踩坑。故障三集群升级导致 PV 回收策略被重置18 分钟时间线7 月 25 日 03:00集群从 K8s 1.28 升级到 1.29。升级过程中节点重启部分 Pod 被驱逐。03:15 重建 Pod 时发现 3 个 PVC 处于 Lost 状态对应的 PV 已被删除。直接原因升级过程中StorageClass 的reclaimPolicy从Retain被意外重置为默认值Delete。节点重启触发 Pod 驱逐后PVC 和 PV 的绑定关系断开K8s 按照Delete策略删除了 PV。3 个模型推理服务的权重文件数据丢失。为什么之前没发现集群升级的回滚方案只覆盖了 K8s 核心组件没有覆盖 StorageClass 的配置变更验证。而且升级前没有做 PV 快照。修复第一将 StorageClass 的 reclaimPolicy 配置通过 GitOps 管理升级后自动 diff 验证第二对生产级 PVC 启用 VolumeSnapshot 定时备份每 6 小时一次第三升级脚本中加入kubectl get sc -o yaml的 pre/post 对比检查。三、存储故障的共性模式四种信号值得关注三次故障揭示了四个共性问题容量规划滞后于工作负载变化存储配额和超时参数设置后就不再更新而工作负载却在持续增长。存储配置需要和工作负载指标一起被定期 Review。错误信息质量差CSI Driver 和 Provisioner 返回的错误信息经常不够明确导致排障走错方向。需要在监控层面对存储错误做二次解析和分类。变更管理缺乏存储专项检查集群升级、模型部署、节点扩缩容都应该包含存储侧的配置验证步骤。数据备份策略覆盖不足推理服务的权重文件通常不列入备份范围因为可以重新下载但这个假设在批量故障时会导致严重的恢复延时。四、八月的改进计划与已知局限针对三次故障制订的三项改进已经在八月初上线挂载超时动态计算根据 PVC 大小和当前节点 EBS 连接数通过 admission webhook 动态计算合理的超时值而非一刀切的 120s 或 300s。PVC 生命周期监控新增pvc_pending_duration_seconds和pv_reclaim_events_total两个指标覆盖 PVC 从创建到绑定的全链路。存储故障演练每月执行一次 PVC 挂载故障的 Chaos Engineering 实验验证恢复流程的有效性。但需要承认这些措施并不能覆盖所有存储风险。例如分布式存储系统Ceph/Longhorn本身的 Bugs、云厂商存储服务的底层故障这些仍然不在我们的控制范围内。当前架构的选择是能控制的部分做到极致不能控制的部分做好容灾降级。五、总结七月三次存储故障的总影响时长 58 分钟根因分别是 CSI 超时模型膨胀触发、PVC 配额不足规划滞后和升级导致的 PV 删除变更管理缺失。三个故障的共同特征是配置和规划没能跟上工作负载的增长速度。存储层是基础设施中最容易被忽视的一层——正常情况下它默默工作但一旦出问题往往是致命级。基础设施不需要漂亮话存储层更需要在故障发生之前就把底兜住。