4. Deployment控制器:无状态应用部署、滚动更新、回滚、副本管理
Deployment 是 Kubernetes 中最核心的工作负载控制器,专门用于管理无状态应用的声明式部署与生命周期。它通过 ReplicaSet 间接管理 Pod,提供了副本管理、滚动更新、回滚、暂停/恢复等企业级运维能力。本章将深入剖析 Deployment 的工作原理与值班场景下的关键操作。
4.1 无状态应用与 Deployment 的职责边界
无状态应用(Stateless Application)是指每个请求独立、不依赖本地持久化数据的应用实例。典型的无状态应用包括 Web 前端、API 网关、微服务中的计算节点等。Deployment 专为这类场景设计,其核心职责包括:
- 副本管理:确保指定数量的 Pod 副本始终运行。
- 声明式更新:通过修改 Pod Template 触发滚动更新。
- 版本回滚:保留历史版本,支持快速回退到任意稳定版本。
- 扩缩容:手动或自动调整副本数量。
- 自愈:当 Pod 因节点故障或资源耗尽而终止时,自动重建。
4.2 Deployment 架构与核心对象关系
Deployment 并不直接管理 Pod,而是通过 ReplicaSet 实现间接控制。这种分层设计使得滚动更新和回滚操作更加灵活和可追溯。下图展示了 Deployment、ReplicaSet 与 Pod 之间的层级关系:
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(保证全部可用) |
滚动更新的执行流程如下:
- 用户修改 Pod Template(如更新镜像版本)。
- Deployment 创建一个新的 ReplicaSet,初始副本数为 0。
- 根据
maxSurge和maxUnavailable逐步创建新 Pod,同时终止旧 Pod。 - 当新 ReplicaSet 的副本数达到期望值,旧 ReplicaSet 副本数降为 0 时,更新完成。
- 旧 ReplicaSet 保留在系统中(受
revisionHistoryLimit限制),用于回滚。
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 恢复为历史版本对应的模板,然后触发一次新的滚动更新。具体流程如下:
- 用户执行
kubectl rollout undo命令。 - Deployment 控制器从历史版本中找到目标版本的 Pod Template。
- 将当前 Deployment 的 Pod Template 替换为目标版本模板。
- 触发滚动更新,逐步将 Pod 替换为目标版本。
- 回滚会触发新的滚动更新,不是瞬间完成。对于紧急故障,建议先暂停更新(
kubectl rollout pause)再执行回滚。 - 如果
revisionHistoryLimit设置过小,历史版本可能已被清理,导致无法回滚到指定版本。 - 回滚后,被回滚到的版本会成为新的当前版本,原来的最新版本会被保留在历史记录中。
4.6 更新策略对比:滚动更新 vs 重建
| 策略 | 配置方式 | 停机时间 | 适用场景 | 风险 |
|---|---|---|---|---|
| 滚动更新 | strategy.type: RollingUpdate(默认) |
无(配置合理时) | 生产环境、在线服务 | 更新速度较慢,需关注 maxUnavailable |
| 重建 | strategy.type: Recreate |
有(全部 Pod 同时终止) | 开发环境、离线任务、需要排他访问的应用 | 完全停机,可能导致服务中断 |
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 配置。