Kubernetes 滚动升级原理:ReplicaSet、Deployment 与更新策略
滚动升级(Rolling Update)是 Kubernetes 中实现无宕机应用更新的核心机制。其底层依赖 ReplicaSet 与 Deployment 控制器的协同工作,并通过 maxSurge 和 maxUnavailable 两个参数精确控制更新速率与资源消耗。理解这三者的关系,是后续进行 Prometheus 监控与故障排查的基础。
2.1 核心组件:ReplicaSet 与 Deployment
Deployment 并不直接管理 Pod,而是通过管理 ReplicaSet 来间接控制 Pod 的副本数量与版本。每次更新都会创建一个新的 ReplicaSet,并逐步调整新旧 ReplicaSet 的副本数。
| 组件 | 职责 | 滚动升级中的角色 |
|---|---|---|
| Pod | 运行容器化应用的最小单元 | 被替换的对象,每次更新会创建新版本 Pod,销毁旧版本 Pod |
| ReplicaSet | 确保指定数量的 Pod 副本始终运行 | 每个版本对应一个 ReplicaSet;滚动升级时,新旧两个 ReplicaSet 同时存在,副本数动态调整 |
| Deployment | 声明式更新控制器,管理 ReplicaSet 的创建、缩放与回滚 | 编排整个滚动升级流程,根据策略计算新旧 ReplicaSet 的目标副本数 |
关键理解: Deployment 是“策略层”,ReplicaSet 是“执行层”。滚动升级的本质是 Deployment 控制新旧 ReplicaSet 的副本数此消彼长,直到新 ReplicaSet 完全接管所有流量。
2.2 滚动更新策略:maxSurge 与 maxUnavailable
Deployment 的 strategy.rollingUpdate 字段包含两个核心参数,它们共同定义了滚动升级的“节奏”和“资源占用”。
| 参数 | 类型 | 默认值 | 含义 | 典型场景 |
|---|---|---|---|---|
maxSurge |
整数或百分比 | 25% | 滚动升级过程中,允许超出期望副本数的最大 Pod 数量 | 快速扩容场景:增大该值可加速更新,但会消耗更多集群资源 |
maxUnavailable |
整数或百分比 | 25% | 滚动升级过程中,允许不可用 Pod 的最大数量(相对于期望副本数) | 高可用场景:减小该值可保证更多 Pod 在线,但更新速度变慢 |
计算公式(假设期望副本数为 replicas=10,maxSurge=25%,maxUnavailable=25%):
- 最大 Pod 总数 = replicas + maxSurge = 10 + 2.5(向上取整 3)= 13
- 最小可用 Pod 数 = replicas - maxUnavailable = 10 - 2.5(向下取整 2)= 8
- 滚动升级期间,集群中 Pod 总数始终在 8~13 之间波动。
2.3 滚动升级流程:新旧 ReplicaSet 的交替
以下 SVG 图展示了 Deployment 从 v1 升级到 v2 时,新旧 ReplicaSet 副本数的变化过程(假设 replicas=5,maxSurge=1,maxUnavailable=1)。
2.4 滚动升级的完整步骤
- 触发更新:修改 Deployment 的 Pod template(如镜像版本),Kubernetes API Server 记录新的
spec。 - 创建新 ReplicaSet:Deployment controller 检测到版本变化,创建一个新的 ReplicaSet(RS-v2),初始副本数为 0。
- 计算目标副本数:根据
maxSurge和maxUnavailable计算当前允许的最大 Pod 总数和最小可用 Pod 数。 - 逐步扩容新 RS:增加 RS-v2 的副本数(创建新版本 Pod),同时确保不超过最大 Pod 总数。
- 逐步缩容旧 RS:减少 RS-v1 的副本数(删除旧版本 Pod),同时确保不低于最小可用 Pod 数。
- 健康检查等待:新 Pod 通过 readiness probe 后,才继续下一轮扩容/缩容操作。
- 完成:当 RS-v2 副本数达到期望值,RS-v1 副本数降为 0 时,滚动升级完成。旧 ReplicaSet 保留在集群中,用于回滚。
常见陷阱:
- readiness probe 配置不当:如果新 Pod 的 readiness probe 一直失败,Deployment 会认为新 Pod 不可用,导致滚动升级卡住,新旧 Pod 同时存在。
- maxSurge 设置过大:在资源紧张的集群中,可能导致节点资源耗尽,Pod 调度失败。
- maxUnavailable 设置为 0:严格保证所有旧 Pod 都可用,但更新速度极慢,且如果新 Pod 启动失败,更新将完全阻塞。
2.5 滚动升级策略配置示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 3 # 允许最多超出 3 个 Pod
maxUnavailable: 2 # 允许最多 2 个 Pod 不可用
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:2.0.0
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
监控联动提示: 在 Prometheus 中,可以通过 kube_deployment_status_replicas_available 和 kube_deployment_status_replicas_unavailable 指标实时观察滚动升级过程中可用副本数的变化。当 unavailable 指标持续高于 maxUnavailable 时,说明更新可能遇到了问题。