Kubernetes双Worker节点集群故障恢复后,如何实现Deployment的Pod跨节点重新分布
这个需求其实挺常见的——Kubernetes默认情况下并不会主动重新平衡已经运行的Pod,它的调度器只会在需要创建新Pod的时候工作,已经在节点上跑起来的Pod除非遇到驱逐条件(比如节点资源不足),否则不会被移动。不过我们有几种方法可以实现你想要的Pod重新分布效果,我给你详细说说:
方案1:手动触发Deployment滚动更新
这是最直接的临时解决办法,通过让Deployment重新创建所有Pod,调度器会把新Pod分配到现在可用的两个Worker节点上,自然实现分布平衡。你只需要执行一条命令:
kubectl rollout restart deployment kub-homenet-deployment
这条命令会触发Deployment的滚动更新,逐步删除旧Pod并创建新Pod,调度器会根据当前节点状态把新Pod调度到两个节点上,最终每个节点各运行1个Pod。
方案2:配置Pod拓扑分布约束(长期自动化方案)
如果你希望以后节点恢复后,Pod能自动保持分布平衡(不需要手动操作),可以给Deployment添加拓扑分布约束(Topology Spread Constraints)。这个配置会告诉调度器,尽量把Pod均匀分布在不同的节点上。
修改你的Deployment配置,在spec.template.spec下添加以下内容:
topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: kub-homenet
解释一下这些字段:
maxSkew: 1:表示任意两个节点之间的Pod数量差不能超过1(你的副本数是2,刚好每个节点1个)topologyKey: kubernetes.io/hostname:以节点的主机名作为拓扑域的划分依据(也就是每个节点是一个独立的拓扑域)whenUnsatisfiable: DoNotSchedule:如果无法满足分布要求,就不调度新Pod(避免所有Pod都跑到一个节点)labelSelector:指定要应用这个约束的Pod标签(和你的Deployment的Pod标签一致)
添加完这个配置后,你需要先触发一次滚动更新(用上面的kubectl rollout restart命令)让配置生效。之后如果再出现节点故障恢复的情况,当有Pod需要重建时,调度器会自动把它调度到恢复的节点上,保持Pod的均匀分布。
方案3:使用Kubernetes Descheduler(集群级自动重平衡)
如果你的集群经常有节点故障恢复的场景,或者需要更自动化的重平衡,可以部署Descheduler组件。Descheduler会定期扫描集群,找出不符合调度策略的Pod(比如分布不均的Pod),然后驱逐它们,让调度器重新调度这些Pod到合适的节点上。
你需要部署Descheduler并配置对应的策略,比如启用RemovePodsViolatingTopologySpreadConstraint策略,它会自动处理拓扑分布不符合要求的Pod。部署完成后,当故障节点恢复,Descheduler会在下次运行时把多余的Pod从单个节点驱逐,调度器会把这些Pod重新分配到恢复的节点上,实现自动平衡。
内容的提问来源于stack exchange,提问作者user13702012

