4. Deployment控制器:无状态应用部署、滚动更新、回滚、副本管理

Deployment 是 Kubernetes 中最核心的工作负载控制器,专门用于管理无状态应用的声明式部署与生命周期。它通过 ReplicaSet 间接管理 Pod,提供了副本管理、滚动更新、回滚、暂停/恢复等企业级运维能力。本章将深入剖析 Deployment 的工作原理与值班场景下的关键操作。

4.1 无状态应用与 Deployment 的职责边界

无状态应用(Stateless Application)是指每个请求独立、不依赖本地持久化数据的应用实例。典型的无状态应用包括 Web 前端、API 网关、微服务中的计算节点等。Deployment 专为这类场景设计,其核心职责包括:

  • 副本管理:确保指定数量的 Pod 副本始终运行。
  • 声明式更新:通过修改 Pod Template 触发滚动更新。
  • 版本回滚:保留历史版本,支持快速回退到任意稳定版本。
  • 扩缩容:手动或自动调整副本数量。
  • 自愈:当 Pod 因节点故障或资源耗尽而终止时,自动重建。
值班提示: Deployment 不适用于有状态应用(如数据库、消息队列)。对于需要持久化存储和稳定网络标识的工作负载,应使用 StatefulSet。

4.2 Deployment 架构与核心对象关系

Deployment 并不直接管理 Pod,而是通过 ReplicaSet 实现间接控制。这种分层设计使得滚动更新和回滚操作更加灵活和可追溯。下图展示了 Deployment、ReplicaSet 与 Pod 之间的层级关系:

Deployment 架构与对象关系图 Deployment 对象层级关系 Deployment 管理 ReplicaSet 控制 Pod (v1) Pod (v1) Pod (v1) 说明: Deployment 通过 ReplicaSet 管理 Pod 副本。每次更新会创建新的 ReplicaSet,旧版本 ReplicaSet 保留用于回滚。 一个 Deployment 可以关联多个 ReplicaSet,但只有当前版本处于活跃状态。

4.3 副本管理机制

Deployment 通过 ReplicaSet 确保 Pod 副本数量始终与期望值一致。副本管理涉及以下核心参数:

参数 位置 说明 值班场景
replicas spec.replicas 期望运行的 Pod 副本数 扩缩容时直接修改此值
selector spec.selector.matchLabels 标签选择器,用于匹配 Pod 创建后不可修改,否则导致孤儿 Pod
template spec.template Pod 模板,定义容器、资源、挂载等 更新触发滚动更新
revisionHistoryLimit spec.revisionHistoryLimit 保留的历史版本数(默认 10) 影响回滚可用版本数量
副本管理最佳实践:
  • 生产环境建议设置 replicas ≥ 2 以保证高可用。
  • 使用 kubectl scale deployment <name> --replicas=<n> 进行快速扩缩容。
  • 结合 HPA(Horizontal Pod Autoscaler)实现自动扩缩容。

4.4 滚动更新策略

滚动更新(Rolling Update)是 Deployment 默认的更新策略,它通过逐步替换旧版本 Pod 为新版本 Pod,实现零停机部署。更新策略由以下两个关键参数控制:

参数 默认值 说明 配置示例
maxSurge 25% 更新期间允许超出期望副本数的最大 Pod 数量 maxSurge: 1(数量)
maxUnavailable 25% 更新期间允许不可用的最大 Pod 数量 maxUnavailable: 0(保证全部可用)

滚动更新的执行流程如下:

  1. 用户修改 Pod Template(如更新镜像版本)。
  2. Deployment 创建一个新的 ReplicaSet,初始副本数为 0。
  3. 根据 maxSurge 和 maxUnavailable 逐步创建新 Pod,同时终止旧 Pod。
  4. 当新 ReplicaSet 的副本数达到期望值,旧 ReplicaSet 副本数降为 0 时,更新完成。
  5. 旧 ReplicaSet 保留在系统中(受 revisionHistoryLimit 限制),用于回滚。
滚动更新流程示意图 滚动更新执行流程 更新前 RS-v1: 5 Pods (100%) 更新中 RS-v1: 3 Pods (60%) RS-v2: 2 Pods (40%) 更新完成 RS-v2: 5 Pods (100%) 关键行为: 更新期间,旧 Pod 逐步终止,新 Pod 逐步创建,始终保持总副本数在期望值 ± maxSurge 范围内。 maxUnavailable=0 可保证更新期间所有请求都能被正常处理,但会降低更新速度。 maxSurge = 25% 允许临时超出期望副本数 25%,加速更新 maxUnavailable = 25% 允许最多 25% 的 Pod 不可用,平衡可用性与速度

