Skip to content
Kubernetes 发布与排障主线 · 第 3 篇 / 共 4 篇
领域运维与部署
专题Kubernetes 专题
当前序列Kubernetes 发布与排障主线
阅读位置第 3 篇 / 共 4 篇当前专题第 2 个序列 / 共 3 个序列

StatefulSet、PVC、StorageClass 怎么理解

刚接触 Kubernetes 时,很多人会把这三个概念混在一起:

  • StatefulSet
  • PVC
  • StorageClass

表面看它们都和“有状态服务”有关,但真正到线上部署 MySQL、Redis、Kafka、ZooKeeper、Elasticsearch 这类组件时,如果没把三者分工想清楚,就很容易出现:

  • Pod 重建后实例身份变了,集群成员关系混乱
  • 数据盘没有正确挂回原实例,服务启动异常
  • 存储性能和业务负载不匹配,延迟忽高忽低
  • 扩容、缩容、迁移时不知道哪些对象能删,哪些不能碰

先说结论

  • StatefulSet 解决的是有状态 Pod 的稳定身份和有序管理
  • PVC 解决的是应用如何声明和绑定所需存储
  • StorageClass 解决的是底层存储资源如何被动态供应,以及性能等级和参数如何统一管理

更直接一点说:

  • StatefulSet 管的是“这个实例是谁”
  • PVC 管的是“这个实例用哪块盘”
  • StorageClass 管的是“这块盘从哪里来、性能怎样、怎么创建”

一、为什么有状态服务不能只用 Deployment

Deployment 非常适合无状态应用,因为它不关心“这个 Pod 之前是谁”,只关心副本数够不够。

但数据库、注册中心、消息队列这类组件通常不一样,它们往往依赖:

  • 稳定的实例名
  • 可预测的启动顺序
  • 与固定存储卷的绑定关系

比如你部署一个 3 节点数据库集群,节点之间可能直接依赖:

  • 固定主机名
  • 固定副本编号
  • 固定数据目录

如果 Pod 每次漂移后名字和挂载关系都变了,集群恢复和排障成本会非常高。

二、StatefulSet 的核心价值是什么

StatefulSet 最大的价值,不是“它比 Deployment 高级”,而是它提供了有状态服务最看重的三件事。

1. 稳定网络标识

每个 Pod 都有稳定编号,例如:

  • mysql-0
  • mysql-1
  • mysql-2

实例重建后名字不变,域名也可预测,这对集群成员发现很重要。

2. 有序启动与有序终止

很多有状态组件不是所有节点同时起来就最好,而是有主从、仲裁、初始化顺序要求。StatefulSet 可以按顺序拉起和销毁,减少集群初始化混乱。

3. 与持久化卷形成稳定关系

某个 Pod 对应的卷声明通常也会稳定存在。Pod 重建后,仍然更容易挂回原来那块数据卷。

三、PVC 到底在解决什么

PVC 可以理解成应用对存储的“需求单”。

应用不需要直接写死:

  • 云盘 ID 是什么
  • 存储设备在哪个节点
  • 底层驱动如何创建卷

它只需要声明:

  • 要多大容量
  • 需要什么访问模式
  • 想要哪一类存储

然后由集群去完成绑定。

PVC 的意义不是只为了“能挂盘”,而是把应用声明和底层存储实现解耦。

这件事在线上很重要,因为同一套业务在不同环境里可能用到的底层存储并不完全一样:

  • 测试环境可能是本地盘或 NFS
  • 生产环境可能是云硬盘、SSD、ESSD
  • 某些分析场景还可能接对象存储或分布式文件系统

有了 PVC,应用配置更稳定,环境切换也更可控。

四、StorageClass 为什么不能省

如果没有 StorageClass,PVC 往往只能依赖手工创建好的 PV。小规模还能维护,规模一上来问题就很多:

  • 创建流程重
  • 环境一致性差
  • 存储参数分散
  • 团队很难统一“什么业务该用什么盘”

StorageClass 的价值在于把这层能力标准化。

它通常会约束一组存储策略:

  • 使用哪种卷类型
  • 是否动态创建
  • 回收策略是什么
  • 扩容是否支持
  • 性能等级如何

这样应用只要在 PVC 里选中对应的 StorageClass,就能拿到一类符合预期的卷。

五、把三者串起来看,就容易多了

更实用的理解方式不是分别背概念,而是顺着一个具体实例去看。

例如部署一个 3 节点的 Kafka 或 MySQL 集群时:

  1. StatefulSet 决定会有 xxx-0xxx-1xxx-2 这几个稳定实例。
  2. 每个实例会生成自己的 PVC,例如 data-xxx-0data-xxx-1
  3. 这些 PVC 按指定 StorageClass 动态申请对应类型的云盘。
  4. 某个 Pod 异常重建后,会尽量重新挂回它之前绑定的卷。

