Kubernetes:如何控制HPA扩容时选择的ReplicaSet以避免可用性损失?
HPA扩容时ReplicaSet的选择逻辑及故障规避方案
一、HPA扩容的核心逻辑
HPA本身并不直接选择要扩容的ReplicaSet(RS),它的作用对象是Deployment的replicas字段:当HPA检测到资源使用率阈值触发扩容时,会直接修改Deployment的期望副本数。而具体将新增副本分配给哪个RS,完全由Deployment的滚动更新策略决定。
在滚动更新过程中(存在新旧两个RS时),Deployment会遵循以下规则分配副本:
- 依据
maxSurge参数控制总副本数上限:总运行副本数(旧RS + 新RS)不能超过期望副本数 + maxSurge(maxSurge支持百分比或绝对值,默认25%)。 - 依据
maxUnavailable参数保证服务可用性:就绪副本数不能低于期望副本数 - maxUnavailable(默认25%)。
你遇到的场景中,当HPA将Deployment期望副本从1调至4时:
- 由于新RS的Pod无法就绪,Deployment不会缩容旧RS(否则会触发
maxUnavailable限制); - 同时Deployment会尝试创建新RS的Pod以满足期望副本数,受
maxSurge限制,最终出现旧RS新增1个、新RS新增2个的分配结果——但新RS的Pod无法就绪,导致最终就绪副本仅2个,低于需求。
二、控制扩容逻辑的解决方案
要避免此类故障,核心是让Deployment在新RS未就绪时,优先扩容可用的旧RS,而非继续尝试创建无效的新RS,具体方案如下:
1. 临时暂停Deployment滚动更新
执行命令暂停Deployment的更新流程,此时Deployment会停止向新RS分配副本,所有HPA触发的扩容都会指向旧RS:
kubectl rollout pause deployment/<your-deployment-name>
待新RS的镜像/配置修复后,再恢复滚动更新:
kubectl rollout resume deployment/<your-deployment-name>
2. 调整滚动更新策略参数
修改Deployment的滚动更新配置,限制新RS的副本创建速率,或强制优先保留旧RS:
- 设置
maxSurge=0:禁止在更新过程中创建额外的新Pod,Deployment只会在旧Pod被替换后才创建新Pod。此时HPA扩容时,所有新增副本都会分配给旧RS(因为新RS无法创建额外Pod)。 - 设置
maxUnavailable=0:要求更新过程中就绪副本数不能低于期望副本数,这意味着新Pod必须就绪后,才会缩容旧Pod。当新RS的Pod无法就绪时,Deployment不会继续创建新Pod,HPA扩容会优先补充旧RS的副本。
示例Deployment配置片段:
spec: strategy: rollingUpdate: maxSurge: 0 maxUnavailable: 0 type: RollingUpdate
3. 回滚至旧版本RS
如果新RS的问题短期内无法修复,直接回滚Deployment到旧的可用版本,此时HPA扩容会完全基于正常的旧RS:
kubectl rollout undo deployment/<your-deployment-name>
内容的提问来源于stack exchange,提问作者Varun Mathur
相关产品推荐
相关产品推荐