4.5 回滚操作

当滚动更新导致应用异常时,值班工程师需要快速回滚到上一个稳定版本。Kubernetes 为 Deployment 提供了内置的回滚机制:

4.5.1 回滚命令

# 回滚到上一个版本
kubectl rollout undo deployment/<deployment-name>

# 回滚到指定版本
kubectl rollout undo deployment/<deployment-name> --to-revision=<revision-number>

# 查看部署历史
kubectl rollout history deployment/<deployment-name>

# 查看指定版本的详细信息
kubectl rollout history deployment/<deployment-name> --revision=<revision-number>

4.5.2 回滚原理

回滚操作的本质是:Deployment 将 Pod Template 恢复为历史版本对应的模板,然后触发一次新的滚动更新。具体流程如下:

  1. 用户执行 kubectl rollout undo 命令。
  2. Deployment 控制器从历史版本中找到目标版本的 Pod Template。
  3. 将当前 Deployment 的 Pod Template 替换为目标版本模板。
  4. 触发滚动更新,逐步将 Pod 替换为目标版本。
值班警告:
  • 回滚会触发新的滚动更新,不是瞬间完成。对于紧急故障,建议先暂停更新(kubectl rollout pause)再执行回滚。
  • 如果 revisionHistoryLimit 设置过小,历史版本可能已被清理,导致无法回滚到指定版本。
  • 回滚后,被回滚到的版本会成为新的当前版本,原来的最新版本会被保留在历史记录中。

4.6 更新策略对比:滚动更新 vs 重建

策略 配置方式 停机时间 适用场景 风险
滚动更新 strategy.type: RollingUpdate(默认) 无(配置合理时) 生产环境、在线服务 更新速度较慢,需关注 maxUnavailable
重建 strategy.type: Recreate 有(全部 Pod 同时终止) 开发环境、离线任务、需要排他访问的应用 完全停机,可能导致服务中断
值班建议: 生产环境始终使用滚动更新策略。如果遇到数据库 schema 变更等需要排他访问的场景,可考虑使用 Recreate 策略,但必须提前通知相关方并安排维护窗口。

4.7 值班场景:Deployment 故障排查清单

当 Deployment 出现异常时,值班工程师应按照以下清单进行排查:

步骤 命令 排查目标
1 kubectl get deployment <name> -o wide 查看 Deployment 状态、可用副本数、更新策略
2 kubectl describe deployment <name> 查看事件、条件、滚动更新状态
3 kubectl get rs -l app=<label> 查看 ReplicaSet 状态,确认新旧版本 Pod 数量
4 kubectl get pods -l app=<label> 查看 Pod 状态,确认是否有 CrashLoopBackOff、ImagePullBackOff
5 kubectl logs <pod-name> --previous 查看 Pod 崩溃前的日志
6 kubectl rollout status deployment <name> 查看滚动更新进度
7 kubectl rollout history deployment <name> 查看可回滚的版本列表

4.8 实战:Deployment 完整 YAML 示例

以下是一个生产级 Deployment 配置示例,包含了副本管理、滚动更新策略、健康检查等关键配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
  labels:
    app: web-app
    tier: frontend
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.3
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
配置要点解析:
  • revisionHistoryLimit: 5:保留最近 5 个版本用于回滚,避免历史版本过多占用 etcd 存储。
  • maxSurge: 1 和 maxUnavailable: 0:每次只多创建 1 个新 Pod,同时保证所有旧 Pod 在更新期间保持可用,适合对可用性要求极高的场景。
  • livenessProbe 和 readinessProbe:确保只有健康的 Pod 接收流量,避免将请求路由到启动中或已故障的实例。

4.9 本章小结

Deployment 控制器是 Kubernetes 无状态应用部署的基石。值班工程师需要熟练掌握以下核心能力:

  • 理解 Deployment → ReplicaSet → Pod 的三层架构关系。
  • 掌握滚动更新的参数调优,平衡更新速度与可用性。
  • 熟练使用 kubectl rollout 系列命令进行回滚操作。
  • 能够通过故障排查清单快速定位 Deployment 异常根因。
  • 编写符合生产标准的 Deployment YAML 配置。