3. Deployment 滚动更新机制详解:ReplicaSet、滚动更新策略与更新流程
Deployment 的滚动更新(Rolling Update)是 Kubernetes 中最核心的应用发布策略。它通过逐步替换旧版本 Pod 实例,实现零停机、可控速率的应用升级。理解其底层组件 ReplicaSet 以及策略参数 maxSurge 与 maxUnavailable,是优化证书轮换等敏感作业流程的基础。
3.1 核心组件:ReplicaSet 的版本化控制
Deployment 并不直接管理 Pod,而是通过 ReplicaSet(RS) 进行间接管理。每次 Deployment 的 Pod 模板(spec.template)发生变更(例如更新证书文件或镜像版本),Kubernetes 都会创建一个新的 ReplicaSet,并逐步调整新旧 RS 的副本数。
| 组件 | 职责 | 与滚动更新的关系 |
|---|---|---|
| Deployment | 声明式管理,维护期望状态 | 触发更新、控制策略、记录版本历史 |
| ReplicaSet (旧) | 维持旧版本 Pod 数量 | 在更新过程中被逐步缩容至 0 |
| ReplicaSet (新) | 维持新版本 Pod 数量 | 在更新过程中被逐步扩容至期望副本数 |
| Pod | 运行实际应用实例 | 承载证书文件,被逐个替换 |
关键认知: 滚动更新的本质是 ReplicaSet 之间的副本转移。旧 RS 缩容一个 Pod,新 RS 就扩容一个 Pod,直到所有流量切换到新版本。Deployment 的 revisionHistoryLimit 属性控制保留多少个旧 RS,用于快速回滚。
3.2 滚动更新策略:maxSurge 与 maxUnavailable
滚动更新的速率和资源占用由 strategy.rollingUpdate 下的两个关键参数控制。这两个参数可以是整数(数量)或百分比(相对于期望副本数)。
| 参数 | 含义 | 默认值 | 典型场景 |
|---|---|---|---|
| maxSurge | 更新过程中,允许超出期望副本数的最大 Pod 数量 | 25% | 控制更新期间的资源峰值,避免集群过载 |
| maxUnavailable | 更新过程中,允许不可用 Pod 的最大数量 | 25% | 保证服务的最小可用实例数,维持服务容量 |
参数计算示例(期望副本数 replicas=10):
- maxSurge=25%:更新期间最多允许 10 * 25% = 2.5,向上取整为 3 个额外 Pod。集群中 Pod 总数最多为 10 + 3 = 13 个。
- maxUnavailable=25%:更新期间最多允许 10 * 25% = 2.5,向下取整为 2 个 Pod 不可用。集群中可用 Pod 最少为 10 - 2 = 8 个。
证书轮换优化建议: 对于证书挂载场景,建议将
maxUnavailable 设置为 0,确保更新过程中始终有足够的 Pod 处理业务流量,避免因证书短暂缺失导致服务中断。同时,适当调大 maxSurge 可以加速轮换过程。
3.3 滚动更新流程详解
以下 SVG 图展示了从触发更新到完成的完整流程,以及新旧 ReplicaSet 的副本变化。
3.4 更新流程中的关键步骤与状态检查
Kubernetes Controller Manager 中的 Deployment Controller 负责执行滚动更新,其核心逻辑是一个循环,直到新旧 RS 的副本数达到期望状态。
- 检测变更: Controller 监听到 Deployment 的 Pod 模板发生变化(如
spec.template.spec.containers[].image或挂载的 Secret/ConfigMap 版本更新)。 - 暂停旧 RS: 将旧 ReplicaSet 标记为不再接收新 Pod 请求。
- 创建新 RS: 根据新的 Pod 模板创建一个新的 ReplicaSet,初始副本数为 0。
- 执行扩容(新 RS): 计算当前可扩容数量,不超过
maxSurge的限制。新 Pod 启动并通过 Readiness Probe 检查后,标记为 Ready。 - 执行缩容(旧 RS): 计算当前可缩容数量,不超过
maxUnavailable的限制。Controller 向旧 Pod 发送 SIGTERM 信号,等待 TerminationGracePeriodSeconds 后强制删除。 - 重复步骤 4-5: 直到新 RS 的副本数等于期望副本数,旧 RS 的副本数归零。
- 更新状态: Deployment 的
status.updatedReplicas等于期望副本数,status.readyReplicas等于可用副本数,滚动更新完成。
证书轮换陷阱: 如果 Pod 的 Readiness Probe 配置不当(例如探针依赖的证书文件在挂载延迟后才生效),新 Pod 可能永远不会进入 Ready 状态,导致滚动更新卡住。建议在 Readiness Probe 中增加对证书文件存在性的检查,并设置合理的
initialDelaySeconds。
3.5 滚动更新策略配置示例
以下是一个针对证书轮换场景优化的 Deployment YAML 配置片段,强调安全性和可控性。
apiVersion: apps/v1
kind: Deployment
metadata:
name: cert-renewal-app
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # 允许最多额外创建 2 个 Pod,加速轮换
maxUnavailable: 0 # 确保更新期间所有旧 Pod 都可用,零停机
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: cert-volume
mountPath: /etc/certs
readinessProbe:
exec:
command:
- cat
- /etc/certs/tls.crt
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: cert-volume
secret:
secretName: my-tls-secret
参数选择建议:
- maxUnavailable=0: 适用于证书轮换等对服务连续性要求极高的场景,确保任何时候都有足够的 Pod 处理请求。
- maxSurge=1 或 2: 在集群资源充足的情况下,适当增加该值可以缩短轮换时间。对于大规模集群,建议设置为 10%-25% 以避免资源冲击。
- Readiness Probe: 必须包含对证书文件或挂载点的检查,防止 Pod 在证书未就绪时被纳入 Service 端点。
3.6 滚动更新 vs 其他更新策略
| 策略 | 更新方式 | 适用场景 | 证书轮换适用性 |
|---|---|---|---|
| RollingUpdate | 逐步替换 Pod | 大多数无状态应用,需要零停机 | ✅ 推荐,配合 maxUnavailable=0 |
| Recreate | 先删除所有旧 Pod,再创建新 Pod | 有状态应用或需要完全重启的场景 | ❌ 不推荐,会导致服务短暂中断 |
| Blue/Green | 同时运行两套环境,切换 Service 流量 | 需要快速回滚、A/B 测试 | ✅ 可用,但资源消耗翻倍 |
| Canary | 先更新少量 Pod,验证后再全量更新 | 灰度发布、风险控制 | ✅ 可用,适合验证新证书兼容性 |