“我部署服务用的是 Deployment,数据库用 StatefulSet,但具体有什么区别?”
“Stateless、Stateful 到底指什么?”
“我可以用 Deployment 运行 Kafka 吗?”
这篇文章将用通俗语言和实际案例,深度解析 Deployment 和 StatefulSet 的区别与使用场景,让你在设计集群架构时不再迷糊。
Deployment 与 StatefulSet 简介
在 Kubernetes 中,Pod 是最小的运行单位,但我们几乎不会直接创建 Pod,而是通过控制器(Controller)来管理 Pod 的副本、重启、更新等生命周期操作。
两种常见的控制器:
控制器类型 | 用途 | 特点 |
Deployment | 管理 无状态服务,如 Web 应用、API 服务 | 灵活更新、滚动升级、自动重建 |
StatefulSet | 管理 有状态服务,如数据库、Kafka、Zookeeper | 保持稳定身份、顺序部署、持久存储 |
Deployment 管理的是“可以随时替换的工人”,StatefulSet 管理的是“有编号、带工位的员工”。
Deployment 适合什么?
Deployment 适用于大部分无状态服务:
- 前端 Web 服务
- 后端 API 网关
- 负载均衡后的业务应用
- 缓存服务(如 Redis 单节点)
- 定时任务服务
它具备的能力:
- 自动滚动升级 / 回滚
- 多副本负载均衡
- 健康检查探针支持
- 结合 Service 提供访问入口
示例配置:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v1
ports:
- containerPort: 80
特点总结:
- Pod 名称是随机生成,如 my-app-7c9d64f4f6-ljwhx
- Pod IP 变化不影响服务可用性
- 无需有状态存储、顺序启动
StatefulSet 适合什么?
StatefulSet 专为有状态服务设计,尤其适合需要:
- 稳定网络标识(Pod 名)
- 有序部署与终止(依赖顺序启动)
- 持久存储(如挂载 PVC)
- 节点间唯一身份标识
适用场景包括:
- 数据库(MySQL、PostgreSQL)
- 分布式系统(Kafka、Zookeeper、Etcd)
- 需要稳定 DNS 的服务(如 Redis Sentinel)
StatefulSet 具备的能力:
- 固定 Pod 名称(如 mysql-0, mysql-1)
- 自动挂载持久卷(每个 Pod 独立 PVC)
- 保证有序部署、升级、终止
- 结合 Headless Service 可实现 DNS 直连
示例配置:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-pvc
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
Deployment vs StatefulSet 核心对比
特性 | Deployment | StatefulSet |
Pod 名 | 随机生成 | 固定命名(如 xxx-0, xxx-1) |
Pod 顺序 | 不保证顺序 | 保证按顺序创建和删除 |
存储 | 通常使用共享存储(或无持久存储) | 每个 Pod 独立 PVC |
DNS | 无法单独访问某个 Pod | 可通过 Headless Service 直接访问某 Pod |
应用场景 | 无状态服务 | 有状态服务 |
伸缩 | 即刻扩缩容 | 按编号扩容,顺序启动 |
实际对比示意图
- Deployment:Pod 无固定身份,Service 做负载均衡
- StatefulSet:Pod 有固定身份,每个挂独立 PVC,适合有状态部署
常见误区与解答
Q1:我可以用 Deployment 来部署 Redis 吗?
- 如果你部署的是单节点 Redis 且无状态,可以。
- 如果你部署 Redis Sentinel 或主从结构,推荐使用 StatefulSet + Headless Service。
Q2:为什么我的 StatefulSet 不能并发启动所有 Pod?
- 因为 StatefulSet 默认是按编号顺序启动的,确保依赖有序(如 Kafka 依赖 Zookeeper 的顺序)。
Q3:StatefulSet 的 PVC 会自动删除吗?
- 不会。你删除 StatefulSet 时,它的 PVC 默认不会被删除,避免数据丢失。需手动清理。
总结:如何选择?
需求 | 建议 |
无状态服务,如 API、Web、前端 | Deployment |
有状态服务,如数据库、Zookeeper、Kafka | StatefulSet |
需要稳定 Pod 名、独立存储、顺序启动 | 必须用 StatefulSet |
快速滚动更新、大规模伸缩部署 | 优选 Deployment |
实战推荐练习
- 使用 Deployment 部署一个多副本的 Nginx 服务,并使用 Service 暴露;
- 使用 StatefulSet 部署三副本 MySQL,配置持久卷和 Headless Service;
- 测试 StatefulSet 扩容缩容对 Pod 命名和 PVC 的影响;