CFN Cloud
2025-10-07

Kubernetes 上运行有状态应用:存储、身份与运维要点

从数据库和消息系统等场景出发,理解 Kubernetes 上有状态应用的部署方式、风险点与运维重点。

有状态应用往往是 Kubernetes 从“会发服务”走向“真正在生产里负责任”时的分水岭。数据库、消息队列、复制型存储这些系统,不只是需要 Pod 跑起来,它们还要求身份稳定、卷稳定、拓扑稳定,出事后还能恢复得回来。

有状态工作负载通常需要什么

  • 稳定身份
  • 持久化存储
  • 有序启动和停止
  • 可预期的复制行为
  • 真实可执行的备份与恢复流程

这几个条件只要缺一个,系统可能仍然能启动,但运维过程会很快变得痛苦。

最常见的一套基础组合

对大多数有状态系统来说,最典型的组合是:

  • StatefulSet
  • 基于 PVC 的持久存储
  • 通过 StorageClass 提供存储策略
  • 用 Headless Service 提供稳定 DNS
  • 集群外或集群级的备份恢复流程

所以这篇天然应该和下面几篇一起看:

  • kubernetes-quickstart-statefulset.md
  • kubernetes-quickstart-pv-pvc.md
  • kubernetes-quickstart-storageclass.md
  • kubernetes-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.mdkubernetes-quickstart-storageclass.md,把存储链路看完整
  • 如果你想看具体数据库案例,继续读 MySQL 系列 QuickStart

收个尾

有状态工作负载真正考验的不是“能不能部署”,而是“坏了之后能不能按预期恢复”。Kubernetes 能帮你把身份、调度和持久化组织起来,但恢复故事仍然必须由你自己负责。

参考链接