文章目录
一、Kubernetes Deployment 更新策略详解
Kubernetes Deployment 提供了两种主要的更新策略:滚动更新(RollingUpdate)和重建更新(Recreate)。下面我将详细介绍这两种策略,特别是滚动更新的相关参数。
1. 重建更新 (Recreate)
重建更新策略是最简单的更新方式:
- 工作原理:
- 首先删除所有旧的Pod
- 然后一次性创建所有新的Pod
- 特点:
- 更新期间服务会有短暂不可用
- 资源使用效率高,因为不会同时运行新旧版本
- 适合开发环境或可以容忍短暂中断的场景
- 配置示例:
strategy: type: Recreate
2. 滚动更新 (RollingUpdate)
滚动更新策略是默认的更新策略,它能够实现零停机更新:
- 工作原理:
- 逐步用新Pod替换旧Pod
- 始终保持一定数量的Pod在运行
- 确保服务在整个更新过程中都可用
- 特点:
- 更新过程平滑,服务不中断
- 需要更多资源,因为新旧版本会同时运行一段时间
- 支持健康检查,确保新版本稳定后再继续更新
滚动更新的两个关键参数
滚动更新有两个重要参数控制更新过程:
-
maxUnavailable (最大不可用数)
- 定义:在更新过程中,允许不可用的Pod的最大数量或百分比
- 作用:控制更新速度,值越大更新越快但风险越高
- 示例值:数字(如1)或百分比(如25%)
- 默认值:25%
-
maxSurge (最大峰值数)
- 定义:在更新过程中,允许创建的超过期望副本数的Pod的最大数量或百分比
- 作用:控制资源使用,值越大更新越快但消耗资源越多
- 示例值:数字(如1)或百分比(如25%)
- 默认值:25%
配置示例
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
滚动更新过程示例
假设有一个Deployment有4个副本(replicas=4),配置为maxUnavailable=1
和maxSurge=1
:
- 开始更新时,先创建1个新Pod(由于maxSurge=1,总数暂时变为5)
- 当新Pod就绪后,终止1个旧Pod(由于maxUnavailable=1)
- 重复这个过程,直到所有旧Pod都被替换
两种策略的选择建议
-
使用RollingUpdate(滚动更新):
- 生产环境
- 需要高可用的服务
- 更新过程需要平滑过渡
-
使用Recreate(重建更新):
- 开发或测试环境
- 应用程序不支持多版本并行运行
- 可以接受短暂的服务中断
滚动更新通过精细控制maxUnavailable
和maxSurge
参数,可以在更新速度和系统稳定性之间取得平衡。
二、Kubernetes Deployment 配置变更与生效机制
在 Kubernetes 中,修改 Deployment 的配置是否要求重启 Pod 取决于您修改的具体字段。以下是详细的说明和建议:
关于更新策略变更
修改更新策略(spec.strategy
):
- 不需要重启现有 Pod 即可生效
- 新策略会在下一次更新时应用(如执行新的滚动更新时)
- 当前运行的 Pod 不会受到影响
需要替换 Pod 才能生效的配置
以下配置变更需要替换 Pod才能生效:
-
镜像相关变更:
spec.template.spec.containers[*].image
(容器镜像版本)- 这是最常见的需要重启的情况
-
环境变量变更:
spec.template.spec.containers[*].env
spec.template.spec.containers[*].envFrom
-
资源配置变更:
spec.template.spec.containers[*].resources
(CPU/内存限制)
-
卷挂载变更:
spec.template.spec.volumes
spec.template.spec.containers[*].volumeMounts
-
命令和参数变更:
spec.template.spec.containers[*].command
spec.template.spec.containers[*].args
不需要替换 Pod 的配置
以下配置变更通常不需要替换现有 Pod:
- 副本数:
spec.replicas
- 更新策略:
spec.strategy
- RollingUpdate 参数:
spec.strategy.rollingUpdate
- 标签和选择器(如果选择器不变)
- 亲和性/反亲和性规则:
spec.template.spec.affinity
三、配置更新策略可能的冲突
在 Kubernetes Deployment 的配置中,确实存在一些可能与滚动更新参数(maxUnavailable
和 maxSurge
)产生冲突或相互影响的配置。以下是需要特别注意的 7 类关键冲突点,以及它们的解决方案:
1. 资源配额(Resource Quotas)
冲突点:
maxSurge
创建的临时超额 Pod 可能触发资源配额限制(如 CPU/Memory 配额)。maxUnavailable
设置过大时,剩余 Pod 可能因资源不足无法处理流量。
解决方案:
# 确保配额足够覆盖 (replicas + maxSurge) 的资源需求
kubectl set resources deployment/my-app --limits=cpu=500m,memory=512Mi
2. Pod 中断预算(PDB, PodDisruptionBudget)
冲突点:
- PDB 要求最小可用 Pod 数(如
minAvailable: 80%
),可能与maxUnavailable
冲突。 - 若
maxUnavailable > (replicas - minAvailable)
,滚动更新会被阻塞。
解决方案:
# PDB 配置需兼容滚动更新参数
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 60% # 必须 ≥ (100% - maxUnavailable)
selector:
matchLabels:
app: my-app
3. HPA(Horizontal Pod Autoscaler)
冲突点:
- HPA 在滚动更新期间可能因
maxSurge
触发的临时 Pod 数波动而误判负载。 - 若
maxUnavailable
设置过高,HPA 扩容可能无法及时补偿可用性损失。
解决方案:
# 为 HPA 设置稳定窗口(Kubernetes ≥1.18)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 避免因滚动更新误缩容
4. Readiness Probe 配置
冲突点:
- 过于严格的
readinessProbe
(如长初始化时间)会导致新 Pod 无法快速就绪,maxUnavailable
的 Pod 被持续计入不可用计数。 - 可能造成滚动更新卡死(新 Pod 未就绪,旧 Pod 已被终止)。
解决方案:
# 优化探针配置
spec:
template:
spec:
containers:
- name: app
readinessProbe:
initialDelaySeconds: 5 # 避免过长延迟
periodSeconds: 5 # 适当提高检查频率
failureThreshold: 3 # 允许短暂失败
5. 节点亲和性/反亲和性(Affinity)
冲突点:
- 严格的
podAntiAffinity
(如requiredDuringSchedulingIgnoredDuringExecution
)可能导致maxSurge
的 Pod 因节点资源不足无法调度。 - 更新过程因调度失败而停滞。
解决方案:
# 改用软约束(preferredDuringScheduling)
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: my-app
topologyKey: kubernetes.io/hostname
6. Termination Grace Period
冲突点:
- 过长的
terminationGracePeriodSeconds
会导致旧 Pod 退出缓慢,占用maxUnavailable
配额,拖慢更新速度。
解决方案:
# 合理设置终止宽限期
spec:
template:
spec:
terminationGracePeriodSeconds: 30 # 根据应用优雅退出需求调整
7. 镜像拉取策略(Image Pull Policy)
冲突点:
imagePullPolicy: Always
在每次更新时强制拉取镜像,可能导致maxSurge
Pod 因拉取延迟无法快速就绪。
解决方案:
# 生产环境推荐使用固定版本标签 + IfNotPresent
containers:
- name: app
image: my-app:v1.2.3 # 避免使用 latest
imagePullPolicy: IfNotPresent
冲突检测与调试技巧
- 检查滚动更新状态:
kubectl rollout status deployment/my-app
- 查看阻塞事件:
kubectl describe deployment/my-app | grep -A 10 "Events"
- 模拟更新测试:
kubectl set image deployment/my-app app=my-app:test --dry-run=server
配置兼容性检查表
配置项 | 冲突风险 | 检查方法 |
---|---|---|
资源配额 | maxSurge 超限 | kubectl describe quota |
PDB | maxUnavailable 超出 PDB 约束 | kubectl get pdb |
HPA | 更新期间误触发扩缩容 | kubectl describe hpa |
Readiness Probe | 新 Pod 就绪慢导致更新卡住 | kubectl get pods -w |
节点亲和性 | maxSurge Pod 无法调度 | kubectl get events --field-selector=reason=FailedScheduling |
四、Kubernetes滚动更新参数(maxUnavailable/maxSurge)
1、参数基础定义
1. maxUnavailable (最大不可用数)
- 作用:控制更新期间允许不可用的Pod数量
- 格式:
- 整数(如1)
- 百分比字符串(如"25%")
- 默认值:25%
- 效果:保证服务的最低可用性
2. maxSurge (最大峰值数)
- 作用:控制可创建的超出期望副本数的Pod数量
- 格式:
- 整数(如1)
- 百分比字符串(如"25%")
- 默认值:25%
- 效果:控制资源使用和更新速度
2、取值范围与边界情况
1. 合法取值范围
参数 | 最小值 | 最大值 | 特殊值 |
---|---|---|---|
maxUnavailable | 0 | 无上限 | 100% |
maxSurge | 0 | 无上限 | 100% |
2. 数学约束条件
maxUnavailable + maxSurge > 0
- 两者不能同时为0
- 至少一个参数必须>0
3、特殊值行为分析
1. 设置为100%
参数 | 设置值 | 行为表现 | 适用场景 |
---|---|---|---|
maxUnavailable | 100% | 类似Recreate策略,先删后建 | 不支持多版本并行的场景 |
maxSurge | 100% | 先建后删,资源翻倍 | 零停机更新 |
2. 设置为>100%
参数 | 设置值 | 实际计算 | 最终效果 |
---|---|---|---|
maxUnavailable | 1000% | ceil(副本数×10) | 等同于100% |
maxSurge | 1000% | ceil(副本数×10) | 受限于实际资源 |
3. 设置为0
参数组合 | 行为表现 | 要求 |
---|---|---|
maxUnavailable=0 | 零停机更新 | maxSurge≥1 |
maxSurge=0 | 逐个替换 | maxUnavailable≥1 |
两者=0 | 报错不执行 | 不允许 |
4、格式要求与校验规则
1. 合法格式
格式类型 | 示例 | 是否合法 |
---|---|---|
整数 | maxUnavailable: 1 | ✅ |
百分比字符串 | maxSurge: “25%” | ✅ |
小数百分比 | maxUnavailable: “20.5%” | ✅ |
2. 非法格式
格式类型 | 示例 | 错误提示 |
---|---|---|
小数数值 | maxSurge: 1.5 | “must be integer or percentage” |
未加引号百分比 | maxUnavailable: 50% | 语法错误 |
负数 | maxSurge: -1 | “must be positive” |
3. 计算规则
- 百分比值向上取整(ceil)
- 至少计算为1个Pod
- 示例:3副本,20.1% → ceil(0.603)=1
5、生产环境推荐配置
1. 通用场景
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
2. 关键业务
rollingUpdate:
maxUnavailable: 10% # 保证90%可用性
maxSurge: 20% # 适度加快更新
3. 开发环境
rollingUpdate:
maxUnavailable: 50%
maxSurge: 50% # 快速更新
4. 特殊场景
场景 | 配置 | 说明 |
---|---|---|
数据库迁移 | maxUnavailable: 100% | 需停机更新 |
资源充足 | maxSurge: 100% | 零停机 |
资源紧张 | maxSurge: 0 | 逐个替换 |
6、常见问题解答
Q1: 可以设置为小数吗?
- 百分比字符串允许小数(“20.5%”)
- 数值形式必须整数
Q2: 设置为1000%会怎样?
- 计算值会远大于实际副本数
- 实际效果等同于100%
Q3: 为什么不能全为0?
- 会导致更新无法进行
- 系统需要至少一个方向(删除或创建)的操作空间
Q4: 如何实现零停机更新?
maxUnavailable: 0
maxSurge: 100% # 或更大