2. Kubernetes Deployment 基础回顾

在深入故障域隔离与黄金路径边界验证之前,必须重新夯实 Deployment 的核心运行机制。Deployment 是 Kubernetes 中声明式管理无状态工作负载的顶层控制器,它通过 ReplicaSet 实现 Pod 副本的期望状态维持,并通过 滚动更新 完成版本切换。本节将拆解这三个层次,为后续的故障域建模提供精确的语义基础。

2.1 Deployment 核心概念与层级关系

Deployment 并不直接管理 Pod,而是通过 ReplicaSet 间接控制。这种分层设计使得版本回滚、扩缩容、更新策略可以独立作用于不同层级。下图展示了 Deployment → ReplicaSet → Pod 的三层控制关系:

Deployment 三层控制模型 Deployment ReplicaSet (v1) ReplicaSet (v2) Pod A1 Pod A2 Pod B1 Pod B2 Deployment 只负责声明期望状态,ReplicaSet 负责实际 Pod 数量与版本控制
关键认知:Deployment 的 spec.replicas 直接作用于当前活跃的 ReplicaSet。当触发更新时,旧 ReplicaSet 的副本数逐渐归零,新 ReplicaSet 的副本数逐渐上升。这种“双 ReplicaSet 共存”窗口期是滚动更新故障域分析的核心场景。

2.2 ReplicaSet:副本保障与选择器机制

ReplicaSet 的核心职责是确保任意时刻都有指定数量的 Pod 副本处于运行状态。它通过 Label Selector 匹配 Pod,并利用 OwnerReference 建立从属关系。

属性 说明 故障域影响
spec.replicas 期望的 Pod 副本数量 决定了故障域内 Pod 分布密度
spec.selector.matchLabels 用于匹配 Pod 的标签键值对 必须与 Pod template 标签严格一致,否则 ReplicaSet 无法接管 Pod
spec.template Pod 模板,定义容器、资源、调度约束 模板中的 topologySpreadConstraints 和 affinity 直接影响故障域隔离效果
status.availableReplicas 当前就绪的副本数 滚动更新时用于判断是否达到期望水位
SRE 视角:ReplicaSet 的 matchLabels 一旦创建不可修改。如果误配标签,会导致 ReplicaSet 无法匹配任何 Pod,造成副本数持续为 0。在故障域迁移场景中,建议使用 matchExpressions 提供更灵活的匹配逻辑。

2.3 滚动更新机制详解

滚动更新是 Deployment 默认的更新策略。它通过控制新旧 ReplicaSet 的副本数变化,实现 Pod 的平滑替换。更新过程由两个关键参数驱动:maxSurge 和 maxUnavailable。

2.3.1 滚动更新参数

参数 默认值 含义 故障域影响
maxSurge 25% 更新期间允许超出期望副本数的最大 Pod 数量 超出部分可能突破节点资源限制,引发调度失败
maxUnavailable 25% 更新期间允许不可用 Pod 的最大数量 设置过小会导致更新缓慢,设置过大会降低故障域容错能力

2.3.2 滚动更新流程

以下是一个副本数为 4、maxSurge=1、maxUnavailable=1 的典型滚动更新步骤:

  1. 创建新 ReplicaSet:Deployment 创建新 RS (v2),初始副本数为 0。
  2. 扩容新 RS:新 RS 创建 1 个新 Pod(受 maxSurge 限制),等待 Pod 进入 Ready 状态。
  3. 缩容旧 RS:新 Pod Ready 后,旧 RS (v1) 删除 1 个旧 Pod(受 maxUnavailable 限制)。
  4. 循环迭代:重复步骤 2-3,直到新 RS 达到期望副本数,旧 RS 副本数归零。
  5. 清理:旧 RS 保留在系统中(用于回滚),但副本数置为 0。
滚动更新状态转换(副本数=4, maxSurge=1, maxUnavailable=1) 阶段 1 RS(v1): 4 Pod RS(v2): 0 Pod 阶段 2 RS(v1): 4 Pod RS(v2): 1 Pod 阶段 3 RS(v1): 3 Pod RS(v2): 1 Pod 最终状态 RS(v1): 0 Pod RS(v2): 4 Pod 滚动更新关键行为 • 新 Pod 必须通过 Readiness Probe 才会被视为 Ready,否则滚动更新会阻塞 • 如果新 Pod 一直无法 Ready,Deployment 会停止扩容,旧 Pod 保持运行 • 更新过程中新旧 Pod 共存,流量可能同时路由到两个版本(取决于 Service 选择器)

2.4 更新策略对比

策略 行为 适用场景 故障域风险
RollingUpdate 逐步替换 Pod,新旧版本共存 生产环境默认策略,追求零停机 新旧 Pod 可能同时分布在同一个故障域内,导致故障域内版本不一致
Recreate 先删除所有旧 Pod,再创建新 Pod 开发环境、有状态应用、数据库迁移 更新期间服务完全不可用,故障域隔离失效
故障域隔离陷阱:滚动更新默认不感知节点拓扑。如果集群中有 3 个可用区,每个可用区 2 个节点,滚动更新可能先更新可用区 A 的所有 Pod,导致可用区 A 的旧 Pod 全部被替换。此时如果可用区 B 或 C 发生故障,流量无法被新 Pod 承接,因为新 Pod 尚未部署到其他可用区。这是后续课程中“黄金路径边界验证”要解决的核心问题之一。

2.5 回滚机制

Deployment 默认保留最近 10 个 ReplicaSet 版本(通过 spec.revisionHistoryLimit 控制)。回滚操作本质上是将 Deployment 的 Pod template 重置为历史版本,触发新一轮滚动更新。

# 查看 Deployment 更新历史
kubectl rollout history deployment/my-app

# 回滚到上一个版本
kubectl rollout undo deployment/my-app

# 回滚到指定版本
kubectl rollout undo deployment/my-app --to-revision=3
SRE 最佳实践:在故障域隔离场景中,回滚操作可能触发大规模的 Pod 重建。建议在回滚前确认当前故障域的健康状态,避免在部分节点不可用时触发回滚,导致 Pod 被调度到不健康的故障域中。

2.6 本节小结

Deployment 的三层架构(Deployment → ReplicaSet → Pod)为故障域隔离提供了天然的抽象边界。滚动更新机制虽然实现了零停机部署,但其默认的“无拓扑感知”行为可能导致 Pod 在故障域内分布不均。理解 ReplicaSet 的选择器机制、滚动更新的参数控制以及回滚的副作用,是后续设计故障域隔离策略的基础。