K3S添加主节点污点后旧Deployment Pod无法调度到worker节点问题
问题产生原因
调度器的报错已经直接对应了所有4个节点的筛选失败原因,和Deployment新旧版本没有直接关系,核心是节点配置与Pod调度规则不匹配:
- 你总共3个控制平面节点,仅为其中2个添加了
k3s-controlplane=true:NoSchedule污点,这2个节点会直接拒绝没有对应容忍配置的Pod调度,对应报错里的「2 node(s) had taint {k3s-controlplane: true}, that the pod didn't tolerate」。 - 剩余2个节点(1个未打污点的控制平面节点、1个工作节点)没有匹配你在Deployment中硬配置的
nodeSelector: type: "slow"规则——这两个节点没有打上type=slow标签,因此被节点选择器直接筛除,对应报错里的「2 node(s) didn't match Pod's node affinity/selector」。
之前Pod能正常运行,是因为未加污点时,Pod原本调度在那2个后来被你打上污点的控制平面节点上,这两个节点本身带有type=slow标签,刚好满足nodeSelector要求。加污点后这两个节点不再接受无容忍的Pod,其余可用节点又不符合nodeSelector的硬约束,自然调度失败。
新建Deployment能正常调度,是因为这些Deployment没有配置强制的type=slow节点选择规则,自然可以被调度到无污点的节点上。
另外你最初的配置本身有遗漏:目标是工作负载默认不调度到主节点,但3个控制平面节点只给2个加了污点,剩余1个主节点依然存在被随意调度工作负载的风险。
修复方案
按以下步骤操作即可恢复调度,同时满足你最初的主节点调度限制需求:
- 补全所有控制平面节点的污点配置,给未打污点的第三个主节点加上对应NoSchedule污点,确保所有主节点都拒绝无容忍的工作负载:
kubectl taint nodes <第三个主节点的实际名称> k3s-controlplane=true:NoSchedule - 解决nodeSelector不匹配问题,根据实际需求二选一即可:
- 如果你确实需要这个test工作负载运行在标记为
type=slow的节点上:给工作节点打上对应标签,让无污点的worker节点满足节点选择规则:kubectl label nodes <你的工作节点实际名称> type=slow - 如果你不需要强制限制该工作负载运行在slow类型节点上:直接编辑test Deployment,删除
spec.template.spec下的nodeSelector配置段,或者将nodeSelector的匹配规则修改为和工作节点实际标签一致,保存后Deployment会自动重建Pod。
- 如果你确实需要这个test工作负载运行在标记为
- 执行
kubectl get pods -l app=test -o wide验证,确认Pod状态变为Running且调度到工作节点即修复完成。
内容的提问来源于stack exchange,提问作者Xhelliom
相关产品推荐
相关产品推荐

