4. Deployment 滚动更新:rollingUpdate 策略、maxSurge 与 maxUnavailable 参数、更新过程演示
滚动更新(Rolling Update)是 Kubernetes Deployment 默认的更新策略,它通过逐步替换旧 Pod 实例来保证服务在更新期间持续可用。本节将深入解析 rollingUpdate 策略的核心参数 maxSurge 与 maxUnavailable,并通过完整的更新过程演示帮助理解其工作原理。
4.1 rollingUpdate 策略概述
当 Deployment 的 spec.strategy.type 设置为 RollingUpdate 时,Kubernetes 会按照用户定义的参数逐步替换 Pod。该策略的核心目标是:在保证服务可用性的前提下,平滑地将所有 Pod 从旧版本迁移到新版本。
| 策略类型 | 描述 | 适用场景 |
|---|---|---|
RollingUpdate |
逐步替换旧 Pod,保持一定数量的 Pod 可用 | 生产环境默认策略,追求零停机更新 |
Recreate |
先删除所有旧 Pod,再创建新 Pod | 开发环境或允许短暂停服的场景 |
最佳实践: 生产环境始终使用
RollingUpdate 策略,并配合 readinessProbe 和 livenessProbe 确保流量只路由到就绪的 Pod。
4.2 maxSurge 与 maxUnavailable 参数详解
这两个参数共同控制滚动更新的速率和资源占用,是精细化调优的关键。
4.2.1 maxUnavailable
定义: 更新过程中允许处于不可用状态的 Pod 最大数量或百分比(相对于期望副本数)。
- 作用: 保证更新期间至少有
replicas - maxUnavailable个 Pod 处于可用状态。 - 取值: 整数(如 1)或百分比(如 25%),默认值为 25%。
- 示例: 若
replicas=10,maxUnavailable=25%,则更新期间最多允许 2 个 Pod 不可用,确保至少 8 个 Pod 持续提供服务。
4.2.2 maxSurge
定义: 更新过程中允许超出期望副本数的 Pod 最大数量或百分比。
- 作用: 控制可以提前创建的新 Pod 数量,加速更新过程。
- 取值: 整数(如 1)或百分比(如 25%),默认值为 25%。
- 示例: 若
replicas=10,maxSurge=25%,则更新期间最多允许 12 个 Pod 同时存在(10 + 2),新 Pod 创建后旧 Pod 才被删除。
| 参数 | 控制方向 | 默认值 | 典型配置 | 影响 |
|---|---|---|---|---|
maxUnavailable |
最小可用 Pod 数 | 25% | 0(零停机)或 1(保守) | 影响服务可用性下限 |
maxSurge |
最大额外 Pod 数 | 25% | 1(资源受限)或 100%(快速更新) | 影响更新速度和资源占用 |
注意: 当
maxUnavailable=0 时,必须设置 maxSurge>0,否则无法创建新 Pod 来替换旧 Pod,更新将卡住。反之,maxSurge=0 时,maxUnavailable 必须大于 0。
4.3 滚动更新过程演示
以下通过一个实际案例演示滚动更新的完整流程。假设 Deployment 配置如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
version: v1
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
执行更新命令:kubectl set image deployment/web-app nginx=nginx:1.25
4.3.1 更新步骤分解
- 初始状态: 4 个
version=v1的 Pod 全部运行,ReplicaSetweb-app-xxx-v1管理所有 Pod。 - 创建新 ReplicaSet: Kubernetes 创建新的 ReplicaSet
web-app-yyy-v2,期望副本数为 0。 - 扩容新 RS: 根据
maxSurge=1,允许最多 5 个 Pod 同时存在。系统在旧 RS 保持 4 个 Pod 的基础上,为新 RS 创建 1 个新 Pod(version=v2)。 - 缩容旧 RS: 新 Pod 通过
readinessProbe检查变为 Ready 后,根据maxUnavailable=1,系统从旧 RS 中删除 1 个旧 Pod(version=v1)。此时总 Pod 数回到 4。 - 循环执行: 重复步骤 3-4,每次创建 1 个新 Pod,删除 1 个旧 Pod,直到所有旧 Pod 被替换。
- 完成状态: 4 个
version=v2的 Pod 全部运行,旧 ReplicaSet 副本数缩为 0。
关键观察: 在整个过程中,始终有 3 到 4 个 Pod 处于 Ready 状态(
replicas - maxUnavailable = 3),服务从未中断。
4.3.2 滚动更新状态图
4.4 滚动更新参数配置建议
| 场景 | maxSurge | maxUnavailable | 说明 |
|---|---|---|---|
| 零停机更新(资源充足) | 25% 或 1 | 0 | 保证所有旧 Pod 在更新期间持续服务,新 Pod 就绪后才删除旧 Pod |
| 快速更新(容忍短暂降级) | 100% 或 replicas | 50% | 允许创建大量新 Pod 并行替换,但可能造成资源竞争 |
| 资源受限环境 | 1 | 1 | 每次只替换 1 个 Pod,对集群资源冲击最小 |
| 保守更新(关键服务) | 10% | 10% | 缓慢替换,配合 minReadySeconds 确保稳定性 |
生产建议: 对于无状态服务,推荐配置
maxSurge=25% 和 maxUnavailable=25%,在速度和稳定性之间取得平衡。对于有状态服务或数据库,建议 maxSurge=0 配合 maxUnavailable=1,确保数据一致性。
4.5 滚动更新回滚机制
当更新过程中出现故障(如新版本 CrashLoopBackOff),Kubernetes 会自动暂停更新。运维人员可以通过以下命令手动回滚:
# 回滚到上一个版本
kubectl rollout undo deployment/web-app
# 回滚到指定版本
kubectl rollout undo deployment/web-app --to-revision=2
# 查看更新历史
kubectl rollout history deployment/web-app
回滚时,Kubernetes 会复用相同的 rollingUpdate 策略参数,以同样的滚动方式将 Pod 恢复到旧版本,确保回滚过程同样平滑。
4.6 滚动更新与 CRI 资源调度的关系
滚动更新过程中,新 Pod 的创建会触发 CRI(Container Runtime Interface)接口的资源调度流程:
- kubelet 调用 CRI: 新 Pod 被调度到节点后,kubelet 通过 CRI 接口(如 containerd、CRI-O)创建容器。
- 资源预留与限制: CRI 根据 Pod 的
resources.requests和resources.limits配置,向容器运行时申请 CPU、内存等资源。 - 节点资源压力: 若
maxSurge设置过大,可能导致节点资源超分,触发 kubelet 的驱逐机制(Eviction)。
CRI 集成提示: 在滚动更新期间,建议监控节点资源使用率。若使用 containerd,可通过
ctr 命令查看容器资源状态;若使用 CRI-O,可通过 crictl stats 实时观察 Pod 资源消耗。