2. K8s 发布基础回顾:Deployment、StatefulSet、DaemonSet、Job/CronJob 的核心发布机制

在构建自动化回滚与配置漂移修复流水线之前,必须深入理解 Kubernetes 中各类工作负载(Workload)的发布机制。不同控制器(Controller)对 Pod 的更新策略、滚动方式、回滚能力存在本质差异,直接决定了流水线的设计边界。

2.1 核心工作负载概览

Kubernetes 提供四种主要的内建工作负载 API,分别对应无状态服务、有状态服务、节点代理、以及批处理任务。下表从发布视角对比其核心差异:

工作负载类型 Pod 标识 更新策略 回滚支持 存储关联 典型场景
Deployment 随机名称(无状态) RollingUpdate / Recreate 原生支持(Revision 历史) 通常不绑定或使用 ReadWriteMany Web 服务、API 网关、微服务
StatefulSet 有序且稳定(如 web-0) RollingUpdate / OnDelete / 分区更新 原生支持(Revision 历史) 每个 Pod 绑定独立 PVC 数据库、消息队列、ZooKeeper
DaemonSet 每个 Node 一个 Pod RollingUpdate / OnDelete 原生支持(Revision 历史) 通常使用 hostPath 或 emptyDir 日志采集、监控 Agent、CNI 插件
Job / CronJob 随机名称(一次性) 无滚动更新(重新创建) 不支持回滚(可重跑) 通常不绑定 数据迁移、批处理、定时任务
关键认知: 回滚能力并非所有工作负载的标配。Job/CronJob 没有 Revision 历史机制,其“回滚”本质上是重新执行一次相同配置的任务。在流水线设计中,必须为 Job 类任务单独设计幂等性校验与重跑策略。

2.2 Deployment:无状态服务的滚动发布与回滚

Deployment 是生产环境中使用最频繁的工作负载。其核心发布机制围绕 ReplicaSet 的版本管理展开。

2.2.1 发布流程

  1. 用户修改 Deployment 的 Pod template(如镜像版本)。
  2. Deployment Controller 创建一个新的 ReplicaSet,并设置期望副本数。
  3. 新 ReplicaSet 开始启动新版本 Pod;旧 ReplicaSet 的 Pod 按 maxSurge 和 maxUnavailable 参数逐步缩容。
  4. 当新 ReplicaSet 的所有 Pod 达到 Ready 状态后,旧 ReplicaSet 缩容至 0。
  5. 每次 template 变更都会生成一个新的 Revision,存储在 .metadata.annotations 中。

2.2.2 回滚机制

Deployment 通过 kubectl rollout undo 命令或 API 触发回滚。回滚本质上是将当前 ReplicaSet 的 Pod template 替换为指定 Revision 的 template,然后重新触发一次滚动更新。

# 查看发布历史
kubectl rollout history deployment/nginx-deploy

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deploy

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deploy --to-revision=3
配置漂移风险点: 如果回滚后立即有人手动修改了 Deployment 的 replicas 或 resources 等非 template 字段,这些修改不会被回滚覆盖,导致配置漂移。流水线应强制使用 kubectl apply --server-side 并配合字段管理(Field Management)来避免此问题。

2.3 StatefulSet:有状态服务的有序发布与回滚

StatefulSet 为每个 Pod 提供稳定的网络标识和持久化存储。其发布机制必须保证有序性和数据安全。

2.3.1 有序更新策略

  • RollingUpdate(默认): 从序号最大的 Pod 开始,逐个更新。每个 Pod 更新完成后,必须进入 Ready 状态,才会更新下一个。
  • 分区更新(Partition): 通过 .spec.updateStrategy.rollingUpdate.partition 控制。序号大于等于 partition 的 Pod 会被更新,小于 partition 的 Pod 保持不变。常用于金丝雀发布或灰度升级。
  • OnDelete: 不自动更新,需要手动删除 Pod 才会触发重建。

2.3.2 回滚注意事项

StatefulSet 的回滚同样基于 Revision 历史。但由于每个 Pod 绑定独立的 PVC,回滚时需要注意:

  • 回滚不会自动删除或重建 PVC。如果新版本修改了数据格式,回滚到旧版本可能导致数据不兼容。
  • 回滚时 Pod 的更新顺序与发布时相反:从序号最大的 Pod 开始逐个回滚。
# 分区更新示例:只更新序号 >= 2 的 Pod
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
数据兼容性警告: 对于 StatefulSet 回滚,流水线必须在回滚前执行数据格式校验或 Schema 版本检查。建议在 Pod 中注入 READINESS_PROBE 来检测数据版本,避免回滚后启动失败。

