k8s Deployment与StatefulSet:深入理解两种控制器的区别
在 Kubernetes 中,Deployment 和 StatefulSet 是两种常用的控制器,用于管理 Pod 的部署和生命周期。尽管它们都用于管理 Pod,但它们的适用场景和行为有显著差异。以下是它们的深入对比:
1. 适用场景
-
Deployment:
- 适用于无状态应用(Stateless Applications)。
- Pod 之间没有依赖关系,可以随意创建、删除或替换。
- 典型的例子:Web 服务器、API 服务等。
-
StatefulSet:
- 适用于有状态应用(Stateful Applications)。
- Pod 之间有明确的顺序和依赖关系,每个 Pod 有唯一的标识和稳定的网络标识。
- 典型的例子:数据库(如 MySQL、PostgreSQL)、分布式存储系统(如 Zookeeper、Kafka)等。
2. Pod 标识与网络
-
Deployment:
- Pod 的名称是随机的(如
web-app-59d8c5f6c4-abcde
)。 - Pod 之间没有固定的网络标识,IP 地址可能会变化。
- Service 通常通过负载均衡将流量分发到任意 Pod。
- Pod 的名称是随机的(如
-
StatefulSet:
- Pod 的名称是固定的、有序的(如
db-0
、db-1
、db-2
)。 - 每个 Pod 有稳定的网络标识(通过 Headless Service 实现),Pod 的 DNS 名称格式为
<pod-name>.<service-name>.<namespace>.svc.cluster.local
。 - Pod 的启动、更新和删除是有序的(按顺序进行)。
- Pod 的名称是固定的、有序的(如
3. 存储
-
Deployment:
- 通常使用共享存储(如 NFS、GlusterFS)或不使用持久化存储。
- 如果使用 PersistentVolume(PV),所有 Pod 共享相同的存储卷。
-
StatefulSet:
- 每个 Pod 有独立的持久化存储(通过 PersistentVolumeClaim 模板实现)。
- 存储与 Pod 的生命周期绑定,即使 Pod 被删除,存储仍然保留。
- 适用于需要独立存储的场景(如数据库的每个实例需要独立的存储)。
4. 更新策略
-
Deployment:
- 支持滚动更新(Rolling Update),可以逐步替换旧的 Pod。
- 更新时,Pod 是无序创建的,旧的 Pod 会被新的 Pod 替换。
-
StatefulSet:
- 支持有序更新(Ordered Update),Pod 按顺序逐个更新。
- 更新时,Pod 会按照从高到低的顺序逐个替换(如
db-2
->db-1
->db-0
)。 - 也支持分区更新(Partitioned Update),可以只更新部分 Pod。
5. 扩缩容
-
Deployment:
- 扩缩容时,Pod 是无序创建或删除的。
- 可以通过
kubectl scale
命令快速调整副本数。
-
StatefulSet:
- 扩缩容时,Pod 是按顺序创建或删除的。
- 扩容时,Pod 会按顺序创建(如
db-0
->db-1
->db-2
)。 - 缩容时,Pod 会按逆序删除(如
db-2
->db-1
->db-0
)。
6. 删除行为
-
Deployment:
- 删除 Deployment 时,所有关联的 Pod 也会被删除。
- Pod 是无状态且可替换的,删除后可以重新创建。
-
StatefulSet:
- 删除 StatefulSet 时,默认不会删除关联的 Pod 和存储卷。
- 需要手动删除 Pod 和 PersistentVolumeClaim(PVC),以确保数据安全。
7. 典型配置示例
-
Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: nginx image: nginx:1.19
-
StatefulSet:
apiVersion: apps/v1 kind: StatefulSet metadata: name: db spec: serviceName: "db-service" replicas: 3 selector: matchLabels: app: db template: metadata: labels: app: db spec: containers: - name: mysql image: mysql:5.7 volumeMounts: - name: data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi
8. 总结对比
特性 | Deployment | StatefulSet |
---|---|---|
适用场景 | 无状态应用 | 有状态应用 |
Pod 标识 | 随机名称 | 固定有序名称 |
网络标识 | 不固定 | 稳定(通过 Headless Service) |
存储 | 共享或无持久化存储 | 每个 Pod 独立持久化存储 |
更新策略 | 滚动更新(无序) | 有序更新或分区更新 |
扩缩容行为 | 无序创建或删除 | 按顺序创建或删除 |
删除行为 | 删除 Deployment 会删除所有 Pod | 删除 StatefulSet 不会删除 Pod 和存储 |
9. 选择建议
- 如果你的应用是无状态的(如 Web 服务、API 服务),使用 Deployment。
- 如果你的应用是有状态的(如数据库、分布式存储),并且需要稳定的网络标识和独立的存储,使用 StatefulSet。
通过理解这两种控制器的区别,可以更好地设计和管理 Kubernetes 中的工作负载。
本文来自博客园,作者:dashery,转载请注明原文链接:https://www.cnblogs.com/ydswin/p/18326214
分类:
Kubernetes
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略