3. K8s Deployment 滚动更新原理:ReplicaSet、滚动更新策略参数
滚动更新(Rolling Update)是 Kubernetes Deployment 默认的更新策略,其核心目标是在不中断服务的前提下,逐步用新版本 Pod 替换旧版本 Pod。理解滚动更新的底层机制,是制定回滚策略与多租户权限联动方案的基础。
3.1 核心组件:ReplicaSet 的版本管理角色
Deployment 并不直接管理 Pod,而是通过 ReplicaSet(RS) 实现 Pod 的副本控制与版本追踪。每次 Deployment 的 Pod 模板(spec.template)发生变更时,Kubernetes 会创建一个新的 ReplicaSet,并逐步调整新旧 RS 的副本数。
| 组件 | 职责 | 与滚动更新的关系 |
|---|---|---|
| Deployment | 声明式管理 Pod 模板与副本数 | 触发更新、控制滚动策略、记录版本历史 |
| ReplicaSet (旧) | 维护旧版本 Pod 的期望副本数 | 滚动过程中逐步缩容至 0,保留作为回滚目标 |
| ReplicaSet (新) | 维护新版本 Pod 的期望副本数 | 滚动过程中逐步扩容至目标副本数 |
| Pod | 运行实际容器实例 | 被 RS 管理,滚动更新中逐个被替换 |
3.2 滚动更新流程:ReplicaSet 的交替扩容与缩容
下图展示了 Deployment 从 v1 滚动更新至 v2 时,新旧 ReplicaSet 的副本数变化过程(假设 replicas=5,maxSurge=1,maxUnavailable=1)。
desiredReplicas - maxUnavailable 到 desiredReplicas + maxSurge 之间,确保服务不中断。
3.3 滚动更新策略参数:maxSurge 与 maxUnavailable
这两个参数定义在 Deployment 的 spec.strategy.rollingUpdate 中,控制滚动更新的速率与资源占用。
| 参数 | 类型 | 默认值 | 含义 | 影响 |
|---|---|---|---|---|
| maxSurge | 整数或百分比 | 25% | 更新过程中,允许超出期望副本数的最大 Pod 数量 | 控制更新速度与资源消耗;值越大,更新越快,但资源峰值越高 |
| maxUnavailable | 整数或百分比 | 25% | 更新过程中,允许不可用 Pod 的最大数量 | 控制服务可用性下限;值越小,服务越稳定,但更新越慢 |
3.4 参数组合的典型场景
不同的参数组合适用于不同的业务需求。以下表格展示了常见配置及其效果:
| 场景 | maxSurge | maxUnavailable | 行为描述 | 适用场景 |
|---|---|---|---|---|
| 快速更新 | 100% | 100% | 先创建全部新 Pod,再销毁全部旧 Pod(相当于蓝绿部署) | 测试环境、可接受短暂双倍资源占用的场景 |
| 零停机 | 1 (或 10%) | 0 | 先创建 1 个新 Pod,确认就绪后再销毁 1 个旧 Pod,确保始终有全部旧 Pod 提供服务 | 生产环境关键服务,要求严格零停机 |
| 资源受限 | 0 | 1 (或 10%) | 先销毁 1 个旧 Pod,再创建 1 个新 Pod,不额外占用资源 | 集群资源紧张,无法承受额外 Pod 开销 |
| 均衡模式 | 25% | 25% | 默认配置,在速度与稳定性之间取得平衡 | 大多数通用场景 |
3.5 参数配置示例
以下 YAML 片段展示了一个配置了滚动更新策略的 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # 允许最多超出 2 个 Pod
maxUnavailable: 1 # 允许最多 1 个 Pod 不可用
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:2.0.0
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
3.6 滚动更新与回滚的关联
滚动更新过程中,旧 ReplicaSet 不会被立即删除,而是保留在 revisionHistory 中。当更新出现问题时,可以通过 kubectl rollout undo 命令快速回滚到任意历史版本:
# 查看 Deployment 的更新历史
kubectl rollout history deployment/my-app
# 回滚到上一个版本
kubectl rollout undo deployment/my-app
# 回滚到指定版本(例如 revision=3)
kubectl rollout undo deployment/my-app --to-revision=3
回滚的本质是:将目标 ReplicaSet 的 Pod 模板重新设置为当前 Deployment 的模板,并触发一次新的滚动更新。因此,回滚过程同样遵循 maxSurge 和 maxUnavailable 参数的约束。
3.7 多租户场景下的滚动更新考量
在多租户集群中,滚动更新策略需要与资源配额(ResourceQuota)和 Pod 安全策略联动:
- 资源配额限制: 如果 maxSurge 设置过大,可能导致租户的 Pod 数量超出其 ResourceQuota,更新被拒绝。建议为每个租户设置合理的 maxSurge 上限。
- Pod 中断预算(PDB): 对于关键租户服务,应配置 PDB 限制同时中断的 Pod 数量,防止滚动更新导致租户服务降级。
- 更新速率控制: 通过 RBAC 限制租户对
spec.strategy.rollingUpdate的修改权限,防止租户设置过于激进的更新参数影响集群稳定性。