有状态应用往往是 Kubernetes 从“会发服务”走向“真正在生产里负责任”时的分水岭。数据库、消息队列、复制型存储这些系统,不只是需要 Pod 跑起来,它们还要求身份稳定、卷稳定、拓扑稳定,出事后还能恢复得回来。
有状态工作负载通常需要什么
- 稳定身份
- 持久化存储
- 有序启动和停止
- 可预期的复制行为
- 真实可执行的备份与恢复流程
这几个条件只要缺一个,系统可能仍然能启动,但运维过程会很快变得痛苦。
最常见的一套基础组合
对大多数有状态系统来说,最典型的组合是:
- StatefulSet
- 基于 PVC 的持久存储
- 通过 StorageClass 提供存储策略
- 用 Headless Service 提供稳定 DNS
- 集群外或集群级的备份恢复流程
所以这篇天然应该和下面几篇一起看:
kubernetes-quickstart-statefulset.mdkubernetes-quickstart-pv-pvc.mdkubernetes-quickstart-storageclass.mdkubernetes-quickstart-headless-service.md
为什么有状态比无状态难很多
无状态系统更关心的是“副本坏了能不能替换掉”。
有状态系统更关心的是:
- 哪个副本是谁
- 数据到底在哪
- 恢复顺序是什么
- 发布时拓扑会不会被打乱
所以真正难的通常不是 YAML 本身,而是恢复时间和操作正确性。
一开始就该问清楚的拓扑问题
在把一个有状态系统当生产级别对待之前,最好先回答这些问题:
- 它是单主还是多主?
- 客户端怎么发现主节点?
- 副本怎么追数据?
- 节点挂了以后会发生什么?
- 新旧版本能不能在升级期共存?
Kubernetes 能把工作负载跑起来,但不会替你解决数据库复制和共识问题。
存储规划本身就是应用设计的一部分
多数有状态系统都应该是一副本一 PVC。共享卷看起来省事,但除非应用本身明确支持,否则很容易引发性能或一致性问题。
这也意味着容量规划最好按副本来做,而不是只按“整套系统大概需要多少盘”来想。
备份不能只是挂在嘴上
PVC 不等于备份。
你仍然需要:
- 逻辑备份或快照
- 恢复演练
- 备份保留策略
- 把备份放到集群外
很多团队的问题不是“没有备份文件”,而是“真恢复的时候不知道顺序和时机”。
升级节奏必须更慢一点
有状态升级通常更慢,因为你要保护更多东西:
- 成员关系
- 复制延迟
- 卷 attach / mount 时间
- 预热和 readiness 时间
如果你的发布流程只适合无状态 Deployment,那它往往还不够成熟去承载真正的有状态系统。
几个特别值钱的操作习惯
- 先单副本跑顺,再扩多副本
- readiness 必须能代表真实可用性
- 尽量把副本分散到不同节点
- 监控磁盘使用率和复制延迟
- 在事故发生前写好 failover / restore 步骤
很多所谓“高可用”,最后并不是靠某个字段实现的,而是靠这些习惯慢慢堆出来的。
FAQ
Q: 数据库真的适合跑在 Kubernetes 上吗? A: 可以,但前提是你把存储、复制、恢复和升级都当成一等公民来看,而不是只把它当一个能起起来的 Pod。
Q: 有状态应用最大的风险是什么? A: 往往不是起不来,而是恢复比团队预期慢很多,或者恢复步骤本身根本没有真正演练过。
Q: 为什么恢复演练要提前做? A: 因为很多问题不是“有没有备份”,而是“能不能按正确顺序、在可接受时间内把服务恢复回来”。
下一步阅读
- 接着读
kubernetes-quickstart-statefulset.md,理解控制器层面的行为 - 再读
kubernetes-quickstart-pv-pvc.md和kubernetes-quickstart-storageclass.md,把存储链路看完整 - 如果你想看具体数据库案例,继续读 MySQL 系列 QuickStart
收个尾
有状态工作负载真正考验的不是“能不能部署”,而是“坏了之后能不能按预期恢复”。Kubernetes 能帮你把身份、调度和持久化组织起来,但恢复故事仍然必须由你自己负责。