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

如何在K8s中添加节点故障迁移规则及实现Pod跨节点分布

解决Kubernetes Pod跨节点分布的问题

这是K8s调度里很常见的场景,咱们先从排查原因到解决一步步来:

先排查为什么Pod都集中在node2

首先得搞清楚根因,执行下面几个命令看看:

1. 检查节点资源是否充足

先看看node1的资源是不是被占满了,导致调度器没法把Pod调度过去:

kubectl describe nodes node1 | grep -A 20 "Allocated resources"

看Allocated resources下面的Requests和Limits,如果CPU、内存的请求已经接近node1的Allocatable值,那调度器会优先选资源充足的node2。

2. 检查节点是否有污点

如果node1被加了污点(Taints),而你的api-server Pod没有对应的容忍度(Tolerations),调度器就不会把Pod调度到node1上:

kubectl describe node node1 | grep -A 10 "Taints"

如果输出里有类似NoSchedule或NoExecute的污点,那就是这个问题。

3. 检查Deployment的亲和性配置

看看你的api-server Deployment是不是特意配置了节点亲和性,强制要求Pod只能跑在node2上:

kubectl get deployment api-server -o yaml | grep -A 30 "affinity"

如果看到nodeAffinity里指定了node2的标签,那就是这个原因。


针对性解决方法

方法1:添加Pod反亲和性(最常用的解决方案)

给api-server的Deployment配置Pod反亲和性,让调度器尽量把同一个Deployment的Pod分布到不同节点。这是最通用的方法,即使只有2个节点,3个副本也会至少分到两个节点(2个在node2,1个在node1,或者反过来)。

编辑你的api-server Deployment:

kubectl edit deployment api-server

在spec.template.spec下面添加以下配置(注意values里的标签要和你的api-server Pod的app标签一致,可先用kubectl get pods api-server-xxx --show-labels确认):

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - api-server
        topologyKey: kubernetes.io/hostname

保存退出后,Deployment会滚动更新,Pod会重新调度,实现跨节点分布。

小贴士:如果要强制要求Pod必须分布在不同节点(但你的集群只有2个节点,3个副本的话会有一个Pod处于Pending状态,所以不建议),可以把preferredDuringSchedulingIgnoredDuringExecution换成requiredDuringSchedulingIgnoredDuringExecution。

方法2:移除节点污点(如果有)

如果node1有污点,比如不小心加上的NoSchedule污点,执行下面的命令移除(把<污点键>和<污点值>换成你查到的内容):

kubectl taint node node1 <污点键>:<污点值>-

比如查到的污点是node.kubernetes.io/unreachable:NoSchedule,就执行:

kubectl taint node node1 node.kubernetes.io/unreachable:NoSchedule-

方法3:调整节点资源或Pod资源请求

如果node1资源不足,要么给node1扩容(在AWS上就是调整EC2实例规格),要么修改Pod的资源请求,降低对CPU/内存的要求:
编辑Deployment:

kubectl edit deployment api-server

在spec.template.spec.containers.resources里调整requests的值:

resources:
  requests:
    cpu: "100m"  # 原来如果是500m,改成更小的值
    memory: "256Mi"  # 原来如果是1Gi,改成更小的值

方法4:移除错误的节点亲和性配置

如果Deployment里配置了强制调度到node2的节点亲和性,直接删除那部分配置即可,保存后Pod会重新调度。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:05:50