全书目录

第十一篇:Kubernetes 完全指南 —— 星际舰队宇宙

第十一章:无状态与有状态 —— 什么时候 Deployment 对,什么时候根本不对

2 分钟 666 字 第 234 / 962 个阅读单元

Kubernetes 最好用的地方,是跑无状态应用

什么叫无状态?

  • 任意一个 Pod 死了,换新的也没关系
  • 用户请求落到 A Pod 还是 B Pod 都可以
  • 状态放数据库、缓存、对象存储等外部系统里
  • Pod 本身就是可替换零件

典型例子:

  • Web 前端
  • API 服务
  • 普通业务 Worker
  • 网关层

这类最适合 Deployment + Service + HPA


那什么叫有状态?

  • 每个实例有独立身份
  • 实例顺序有意义
  • 本地持久卷绑定有意义
  • 不能把 “A 的数据” 随便当成 “B 的数据” 。
  • 恢复时不是“随便补一个一样的”就行

典型例子:

  • MySQL / PostgreSQL
  • Kafka
  • ZooKeeper / etcd 类协调系统
  • 某些带持久化日志的中间件

这时你要认真看 StatefulSet,而不是强行拿 Deployment 硬跑。

StatefulSet 的心智是:

text
Deployment 的 Pod:同型号、可互换
StatefulSet 的 Pod:同系列、但带编号、不可乱换身份

一个极简 StatefulSet 骨架:

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-hl
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.4
          ports:
            - containerPort: 3306
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi

StatefulSet 的几个关键词:

  • 稳定 Pod 名字,如 mysql-0
  • 稳定网络身份
  • 稳定持久卷关系
  • 有序创建和删除
  • 通常要配 Headless Service

一句话做边界判断:

如果你的实例是“可替换零件”,优先 Deployment;如果你的实例是“带编号资产”,考虑 StatefulSet。

很多系统最佳实践不是“把数据库也 Kubernetes 化”,而是:

  • 业务服务做无状态
  • 状态下沉到托管数据库 / 专业存储系统
  • 让 K8s 主要管理弹性计算层

这通常更省事,也更稳。