«

关于K8s调度策略(NodeSelector, Affinity, Anti-Affinity)

myluzh 发布于 阅读:14 Kubernetes


0x00 前言

在 Kubernetes 生产集群中,合理的调度策略是保障业务 高可用 (HA)低延迟 (Low Latency) 的核心。调度逻辑主要分为“节点选择”与“邻里关系”两大类。

本文将涵盖 nodeSelectorNode Affinity(硬限制/软限制/NotIn)、以及 Pod Affinity/Anti-Affinity 的实现方式。

graph TD
    %% 样式定义
    classDef logic fill:#f9f9f9,stroke:#333,stroke-width:2px;
    classDef node fill:#e1f5fe,stroke:#01579b;
    classDef pod fill:#fff3e0,stroke:#e65100;

    A[Pod 待调度] --> B{调度策略筛选}

    subgraph NodeSelection [节点选择维度]
        B --> C1[nodeSelector: 强匹配]:::logic
        B --> C2[NodeAffinity: 灵活逻辑]:::logic
    end

    subgraph PodTopology [Pod 关系维度]
        B --> D1[PodAffinity: 亲和/就近]:::logic
        B --> D2[PodAntiAffinity: 反亲和/分散]:::logic
    end

    C1 & C2 --> E[Node 节点]:::node
    D1 & D2 --> F[现有 Pod 拓扑]:::pod

0x01 基础调度:nodeSelector

nodeSelector 是最简单的强制性约束,仅支持 Exact Match(完全匹配)。

操作步骤

  1. 给节点打标签
root@k8s-master:~# kubectl label nodes node-01 disktype=ssd
  1. 配置 Pod 调度
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ssd
spec:
  nodeSelector:
    disktype: ssd  # 必须匹配,否则 Pod 无法调度 (Pending)
  containers:
  - name: nginx
    image: nginx:1.21

0x02 进阶节点调度:Node Affinity

Node Affinity 提供了比 nodeSelector 更丰富的操作符(In, NotIn, Exists, Gt, Lt)以及软硬限制。

1. 硬限制 (Required)

requiredDuringSchedulingIgnoredDuringExecution:必须满足,否则 Pending。

2. 软限制 (Preferred)

preferredDuringSchedulingIgnoredDuringExecution:尽量满足。调度器会计算权重(Weight),分高者优选。

3. Node 反亲和实现 (NotIn)

通过 operator: NotIn 实现排除逻辑。

YAML 示例:

spec:
  affinity:
    nodeAffinity:
      # 硬限制:必须在上海或北京
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/region
            operator: In
            values: ["shanghai", "beijing"]
      # 软限制:尽量避开不稳定机型 (Node 反亲和)
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 80
        preference:
          matchExpressions:
          - key: status
            operator: NotIn
            values: ["unstable-vendor"]

0x03 拓扑感知调度:Pod Affinity & Anti-Affinity

这组策略不关注 Node 标签,而是关注 Node 上已经运行了什么 Pod

1. 核心参数:topologyKey

用于定义“同一范围”的边界:

2. Pod 正亲和 (PodAffinity)

场景:将 Web 应用和其缓存(Redis)部署在一起,减少网络开销。

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: redis
        topologyKey: "kubernetes.io/hostname"

3. Pod 反亲和 (PodAntiAffinity) —— 生产高可用核心

场景:避免同一个服务的多个副本落在同一个节点上,防止单点故障。

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution: # 硬限制:禁止同台
      - labelSelector:
          matchLabels:
            app: web-server
        topologyKey: "kubernetes.io/hostname"

0x04 总结与逻辑对比

概念 作用对象 逻辑类型 典型场景
nodeSelector Node Label 硬限制 (In) 简单固定的机器分配
Node Affinity Node Label 硬/软 (In/NotIn) 复杂硬件要求、避开特定节点
Pod Affinity Pod Label 硬/软 业务就近部署,减少内网时延
Pod Anti-Affinity Pod Label 硬/软 生产环境高可用,副本分散

运维避坑指南

  1. IgnoredDuringExecution:所有的亲和性规则目前都只在“调度时”生效。如果 Pod 运行中 Node 标签变了,Pod 不会被自动驱逐。
  2. 计算开销PodAffinity 需要扫描集群内所有 Pod 的标签,在超过 500 个节点的大型集群中,大量使用会导致调度器明显变慢。
  3. 互斥检查:如果你同时定义了 Pod 正亲和与反亲和,且逻辑冲突,Pod 将永远处于 Pending 状态。

k8s pod 调度 亲和性 反亲和性 node 选择器


正文到此结束
版权声明:若无特殊注明,本文皆为 Myluzh Blog 原创,转载请保留文章出处。
文章内容:https://itho.cn/k8s/579.html
文章标题:《关于K8s调度策略(NodeSelector, Affinity, Anti-Affinity)