如何在GKE中配置HPA调度:保按需节点副本,扩容副本到抢占式节点?
解决方案
要实现「至少1个副本在按需节点,HPA扩容副本优先调度到抢占式节点」的需求,需要调整亲和性规则,结合节点亲和性(允许双节点类型)、优先调度偏好和拓扑分布约束来实现,具体配置如下:
1. 核心配置思路
- 移除强制限制所有Pod到按需节点的
requiredDuringSchedulingIgnoredDuringExecution规则,改为允许Pod调度到按需节点或抢占式节点 - 添加优先调度规则,让Pod优先选择抢占式节点,确保HPA扩容的副本优先分配到这类节点
- 配置拓扑分布约束,强制保证至少有1个副本运行在按需节点上
2. 修改后的Deployment调度配置
affinity: # 保留原有的Pod反亲和性(避免同节点部署同服务Pod) podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: service operator: In values: - {{ .Values.nameSpace }}-app topologyKey: "kubernetes.io/hostname" # 节点亲和性:允许Pod调度到两种节点类型 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: # 规则1:匹配没有preemptible-node标签的按需节点 - key: preemptible-node operator: DoesNotExist - matchExpressions: # 规则2:匹配带有preemptible-node=true的抢占式节点 - key: preemptible-node operator: In values: - "true" # 优先调度规则:优先选择抢占式节点,权重设为10(最高优先级) preferredDuringSchedulingIgnoredDuringExecution: - weight: 10 preference: matchExpressions: - key: preemptible-node operator: In values: - "true" # 拓扑分布约束:确保至少1个副本运行在按需节点(无preemptible-node标签的节点组) topologySpreadConstraints: - maxSkew: 1 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: DoNotSchedule labelSelector: matchExpressions: - key: service operator: In values: - {{ .Values.nameSpace }}-app matchLabelKeys: - preemptible-node # 保留原有的容忍度,确保Pod能调度到带有NoSchedule污点的抢占式节点 tolerations: - key: "preemptible-node" operator: "Equal" value: "true" effect: "NoSchedule"
3. 配置说明
- 节点亲和性:通过两个
nodeSelectorTerms规则,允许Pod同时调度到按需节点(无preemptible-node标签)和抢占式节点(标签值为true),打破了原有的强制限制 - 优先调度规则:给抢占式节点设置最高权重(10),当集群有空闲的抢占式节点时,HPA扩容的副本会优先调度到这类节点
- 拓扑分布约束:通过
matchLabelKeys关联节点的preemptible-node标签,强制要求在「无该标签的节点组」中至少存在1个Pod,保证了核心副本的可用性 - 容忍度:保留原有配置,确保Pod可以绕过抢占式节点的
NoSchedule污点
4. 额外验证建议
- 确认抢占式节点池已正确打上
preemptible-node=true标签,按需节点无该标签 - 手动扩容Deployment副本数,观察新增副本是否优先调度到抢占式节点
- 模拟抢占式节点被回收的场景,验证剩余副本会自动在按需节点重建,保证至少1个可用副本
内容的提问来源于stack exchange,提问作者Kaleby Cadorin
相关产品推荐
相关产品推荐