这样你就能理解:

  • 实例身份稳定和存储稳定并不是一回事
  • 但它们必须一起设计,集群才能恢复得稳

六、实战里最常见的几个坑

1. 以为 StatefulSet 自带数据安全

StatefulSet 只帮助你稳定管理实例,不等于自动有备份、容灾、跨可用区复制能力。真正的数据安全仍要靠业务组件自身复制机制和备份策略。

2. 把所有有状态服务都塞进同一种 StorageClass

不同业务对延迟、吞吐、IOPS、成本要求差别很大。数据库日志盘、消息队列数据盘、分析引擎冷热数据,通常不该混用一套存储等级。

3. 缩容或删除时没分清对象生命周期

很多事故都发生在“以为删的是 Pod,结果把卷一起处理了”或者“以为换个 YAML 不影响卷,结果 PVC 绑定关系被打乱”。

4. 只关注正常启动,不演练故障恢复

真正有价值的验证不是“第一次部署能起来”,而是:

  • 节点宕机后能否自动重建
  • Pod 漂移后是否还能正确挂回数据
  • 单卷损坏时恢复流程多长
  • 扩容和回滚是否会影响已有实例

七、什么时候适合用,什么时候要谨慎

更适合用 StatefulSet + PVC 的场景:

  • MySQL、PostgreSQL、MongoDB
  • Kafka、ZooKeeper
  • Elasticsearch、ClickHouse
  • Redis Sentinel 或 Cluster 中部分节点
  • 任何依赖稳定节点身份和持久化数据的服务

要谨慎的地方在于:

  • 不要因为“看起来正规”就把原本无状态的服务也迁成 StatefulSet
  • 不要把 Kubernetes 的卷能力理解成数据库高可用的全部方案
  • 不要忽视云盘性能、快照、备份、容灾这些更底层的问题

八、线上排查时更建议怎么判断

如果线上有状态服务出现异常,可以先按这个顺序看:

  1. Pod 身份是否稳定,是否发生了异常重建或漂移。
  2. PVC 是否正常绑定,事件里有没有挂载失败、权限异常、容量不足。
  3. StorageClass 对应的底层卷类型和性能是否满足当前负载。
  4. 服务异常是来自 Pod 层,还是来自业务本身的主从复制、选主、恢复逻辑。
  5. 最后再决定是调度问题、存储问题还是组件级别问题。

一句话总结

可以把这三个对象记成一条完整链路:StatefulSet 负责稳定实例身份,PVC 负责稳定表达存储需求,StorageClass 负责把底层存储能力标准化。

当你部署数据库、消息队列或搜索集群时,真正要看的不是“对象有没有配齐”,而是实例身份、卷绑定、性能等级和故障恢复路径是否形成了闭环。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读Pod Pending 和 CrashLoopBackOff 怎么排查适合把网络、发布策略、持久化和 Pod 故障排查放到一起看。Kubernetes 专题 · Kubernetes 发布与排障主线同一序列 · 回看前文会更完整RollingUpdate、Blue Green、Canary 怎么选适合把网络、发布策略、持久化和 Pod 故障排查放到一起看。Kubernetes 专题 · Kubernetes 发布与排障主线同专题其他序列 · 共享标签:部署交付节点污点、亲和性和拓扑 spread 怎么组合适合把命名空间、回滚、PDB、HPA、Mesh 和调度约束放在一条 Kubernetes 治理主线上整理。Kubernetes 专题 · Kubernetes 编排约束与交付治理同专题其他序列 · 共享标签:部署交付Deployment 回滚到底依赖了什么信息适合把命名空间、回滚、PDB、HPA、Mesh 和调度约束放在一条 Kubernetes 治理主线上整理。Kubernetes 专题 · Kubernetes 编排约束与交付治理跨专题关联 · 同场景:部署交付标签基数为什么会拖垮 Prometheus适合把 Prometheus、Grafana、标签治理和告警分级放在一起看。可观测性专题 · 指标与告警体系设计跨专题关联 · 同场景:部署交付多环境发布怎么设计:开发、测试、预发、生产不只是名字不同适合沿着流水线设计、自动部署、发布策略、数据库变更和多环境治理这条线往下读。CI/CD 与发布治理专题 · CI/CD 与发布治理
继续阅读Kubernetes 发布与排障主线当前序列第 3 篇 / 共 4 篇当前专题第 2 个序列 / 共 3 个序列
往前看
上一篇RollingUpdate、Blue Green、Canary 怎么选回到当前序列上一章上一序列Kubernetes 核心对象与资源治理从第 1 篇开始:Pod、Deployment、Service 到底怎么协作
往后看
下一篇Pod Pending 和 CrashLoopBackOff 怎么排查继续当前序列下一章下一序列Kubernetes 编排约束与交付治理从第 1 篇开始:Namespace、Label 和 Annotation 该怎么分工

把零散经验整理成可查、可复用、可持续更新的企业级知识门户