GKE升级至1.24后Worker节点池从0节点自动扩容失效
问题根因
这个故障是GKE 1.21到1.24升级过程中,集群自动扩缩容组件(CA)针对0节点空节点池的扩容匹配规则做了两处不兼容的默认行为变更导致,和业务侧的调度逻辑本身无关:
- 空节点池的配置读取逻辑变更
1.21版本的CA评估空节点池是否能承载待调度Pod时,会直接拉取节点池管理面存储的全量配置做模拟调度,包括你创建节点池后手动追加的自定义标签、污点。从1.23基线版本(对应GKE 1.24大版本)开始,CA对空节点池做模拟调度时,只会读取节点池绑定的计算实例模板里固化的标签、污点配置。如果你是在Worker_Pool创建完成后,才通过控制台/API给节点池加上的ABC:XYZ标签、DEF:UVW污点,这些配置不会自动同步更新到实例模板里,节点池缩到0后,CA模拟出来的待扩容节点根本不会带这两个配置,自然会判定你的Pod没法调度到这个节点池,不会触发扩容。你看到的如下报错就是直接证据:Pod conditions: Reason: Unschedulable, Message: 0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.
这个报错说明调度器和CA的视野里只有System_Pool那1个运行节点,完全没把Worker_Pool算成可调度的候选资源。 - 空节点池的污点匹配规则收紧
就算你的标签、污点都是创建节点池时就配好、已经写入实例模板的,1.24版本自带的CA也收紧了校验:如果节点池上的污点配置了具体Value(比如你配的DEF:UVW),CA在空节点池模拟调度时不认Operator: Exists类型的容忍规则,只认Operator: Equal、且显式写死Value和污点Value完全一致的容忍配置。这个是CA针对0节点扩容场景的特殊校验,和K8s原生调度器在已有运行节点上的容忍逻辑不一样,属于版本升级带来的隐式行为变化。
修复步骤
按下面的顺序调整就能恢复0节点自动扩容能力:
- 重新编辑Worker_Pool的节点池配置,确认
ABC:XYZ标签、DEF:UVW污点是直接配置在节点池维度的,保存后GKE会自动重新生成绑定的实例模板,把这些配置固化进去。注意不要只给池内的单个节点打标签、加污点,这类节点级别的配置在节点被删除后,CA做0节点模拟时是读不到的。 - 修改业务Pod的容忍配置,把原来的Exists类型容忍改成Equal类型,显式匹配污点的Value,参考代码如下:
NodeSelector = new Dictionary<string, string> { ["ABC"] = "XYZ" }, Tolerations = new List<V1Toleration> { new V1Toleration { Key = "DEF", OperatorProperty = "Equal", Value = "UVW", Effect = "NoSchedule" } }
- 如果改完还是触发不了扩容,可以在NodeSelector里额外加一条GKE自动给每个节点池注入的原生标签
cloud.google.com/gke-nodepool: <你的Worker_Pool实际名称>,直接显式指定目标节点池,跳过CA的模糊匹配逻辑。
验证方法
改完提交一个测试Pod,查看集群事件,如果出现Triggered scale-up for node pool Worker_Pool类的扩缩容事件,就说明逻辑恢复正常了,后续Worker_Pool无负载时还是可以正常缩到0节点。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

