【K8S】Kubernetes 中的 Deployment、DaemonSet、StatefulSet
本文将围绕 Kubernetes 中的 Deployment、DaemonSet、StatefulSet 三个核心控制器。会按以下思路来展开:
- 定义与使用场景
- 架构 & 工作机制(含 Mermaid 图)
- 优缺点对比
- 源码级(控制器循环逻辑)剖析
- 实际运维建议 & 常见误区
一、Deployment
1. 定义与场景
-
定义:Deployment 是最常用的控制器,适合 无状态(stateless)应用,如 Web 服务、API 网关、微服务。
-
典型场景:
- Nginx/Java/Python Web 服务
- 中间层微服务(不依赖固定存储/节点)
2. 工作机制
- Deployment 管理 ReplicaSet,ReplicaSet 再管理 Pod。
- 通过 声明式 YAML 指定副本数、副本模板,Deployment 控制器会保证集群中实际运行的副本数和期望一致。
- 支持 滚动升级、回滚,通过生成新的 ReplicaSet、缩容旧 ReplicaSet 实现。
3. 优缺点
- ✅ 优点:简单、灵活、支持滚动升级、支持 HPA 自动伸缩。
- ❌ 缺点:不保证 Pod 的唯一性/稳定 ID,不适合需要持久化存储或固定网络标识的服务。
二、DaemonSet
1. 定义与场景
-
定义:保证每个(或指定)节点上都运行一个 Pod。
-
典型场景:
- 日志采集(如 Fluentd、Filebeat)
- 监控 Agent(如 Prometheus Node Exporter)
- 节点级系统守护进程(CNI、存储插件、驱动)
2. 工作机制
- DaemonSet Controller 监听节点事件,当有新节点加入时,自动在该节点上启动 Pod;当节点下线,Pod 会被清理。
- 也支持 节点选择器 / taints & tolerations,让 DaemonSet 只在特定节点上运行。
3. 优缺点
- ✅ 优点:节点级一致性,自动覆盖整个集群,适合做系统级任务。
- ❌ 缺点:不支持滚动版本的多副本(每节点固定 1 个),不适合用户业务应用。
三、StatefulSet
1. 定义与场景
-
定义:为 有状态(stateful)应用 提供控制器,保证 Pod 拥有 固定 ID(序号)、稳定的网络标识、持久化存储卷绑定。
-
典型场景:
- 数据库(MySQL、Postgres)
- 分布式存储系统(Cassandra、Ceph、HDFS)
- 分布式协调系统(Zookeeper、Etcd、Kafka Broker)
2. 工作机制
-
StatefulSet 的 Pod 拥有有序编号(如
myapp-0,myapp-1)。 -
Pod 启动和终止遵循严格顺序:
- 创建顺序:
-0→-1→-2 - 删除顺序:
-n→-n-1→-0
- 创建顺序:
-
每个 Pod 会绑定一个 PersistentVolumeClaim (PVC),保证重启后数据不会丢失。
3. 优缺点
- ✅ 优点:提供稳定 ID + 网络标识 + 存储绑定,适合有状态分布式应用。
- ❌ 缺点:不支持水平扩展过快(顺序限制),扩展和升级成本比 Deployment 大。
四、三者对比(总结表)
| 特性 | Deployment (无状态) | DaemonSet (节点级) | StatefulSet (有状态) |
|---|---|---|---|
| 适用场景 | Web 服务、微服务 | 节点守护进程 | 数据库、分布式存储 |
| Pod 标识稳定性 | ❌ 无保证 | ⚠ 每节点 1 个固定 | ✅ 稳定 ID + 网络 |
| 存储支持 | 通常用临时存储 | 可选配置 | 强绑定 PVC |
| 副本数管理 | 自由伸缩(ReplicaSet) | 每节点固定 1 个 | 有序伸缩 |
| 滚动升级 & 回滚 | ✅ 支持 | ⚠ 有限(逐节点替换) | ✅ 支持但更严格 |
| 典型应用 | Nginx, API 服务 | 日志/监控 Agent | Kafka, Zookeeper, MySQL |
五、控制器源码逻辑(简化版伪代码)
Deployment Controller(核心 reconcile 循环)
for {
desiredRS := getDesiredReplicaSet(deployment)
currentRSs := listReplicaSets(deployment)
scaleUpOrDown(currentRSs, desiredRS.replicas)
manageRollout(currentRSs, desiredRS) // 滚动升级逻辑
sleep(reconcileInterval)
}
DaemonSet Controller
for {
nodes := listAllNodes()
for node in nodes {
if !hasPod(node) {
createPod(node)
}
}
deletePodsOnDeletedNodes()
sleep(reconcileInterval)
}
StatefulSet Controller
for i := 0; i < replicas; i++ {
if !existsPod(i) {
createPodWithID(i)
createPVC(i)
}
}
// 删除时,逆序操作
六、如何选择 Deployment / DaemonSet / StatefulSet

七、运维建议 & 常见误区
-
Deployment:推荐所有微服务默认用 Deployment,除非明确需要状态。
-
DaemonSet:日志/监控/存储驱动必须用它,而不是 Deployment。
-
StatefulSet:别轻易用,尤其在数据库场景,最好配合 Operator(如 MySQL Operator, Kafka Operator)管理复杂逻辑。
-
常见误区:
- ❌ 用 Deployment 部署数据库(Pod 重建时丢失数据/地址变动)。
- ❌ 用 DaemonSet 跑用户应用(会导致每节点一个实例,资源浪费)。
- ❌ 用 StatefulSet 跑无状态 Web 服务(导致不必要的复杂性)。
本文来自博客园,作者:NeoLshu,转载请注明原文链接:https://www.cnblogs.com/neolshu/p/19513686

浙公网安备 33010602011771号