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

如何确保节点组内每个节点至少运行1个Pod?

问题描述

我们拥有一个节点组,组内每个节点均带有相同标签acme/node-type: worker,该节点组包含2个Spot实例节点。
我们部署了一个副本数为3的Deployment,通过nodeAffinity配置将其调度到该节点组,配置如下:

spec:
  affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
       nodeSelectorTerms:
       - matchExpressions:
         - key: acme/node-type
           operator: In
           values:
           - worker

当某个Spot实例被回收后,所有Pod都会迁移到第二个节点;在2个节点都可用时,所有Pod集中在单个节点的情况并不理想。我们希望这3个副本的Deployment能够分布在2个节点上,确保节点组内每个节点至少运行1个Pod,请问是否可行?

尝试的方案1

topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: acme/node-type
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            acme/node-type: worker

调度情况示例图

解决方案

可行,但你当前的topologySpreadConstraints配置不对,达不到预期效果,问题出在这几点:

  • topologyKey用了acme/node-type,但这个标签是所有worker节点共有的,Kubernetes会把这些节点当成同一个拓扑组,根本没法实现节点级的Pod分布。
  • labelSelector匹配的是节点标签acme/node-type: worker,但拓扑分布约束里的labelSelector应该匹配你这个Deployment的Pod自己带的标签,不是节点标签。

你需要调整成下面的正确配置:

首先,确保你的Deployment的Pod模板有专属标签(比如app: my-worker-app,这个标签用来标识属于当前Deployment的Pod):

spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-worker-app
  template:
    metadata:
      labels:
        app: my-worker-app
    spec:
      # 保留原来的nodeAffinity配置
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: acme/node-type
                operator: In
                values:
                - worker
      # 新增正确的拓扑分布约束
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname  # 用节点的主机名作为拓扑区分依据,每个节点是独立的拓扑域
          whenUnsatisfiable: DoNotSchedule    # 不满足分布要求就不调度,避免Pod全堆在一个节点
          labelSelector:
            matchLabels:
              app: my-worker-app  # 匹配当前Deployment的Pod标签

配置说明

  • topologyKey: kubernetes.io/hostname:每个节点的主机名都是唯一的,Kubernetes会以此为依据,把Pod分散到不同节点上。
  • maxSkew: 1:要求任意两个节点上的Pod数量差不超过1。3个副本配2个节点,自然会分成2个和1个,保证每个节点至少有1个Pod。
  • whenUnsatisfiable: DoNotSchedule:如果只剩1个节点(比如某个Spot实例被回收),就暂时不调度多余的Pod;等新的worker节点可用时,Kubernetes会自动把Pod调度过去,恢复分布状态。

要是你希望节点不足时也能运行所有Pod(比如只剩1个节点时仍跑3个Pod),可以把whenUnsatisfiable改成ScheduleAnyway,等节点恢复后,Kubernetes会自动调整Pod的分布。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:05:33