Kubernetes 资源受限场景下如何实现零停机滚动更新
你遇到的业务中断并非滚动更新策略或健康探针配置失效导致,核心触发逻辑是:
- 集群单节点资源上限刚好能承载2个业务Pod(单Pod请求0.2核CPU、1Gi内存),发布时因
maxSurge=2的配置需要临时拉起2个新版本Pod,整体资源需求超出单节点承载能力,导致新Pod被全量调度到node2 - node2上的新Pod就绪后,控制器驱逐node1上的旧Pod,node1立刻释放出全部资源
- 因缺少Pod调度位置的锚定规则,Kubernetes调度器默认的资源平衡策略会主动把node2上正在服务的新Pod迁移回资源更空闲的node1,迁移过程直接导致流量中断。
1. 给Deployment添加硬反亲和约束,杜绝无意义的Pod漂移
在Deployment的Pod模板段添加Pod反亲和规则,固定同应用副本的分布逻辑,核心利用*requiredDuringSchedulingIgnoredDuringExecution*的特性:该规则仅在调度新Pod时生效,已经在节点上稳定运行的Pod不会因节点后续资源变化被主动迁移、驱逐。
具体在.spec.template.spec下添加如下配置:
affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - abc topologyKey: kubernetes.io/hostname
配置生效后,2个业务副本会被强制分散在两个节点上,调度器不会再出现把运行中Pod跨节点迁移的行为。
2. 调整滚动更新参数,匹配当前节点的资源规模
当前配置的maxSurge: 2对双节点、资源刚好卡满的集群过于激进:单节点最多承载2个业务Pod,maxSurge=2意味着发布时需要临时新增2个Pod,直接导致临时资源缺口,迫使Pod集中调度到单节点。
可将滚动更新参数调整为:
strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0
调整后发布流程为:每次仅新增1个新版本Pod,临时总资源需求为3个Pod的请求量,两个节点均可承载,不会出现新Pod全量挤到单节点的情况,从流程上避免触发后续的Pod漂移。
3. 优化就绪探针配置,缩短版本切换的空窗期
当前配置的initialDelaySeconds: 540(9分钟等待时间)远长于应用实际启动周期,过长的探针等待窗口会拉长Pod的临时资源占用时长,提升调度器触发平衡迁移的概率。
可在确认应用真实启动耗时的基础上,将探针等待时间调整到匹配实际启动时长的合理值,缩短Pod从启动到就绪的周期,加快版本切换流程,减少漂移触发的可能性。
可选优化:预留少量节点资源冗余
受限于节点总资源无法提升,可适当下调单Pod的资源请求值,比如将CPU请求从0.2核调整为0.18核、内存请求从1000Mi调整为900Mi,让两个节点总共留出约0.08核CPU、200Mi内存的冗余空间,缓解资源卡满导致的调度抖动问题。
内容的提问来源于stack exchange,提问作者Sakshi

