StatefulSet 持久化存储实战:PVC 生命周期、删除 Pod 不丢数据、PVC 不自动释放
2026-08-11 09:37:39 # 存储

StatefulSet 是有状态应用(数据库、消息队列、Etcd 等)在 K8s 上落地的标准方式,它的核心差异就在存储:每个 Pod 拥有独立、稳定的 PVC,Pod 重建后数据不丢。但这套机制也藏着不少”坑”。

volumeClaimTemplates 是什么

1
2
3
4
5
6
7
8
9
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: ssd
resources:
requests:
storage: 10Gi

StatefulSet 会为每个 Pod 自动创建名为 <template>-<sts-name>-<ordinal> 的 PVC,例如 data-web-0data-web-1Pod 序号与 PVC 一一绑定,这是”稳定存储”的来源。

关键行为:删除 Pod 不丢数据

  • 删除某个 Pod(kubectl delete pod web-0):PVC 保留,重建后的 web-0 重新挂载同一块盘,数据还在;
  • 删除整个 StatefulSet(kubectl delete sts web):PVC 默认也保留(除非用 --cascade=orphan 的特殊组合或显式删 PVC);
  • 真正删数据要显式删除 PVCkubectl delete pvc data-web-0

这也是线上”误删 Pod 数据还在,误删 PVC 数据没了”的根本原因。

常见运维问题

1. PVC 不自动释放(Retain 策略)

PV 的 persistentVolumeReclaimPolicyRetain 时,PVC 删了 PV 仍保留且状态 Released不能被新 PVC 复用。需手动 kubectl delete pv 并清理后端存储,或改成 Delete 策略。

2. 数据迁移 / 扩缩容

  • 缩容(如 web 从 3 副本降为 2):web-2 被删,但 data-web-2 PVC 保留,便于回滚时数据连续;
  • 跨节点迁移:RWO 卷不能直接在两节点同时挂,需先停旧 Pod 再起新 Pod,借助存储后端(如 RBD/云盘)的 detach/attach。

3. 存储类不匹配导致 Pending

StatefulSet 引用的 storageClassName 若不存在或无法供给,所有 Pod 卡 ContainerCreating。确认 StorageClass 名称与可用性。

小结

StatefulSet 的”稳定存储”= 序号化 PVC + 删除 Pod 不删 PVC;丢数据的唯一直接路径是手删 PVC。Retain 策略下记得手动回收 PV,避免存储泄漏。