You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Kubernetes Engine集群无法自动缩容:配置PodDisruptionBudget后仍出现kube-system Pod不可移动日志报错

排查GKE自动缩容因kube-system Pod无法迁移失败的问题

从你给出的Autoscaler日志报错 no.scale.down.node.pod.kube.system.unmovable 来看,核心问题很明确:你的kube-dns Pod被标记为不可移动,所以集群没法缩容它所在的节点——哪怕你配置了PDB也没用。别着急,咱们一步步拆解问题,找出解决办法:

一、先搞懂报错到底啥意思

这个报错说明Cluster Autoscaler觉得 kube-dns-b4f5c58c7-26xdm 这个Pod不能被安全驱逐,所以绝不会动它所在的节点。这里要澄清一个误区:

  • PDB是用来控制Pod驱逐时的可用性,但它不能强迫Autoscaler认为Pod是可迁移的——Autoscaler自身还有一堆额外检查条件。
  • kube-system命名空间下的系统Pod,Autoscaler默认会特殊对待,很多带Critical优先级或者绑定了特定节点的Pod,根本不允许被驱逐。

二、一步步排查不可移动的原因

1. 检查kube-dns Pod的关键配置

先看看这个Pod的详细信息,重点盯这几个点:

kubectl describe pod kube-dns-b4f5c58c7-26xdm -n kube-system
  • 优先级类(Priority Class):如果Pod用了system-cluster-critical或者system-node-critical优先级,Autoscaler默认不会碰这类Pod(除非你手动开权限)。
  • 节点亲和性/选择器:如果Pod绑定了特定节点标签(比如node-role.kubernetes.io/master或者你自定义的标签),Autoscaler没法把它移到别的节点,自然不会缩容当前节点。
  • 污点容忍(Tolerations):如果Pod依赖某个节点的污点,而集群里其他节点没有这个污点,那它也没法迁移过去。

2. 确认你的PDB真的匹配这个Pod

你的PDB用了matchLabels: k8s-app: kube-dns作为选择器,得先确认目标Pod确实带这个标签:

kubectl get pod kube-dns-b4f5c58c7-26xdm -n kube-system --show-labels

要是Pod的标签和PDB的选择器对不上,那PDB相当于没生效,Autoscaler该认为Pod不可移动还是会那么认为。

3. 检查Cluster Autoscaler对kube-system Pod的限制

GKE里的Cluster Autoscaler默认对kube-system下的Pod管得很严,你得看看它的配置是不是允许驱逐这类Pod:

  • 对于1.19版本的GKE,默认参数是--skip-nodes-with-system-pods=true,意思就是有系统Pod的节点不能缩容。你得把这个参数改成false才行。
  • 就算开了这个参数,Autoscaler也只会驱逐那些能安全迁移的系统Pod——比如有Deployment/StatefulSet管着,PDB允许驱逐,而且没绑定特定节点。

三、对应的解决方案

1. 先把PDB和Pod的匹配问题解决

如果发现Pod标签和PDB选择器不匹配,要么修改PDB的selector,要么给Pod补上对应的标签,确保PDB能覆盖到这个kube-dns Pod。

2. 调整Autoscaler的kube-system Pod驱逐策略

在GKE里改这个配置有两种方式:

  • 控制台操作:进入集群的「节点」→「节点池」,选你要调整的节点池,编辑Autoscaler设置,找到「允许节点池缩容即使包含系统Pod」这个选项,把它打开。
  • 命令行操作:用gcloud命令更新集群配置:
gcloud container clusters update 你的集群名 --zone 你的集群区域 --enable-autoscaling --min-nodes=最小节点数 --max-nodes=最大节点数 --skip-nodes-with-system-pods=false

注意:开了这个选项后,Autoscaler才会尝试驱逐kube-system Pod,但前提是这些Pod真的能被安全迁移(比如有足够的副本,PDB允许)。

3. 检查kube-dns的Deployment配置

确保kube-dns的Deployment没有限制迁移的设置:

kubectl describe deployment kube-dns -n kube-system
  • 确认spec.replicas大于1,这样你的PDBmaxUnavailable:1才能发挥作用(要是只有1个副本,驱逐了就没了,Autoscaler肯定不敢动)。
  • 看看有没有nodeSelector或者affinity把Pod绑死在特定节点上,如果有,要么移除这些限制,要么确保其他节点也满足这些条件。

4. 手动验证Pod能不能被驱逐

你可以手动试试驱逐这个Pod,看能不能成功,这能直接告诉你问题出在哪:

kubectl drain 节点名 --ignore-daemonsets --delete-local-data

如果驱逐失败,报错信息会明明白白告诉你原因——比如副本数不够,或者Pod用了本地存储没法迁移之类的。

总结

你的问题大概率逃不开这几个原因:

  1. Cluster Autoscaler默认不让缩容带系统Pod的节点;
  2. PDB和kube-dns Pod的标签不匹配,导致PDB没生效;
  3. kube-dns Pod有优先级、节点绑定等限制,没法被迁移。

按上面的步骤挨个排查,应该就能解决自动缩容的问题了。

内容的提问来源于stack exchange,提问作者Eric Gumba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:17:42