文章中如果有图看不到,可以点这里去 csdn 看看。从那边导过来的,文章太多,没法一篇篇修改好。

【K8S】Kubernetes 中的 Deployment、DaemonSet、StatefulSet

本文将围绕 Kubernetes 中的 Deployment、DaemonSet、StatefulSet 三个核心控制器。会按以下思路来展开:

  1. 定义与使用场景
  2. 架构 & 工作机制(含 Mermaid 图)
  3. 优缺点对比
  4. 源码级(控制器循环逻辑)剖析
  5. 实际运维建议 & 常见误区

一、Deployment

1. 定义与场景

  • 定义:Deployment 是最常用的控制器,适合 无状态(stateless)应用,如 Web 服务、API 网关、微服务。

  • 典型场景

    • Nginx/Java/Python Web 服务
    • 中间层微服务(不依赖固定存储/节点)

2. 工作机制

  • Deployment 管理 ReplicaSet,ReplicaSet 再管理 Pod。
  • 通过 声明式 YAML 指定副本数、副本模板,Deployment 控制器会保证集群中实际运行的副本数和期望一致。
  • 支持 滚动升级、回滚,通过生成新的 ReplicaSet、缩容旧 ReplicaSet 实现。
Deployment
ReplicaSet v1
ReplicaSet v2
Pod-1
Pod-2
Pod-3
Pod-4

3. 优缺点

  • ✅ 优点:简单、灵活、支持滚动升级、支持 HPA 自动伸缩。
  • ❌ 缺点:不保证 Pod 的唯一性/稳定 ID,不适合需要持久化存储或固定网络标识的服务。

二、DaemonSet

1. 定义与场景

  • 定义:保证每个(或指定)节点上都运行一个 Pod。

  • 典型场景

    • 日志采集(如 Fluentd、Filebeat)
    • 监控 Agent(如 Prometheus Node Exporter)
    • 节点级系统守护进程(CNI、存储插件、驱动)

2. 工作机制

  • DaemonSet Controller 监听节点事件,当有新节点加入时,自动在该节点上启动 Pod;当节点下线,Pod 会被清理。
  • 也支持 节点选择器 / taints & tolerations,让 DaemonSet 只在特定节点上运行。
DaemonSet
Node1
Pod(Node1 Agent)
Node2
Pod(Node2 Agent)
Node3
Pod(Node3 Agent)

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),保证重启后数据不会丢失。

StatefulSet
myapp-0 Pod + PVC0
myapp-1 Pod + PVC1
myapp-2 Pod + PVC2

3. 优缺点

  • ✅ 优点:提供稳定 ID + 网络标识 + 存储绑定,适合有状态分布式应用。
  • ❌ 缺点:不支持水平扩展过快(顺序限制),扩展和升级成本比 Deployment 大。

四、三者对比(总结表)

特性Deployment (无状态)DaemonSet (节点级)StatefulSet (有状态)
适用场景Web 服务、微服务节点守护进程数据库、分布式存储
Pod 标识稳定性❌ 无保证⚠ 每节点 1 个固定✅ 稳定 ID + 网络
存储支持通常用临时存储可选配置强绑定 PVC
副本数管理自由伸缩(ReplicaSet)每节点固定 1 个有序伸缩
滚动升级 & 回滚✅ 支持⚠ 有限(逐节点替换)✅ 支持但更严格
典型应用Nginx, API 服务日志/监控 AgentKafka, 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 服务(导致不必要的复杂性)。
posted @ 2025-10-02 15:07  NeoLshu  阅读(1)  评论(0)    收藏  举报  来源