2.4 DaemonSet:节点代理的平滑更新

DaemonSet 确保每个 Node 上运行一个 Pod 副本。其发布机制需要兼顾节点级别的滚动,避免影响集群整体稳定性。

2.4.1 更新策略

  • RollingUpdate(默认): 通过 maxSurge 和 maxUnavailable 控制。DaemonSet 的滚动更新是逐节点进行的,一个节点上的旧 Pod 被删除后,新 Pod 在该节点上启动并 Ready,才会继续下一个节点。
  • OnDelete: 需要手动删除每个节点上的 Pod 来触发更新。

2.4.2 回滚特性

DaemonSet 的回滚与 Deployment 类似,支持 kubectl rollout undo。回滚时,DaemonSet Controller 会按照当前节点的顺序,逐个将 Pod 替换为旧版本 template。

# 查看 DaemonSet 更新状态
kubectl rollout status daemonset/fluentd-elasticsearch

# 回滚 DaemonSet
kubectl rollout undo daemonset/fluentd-elasticsearch

2.5 Job / CronJob:批处理与定时任务

Job 和 CronJob 的设计目标是一次性执行或按计划执行,不提供滚动更新和回滚机制。

2.5.1 Job 的发布行为

  • 修改 Job 的 template 后,无法直接更新正在运行的 Job。必须删除旧 Job 并重新创建。
  • Job 的 completions 和 parallelism 参数控制并发执行数量。
  • Job 完成后,Pod 默认保留一段时间(ttlSecondsAfterFinished)用于日志查看。

2.5.2 CronJob 的发布行为

  • CronJob 每次调度时,根据当前 template 创建一个新的 Job 对象。
  • 修改 CronJob 的 template 后,下一次调度将使用新配置。正在运行的 Job 不受影响。
  • CronJob 支持 startingDeadlineSeconds 和 concurrencyPolicy(Allow/Forbid/Replace)来控制调度行为。
流水线设计建议: 对于 Job/CronJob,流水线应关注 幂等性 和 重试策略。建议在 Job 内部实现去重逻辑(如基于时间戳或业务 ID),并在流水线中增加 kubectl delete job 步骤来清理旧任务,避免资源堆积。

2.6 核心发布机制对比图

下图从 Pod 标识、更新顺序、回滚粒度三个维度,对比四种工作负载的发布机制差异:

K8s 工作负载发布机制对比 四种工作负载发布机制对比 Deployment Pod 标识:随机 更新顺序:并行/乱序 回滚粒度:ReplicaSet maxSurge/maxUnavailable Revision 历史:支持 无状态服务首选 StatefulSet Pod 标识:有序(-0,-1) 更新顺序:逆序(N→0) 回滚粒度:Revision 分区更新:Partition PVC 绑定:独立 有状态服务专用 DaemonSet Pod 标识:节点绑定 更新顺序:逐节点 回滚粒度:Revision maxSurge/maxUnavailable OnDelete 策略 节点级 Agent Job / CronJob Pod 标识:随机 更新方式:重建 回滚:不支持 重跑:幂等性 CronJob:调度创建 批处理/定时任务 核心差异总结 Deployment/StatefulSet/DaemonSet 均支持基于 Revision 的回滚;Job/CronJob 无回滚机制,需通过幂等重跑实现等效回滚。 发布流程共性: 修改 Template → 生成新 Revision → 启动新 Pod → 逐步替换旧 Pod → 完成更新 修改 Template 生成新 Revision 启动新 Pod 替换旧 Pod 更新完成

2.7 发布机制对回滚流水线的影响

基于上述分析,在设计自动化回滚流水线时,必须针对不同工作负载采取差异化策略:

工作负载 回滚触发方式 回滚前检查项 回滚后验证 配置漂移防护
Deployment kubectl rollout undo 检查旧 Revision 的 template 是否完整 Pod Ready + 健康检查 禁止手动 edit,强制 GitOps
StatefulSet kubectl rollout undo 数据格式兼容性 + PVC 状态 有序 Ready + 数据校验 禁止修改 PVC 模板
DaemonSet kubectl rollout undo 节点数量 + 资源预留 所有节点 Ready 禁止修改 nodeSelector
Job/CronJob 删除旧 Job + 重新创建 幂等性校验 + 清理残留 Job 成功完成 禁止修改 concurrencyPolicy
流水线最佳实践: 在流水线中统一使用 kubectl rollout status 来等待更新完成,并设置超时时间(如 5 分钟)。对于 StatefulSet 和 DaemonSet,建议在回滚前执行 kubectl rollout pause 来暂停自动更新,避免回滚过程中被其他控制器干扰。