在K8S中,影响Pod调度策略的有哪些?

在Kubernetes中,Pod的调度策略由kube-scheduler(默认调度器)或自定义调度器决定,其核心目标是将Pod合理分配到集群节点上。影响调度策略的因素可分为调度约束资源因素节点特性策略配置等几大类,具体如下:

1. 标签与选择器(基础匹配规则)

标签(Label)是K8s中用于资源关联的核心机制,直接影响Pod与节点的匹配:

  • nodeSelector:Pod通过 spec.nodeSelector 字段指定节点标签,只有带有对应标签的节点才会被调度(硬约束,必须满足)。
    示例:
    spec:
      nodeSelector:
        env: production  # 仅调度到带有 env=production 标签的节点
    
  • 作用:实现简单的节点筛选(如区分生产/测试环境节点、CPU架构节点等)。

2. 亲和性与反亲和性(灵活的匹配策略)

nodeSelector 更灵活的调度规则,支持硬约束(必须满足)软约束(优先满足),分为三类:

(1)节点亲和性(Node Affinity)

Pod对节点的偏好,通过节点标签筛选节点:

  • 硬亲和(requiredDuringSchedulingIgnoredDuringExecution:必须满足条件,否则Pod无法调度。
  • 软亲和(preferredDuringSchedulingIgnoredDuringExecution:优先满足,若不满足也可调度到其他节点(按权重排序)。

示例:

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 硬约束
        nodeSelectorTerms:
        - matchExpressions:
          - key: disk
            operator: In
            values: ["ssd"]  # 必须调度到带 disk=ssd 标签的节点
      preferredDuringSchedulingIgnoredDuringExecution:  # 软约束
      - weight: 100
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values: ["zone-1"]  # 优先调度到 zone-1 可用区

(2)Pod亲和性(Pod Affinity)

基于已运行Pod的标签,让新Pod调度到“相关Pod所在的节点”(如服务A和服务B需部署在同一节点提高通信效率)。

  • 硬约束:requiredDuringSchedulingIgnoredDuringExecution
  • 软约束:preferredDuringSchedulingIgnoredDuringExecution

示例:

spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:  # 软约束
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values: ["backend"]  # 优先调度到有 app=backend Pod 的节点
          topologyKey: kubernetes.io/hostname  # 按节点维度判断“相关”

(3)Pod反亲和性(Pod Anti-Affinity)

与Pod亲和性相反,让新Pod远离“相关Pod所在的节点”(如避免单节点部署多个相同服务实例,提高可用性)。

示例:

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 硬约束
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["web"]  # 禁止调度到已有 app=web Pod 的节点
        topologyKey: kubernetes.io/hostname  # 按节点维度隔离

3. 污点(Taint)与容忍(Toleration)

节点通过“污点”主动排斥Pod,Pod需通过“容忍”才能被调度到带污点的节点,是节点“主动筛选”Pod的机制:

  • 污点(Taint):节点通过 kubectl taint nodes <node-name> <key>=<value>:<effect> 添加,effect 决定排斥行为:

    • NoSchedule:仅影响新Pod调度,不驱逐已运行Pod;
    • PreferNoSchedule:尽量不调度新Pod到该节点(软约束);
    • NoExecute:不仅不调度新Pod,还会驱逐已运行的、无对应容忍的Pod。
  • 容忍(Toleration):Pod通过 spec.tolerations 声明对污点的容忍,才能被调度到对应节点。

示例:

# 节点添加污点:禁止无容忍的Pod调度(如主节点默认有 node-role.kubernetes.io/master:NoSchedule)
kubectl taint nodes node1 dedicated=special:NoSchedule

# Pod添加容忍,允许被调度到 node1
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "special"
    effect: "NoSchedule"

4. 资源需求与限制(节点资源可用性)

kube-scheduler会优先选择“资源充足”的节点,避免Pod因资源不足而异常:

  • 资源需求(requests:Pod声明的最小资源需求(如CPU、内存),调度器仅会选择满足 节点可用资源 ≥ Pod requests总和 的节点。
  • 资源限制(limits:Pod允许使用的最大资源,不直接影响调度,但影响节点资源分配的“余量”。

示例:

spec:
  containers:
  - name: app
    resources:
      requests:  # 调度时必须满足的最小资源
        cpu: "100m"  # 100毫核
        memory: "128Mi"
      limits:  # 最大资源限制
        cpu: "500m"
        memory: "256Mi"

5. 节点条件与状态(节点健康性)

节点的健康状态直接影响调度,调度器会过滤掉“不健康”的节点:

  • 节点就绪(Ready):节点必须处于 Ready=true 状态(通过 kubectl get nodes 查看),否则无法调度Pod;
  • 资源压力:节点若有内存压力(MemoryPressure)、磁盘压力(DiskPressure)等,调度器会避免将Pod调度到该节点;
  • 网络不可达:节点与API Server通信中断时,会被标记为 NotReady,无法接收新Pod。

6. 优先级与抢占(资源竞争时的策略)

当集群资源不足时,高优先级Pod可“抢占”低优先级Pod的资源:

  • Pod优先级:通过 priorityClassName 关联 PriorityClass 资源,数值越高优先级越高(默认0,可自定义)。
  • 抢占机制:若高优先级Pod因资源不足无法调度,调度器会驱逐低优先级Pod(从资源最匹配的节点),腾出资源供高优先级Pod使用。

示例:

# 定义高优先级
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000  # 优先级数值

# Pod使用高优先级
spec:
  priorityClassName: high-priority

7. 拓扑分布约束(Topology Spread Constraints)

为避免Pod集中在少数节点/可用区(单点故障风险),通过拓扑分布约束将Pod“均匀分布”在不同拓扑域(如节点、可用区、机架):

示例:

spec:
  topologySpreadConstraints:
  - maxSkew: 1  # 不同拓扑域中Pod数量的最大差值
    topologyKey: topology.kubernetes.io/zone  # 按可用区分布
    whenUnsatisfiable: ScheduleAnyway  # 不满足时仍可调度(可选DoNotSchedule)
    labelSelector:
      matchLabels:
        app: web  # 针对带 app=web 标签的Pod进行分布控制

8. 自定义调度器

默认调度器(kube-scheduler)适用于大多数场景,若有特殊需求(如基于硬件特性、自定义指标的调度),可部署自定义调度器,通过 spec.schedulerName 指定Pod使用的调度器:

示例:

spec:
  schedulerName: my-custom-scheduler  # 使用自定义调度器

总结

影响Pod调度的核心因素可归纳为:

  • 匹配规则:标签选择器、亲和性/反亲和性;
  • 节点筛选:污点与容忍、节点健康状态;
  • 资源管理:资源需求、优先级与抢占;
  • 分布策略:拓扑分布约束;
  • 扩展机制:自定义调度器。

这些因素共同决定了Pod最终被调度到哪个节点,合理配置可提高集群资源利用率和服务可用性。

posted @ 2025-08-11 10:15  天道酬勤zjh  阅读(19)  评论(0)    收藏  举报