Kubernetes 最好用的地方,是跑无状态应用。
什么叫无状态?
- 任意一个 Pod 死了,换新的也没关系
- 用户请求落到 A Pod 还是 B Pod 都可以
- 状态放数据库、缓存、对象存储等外部系统里
- Pod 本身就是可替换零件
典型例子:
- Web 前端
- API 服务
- 普通业务 Worker
- 网关层
这类最适合 Deployment + Service + HPA。
那什么叫有状态?
- 每个实例有独立身份
- 实例顺序有意义
- 本地持久卷绑定有意义
- 不能把 “A 的数据” 随便当成 “B 的数据” 。
- 恢复时不是“随便补一个一样的”就行
典型例子:
- MySQL / PostgreSQL
- Kafka
- ZooKeeper / etcd 类协调系统
- 某些带持久化日志的中间件
这时你要认真看 StatefulSet,而不是强行拿 Deployment 硬跑。
StatefulSet 的心智是:
Deployment 的 Pod:同型号、可互换
StatefulSet 的 Pod:同系列、但带编号、不可乱换身份一个极简 StatefulSet 骨架:
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: 20GiStatefulSet 的几个关键词:
- 稳定 Pod 名字,如
mysql-0 - 稳定网络身份
- 稳定持久卷关系
- 有序创建和删除
- 通常要配 Headless Service
一句话做边界判断:
如果你的实例是“可替换零件”,优先 Deployment;如果你的实例是“带编号资产”,考虑 StatefulSet。
很多系统最佳实践不是“把数据库也 Kubernetes 化”,而是:
- 业务服务做无状态
- 状态下沉到托管数据库 / 专业存储系统
- 让 K8s 主要管理弹性计算层
这通常更省事,也更稳。