EKS上Cluster Autoscaler缩容阶段忽略Pod与Node注解的异常问题
问题根因定位
缩容流程的逻辑层级误区
CA的缩容决策是分多轮校验的,日志里输出的“节点不可移除”仅为第一轮快速预筛查的临时拦截提示,并非最终缩容决策:
- 当连续多轮筛查都找不到无阻碍的可缩容节点时,CA会触发强制兜底缩容逻辑,跳过部分低优先级的注解校验,优先满足节点组最小节点数以上的容量回落要求。
- 你观察到的“总是优先删除集群内最老节点”,是开启
--balance-similar-node-groups参数后的默认行为:CA会跨同配置节点组做容量均衡时,优先删除节点组内创建时间最早的实例来抵消跨可用区节点数量差,这个排序优先级在兜底缩容场景下,会高于节点级、Pod级的注解拦截规则。
配置校验遗漏
- StatefulSet Pod模板配置的
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"注解,仅在正常缩容路径生效。强制兜底缩容时,仅两类拦截规则拥有最高优先级:一是配置了--skip-nodes-with-local-storage=true时的本地存储Pod校验,二是节点本身带有的cluster-autoscaler.kubernetes.io/scale-down-disabled: "true"注解。注意节点级注解生效的前提是,CA能通过节点标签识别到其所属的托管节点组,如果节点标签缺失被判定为非托管节点,这个保护注解会完全失效。 - 你之前的启动配置设置了
--skip-nodes-with-local-storage=false,会跳过所有本地存储类Pod的安全驱逐校验,哪怕Pod打了禁止驱逐的注解,也会被强制放行进入删除流程。
版本已知缺陷
你测试的1.18.x、1.19.x系列CA版本存在明确的缩容排序bug:当多可用区节点组开启跨区均衡时,safe-to-evict注解的校验优先级会被错误下调到节点年龄排序之后,哪怕日志已经提示节点存在禁止驱逐的Pod,最终排序时还是会把老节点排到删除队列最前面,跳过注解校验。
可行解决配置
调整CA启动参数对齐拦截优先级
替换现有启动配置,取消错误的优先级覆盖逻辑:
spec: containers: - command: - ./cluster-autoscaler - --v=4 - --stderrthreshold=info - --cloud-provider=aws - --skip-nodes-with-local-storage=true - --expander=least-waste - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/你的集群名称 - --balance-similar-node-groups=false - --skip-nodes-with-system-pods=true - --scale-down-unneeded-time=10m
关键调整说明:
- 关闭
--balance-similar-node-groups,取消跨节点组按节点年龄排序的强制删除逻辑 - 开启本地存储、系统Pod的跳过规则,避免这类Pod的校验逻辑绕过注解保护
- 取消无差别强制兜底缩容的触发条件:当没有可安全删除的节点时,CA直接终止本轮缩容流程,不会为了满足容量回落强制删除带保护注解的节点
补全节点保护规则
- 给运行关键StatefulSet的节点打
cluster-autoscaler.kubernetes.io/scale-down-disabled: "true"注解时,必须同步确认节点带有对应ASG组的k8s.io/cluster-autoscaler/enabled标签,避免CA识别不到节点所属组导致保护失效 - 给带
safe-to-evict: "false"注解的StatefulSet Pod配置高优先级PriorityClass,让CA在节点排序时直接跳过这类Pod所在的节点,不进入兜底删除候选队列
优先缩容临时扩容节点
- 给承接临时负载的新节点单独打
cluster-autoscaler.kubernetes.io/scale-down-unneeded-time: "0s"注解,让这类节点在负载清空后第一时间进入缩容候选队列,优先级高于长期运行业务的老节点 - 可替换expander为
priority类型,直接将带保护注解的节点的删除权重调到最高,永久排除在缩容候选列表外
内容的提问来源于stack exchange,提问作者Sohrab
相关产品推荐
相关产品推荐

