K8s 调度管理

K8s 调度管理

1. 节点选择器(nodeSelector)

  • 最简单的节点调度约束机制。

  • 在 Pod 规范中指定某个 Label,只有具有该 Label 的 Node 才能被调度。

  • 缺点 :功能简单,只支持 等于匹配

示例:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  nodeSelector:
    diskType: ssd
  containers:
    - name: db
      image: mysql:5.7

👉 Pod 只能调度到带有 disktype=ssd 标签的节点上。


2. 节点亲和度(Node Affinity)

相比 nodeSelector,节点亲和度更灵活,支持 集合操作In/NotInGt/Lt 等表达式。

分两类:

  • 强制 (requiredDuringSchedulingIgnoredDuringExecution)

    必须满足条件,否则 Pod 无法调度。

  • 偏好 (preferredDuringSchedulingIgnoredDuringExecution)

    调度器会"尽量"满足,但不保证。

示例:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod1
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:      # 匹配表达式
          - key: diskType        # 标签键
            operator: In         # 操作符
            values:              # 标签键对应的值,可以包含多个值
            - ssd
  containers:
    - name: db
      image: mysql:5.7

apiVersion: v1
kind: Pod
metadata:
  name: web-pod2
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: topologyZone
            operator: In
            values:
            - beijing
  containers:
    - name: db
      image: nginx:1.23

👉 强制要求:必须在 disktype=ssd 的节点上

👉 偏好要求:最好在 region=us-east-1 的节点上


Kubernetes 节点/Pod 亲和性规则中的 operator 工作机制

在调度规则(nodeSelectorTerms.matchExpressionspodAffinity/podAntiAffinity)里,operator 是用来描述 标签的匹配方式 的核心字段。

1 operator 的作用

  • operator 定义了 如何根据 key 与 values 判断条件是否成立

  • 调度器 (kube-scheduler) 在分配 Pod 到节点时,会依次检查这些条件。

  • 如果条件不满足:

    • 强制型规则requiredDuringSchedulingIgnoredDuringExecution)下,Pod 不能调度。

    • 偏好型规则preferredDuringSchedulingIgnoredDuringExecution)下,Pod 仍能调度,但会降低优先级。


2 常见 operator 及机制

In

  • 含义:标签键存在,并且值在指定集合中。

  • 例子

    复制代码
    - key: diskType
      operator: In
      values: ["ssd", "nvme"]

    👉 节点必须有 diskType=ssddiskType=nvme


NotIn

  • 含义:标签键存在,并且值不在指定集合中。

  • 例子

    复制代码
    - key: diskType
      operator: NotIn
      values: ["hdd"]

    👉 节点必须有 diskType,且值不是 hdd


Exists

  • 含义:只要标签键存在即可,不要求具体值。

  • 例子

    复制代码
    - key: gpuType
      operator: Exists

    👉 节点只要打了 gpuType=xxx 标签即可。


DoesNotExist

  • 含义:标签键不存在。

  • 例子

    复制代码
    - key: gpuType
      operator: DoesNotExist

    👉 节点上不能有 gpuType 标签。


Gt(大于)

  • 含义 :标签值必须是 整数,节点该 key 的值 > 指定值。

  • 例子

    复制代码
    - key: cpuCount
      operator: Gt
      values: ["8"]

    👉 节点的 cpuCount 标签必须是 整数 > 8


Lt(小于)

  • 含义 :标签值必须是 整数,节点该 key 的值 < 指定值。

  • 例子

    复制代码
    - key: cpuCount
      operator: Lt
      values: ["32"]

    👉 节点的 cpuCount 必须 < 32。


3 工作机制总结

调度器检查时:

  1. 取出 Pod 的规则(affinity/anti-affinity)。

  2. 遍历 matchExpressions 列表(同一组是 AND 关系)。

  3. 每个 matchExpression 内部的 values 用 operator 来判断。

  4. nodeSelectorTerms 中多个 term 是 OR 关系,只要有一个 term 满足就行。


4 例子

复制代码
nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchExpressions:
      - key: diskType
        operator: In
        values: ["ssd"]
      - key: region
        operator: NotIn
        values: ["us-east-1"]

逻辑等价于:

复制代码
(diskType == "ssd") AND (region != "us-east-1")

如果有多个 nodeSelectorTerms,逻辑会变成:

复制代码
term1 OR term2 OR term3 ...

3. Pod 与 Pod 亲和性 / 反亲和性

Pod 之间的调度关系,可以让 Pod 贴在一起 或者分开运行

Pod 亲和性 (Pod Affinity)

  • 强制或偏好要求 Pod 调度到与某些 Pod 在一起的节点(例如共享机架,低延迟)。

Pod 反亲和性 (Pod Anti-Affinity)

  • 强制或偏好要求 Pod 避开某些 Pod(例如避免多个副本在同一台机器上,提升高可用性)。

示例:

复制代码
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
          - frontend
      topologyKey: "kubernetes.io/hostname"
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - frontend
        topologyKey: "kubernetes.io/hostname"

👉 强制:Pod 必须调度到有 app=frontend 的节点上

👉 偏好:尽量避免与 app=frontend 的 Pod 在同一节点


详细例子

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web-pod-affinity
spec:
  affinity:
    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - db
          topologyKey: kubernetes.io/hostname
  containers:
  - name: web
    image: nginx:1.23

逐行解释这个 Pod 配置 ,重点是 Pod 亲和性 (PodAffinity) 的字段含义:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web-pod-affinity
  • apiVersion: v1 → 使用的 Kubernetes API 版本。
  • kind: Pod → 定义的资源类型是 Pod。
  • metadata.name: web-pod-affinity → Pod 的名字。

复制代码
spec:
  affinity:
    podAffinity:
  • spec → Pod 的规格定义。
  • affinity → Pod 的调度亲和性规则。
  • podAffinity → Pod 亲和性,表示希望这个 Pod 调度到与某些 Pod 靠近(在同一拓扑范围内) 的节点上

复制代码
      preferredDuringSchedulingIgnoredDuringExecution:
  • preferredDuringSchedulingIgnoredDuringExecution → 偏好型规则(软约束)。

    • 如果能满足条件,调度器会优先选择符合条件的节点;

    • 如果条件不满足,也不会阻止 Pod 被调度(Pod 仍然可以运行,只是没有优先级)。

  • 对比:

    • requiredDuringSchedulingIgnoredDuringExecution → 强制约束(硬条件,不满足则 Pod 无法调度)。

复制代码
      - weight: 100
  • weight: 100 → 权重,取值范围 1--100

  • 多个偏好规则时,调度器会根据权重打分,权重高的规则影响力更大。

  • 这里100 表示最高优先级。


复制代码
        podAffinityTerm:
  • podAffinityTerm → 定义 Pod 亲和性的具体条件。

复制代码
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - db
  • labelSelector → 选择目标 Pod 的标签。

  • matchExpressions → 匹配条件。

    • key: app → 匹配 app 标签。

    • operator: In → 取值在指定集合中。

    • values: ["db"] → 标签必须是 app=db

👉 也就是说:当前 Pod 期望调度到和已有 app=db 的 Pod 在同一拓扑范围的节点上


复制代码
          topologyKey: kubernetes.io/hostname
  • topologyKey → 定义"靠近"的范围(拓扑域)。

  • kubernetes.io/hostname → 表示同一个节点(即 Node)。

  • 也可以设置成 topology.kubernetes.io/zone(同一个可用区)或 topology.kubernetes.io/region(同一个区域)。

👉 这里表示:调度器会优先把该 Pod 调度到已经运行了 app=db Pod 的同一台 Node 上


复制代码
  containers:
  - name: web
    image: nginx:1.23
  • 定义 Pod 里的容器。

  • name: web → 容器名字。

  • image: nginx:1.23 → 使用的镜像


总结

  • Pod 名为 web-pod-affinity,运行一个 Nginx 1.23 容器。

  • 使用 Pod 亲和性,软约束。

  • 希望它能调度到 与已有标签 app=db 的 Pod 同一节点topologyKey=kubernetes.io/hostname)上。

  • 权重 100,优先级最高。


4. 污点与容忍(Taints & Tolerations)

  • 污点 (Taint):给 Node 打上"拒绝某类 Pod"的标记。

  • 容忍 (Toleration):Pod 上的属性,可以"忍受"某些污点,从而被调度到该 Node。

常见用途

  • 专用节点(只运行特定 Pod)。

  • 隔离节点(只允许具备特定容忍的 Pod 运行)。

  • 节点异常(如不可达、内存压力)时调度器驱逐 Pod。

添加污点:

复制代码
kubectl taint nodes node1 key=value:NoSchedule

Pod 容忍:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: tensorflow-pod2
spec:
  tolerations:
  - key: gpu
    operator: Equal
    value: "nvidia"
    effect: NoSchedule
  nodeSelector:
    gpu: "nvidia"
  containers:
  - name: tf
    image: tensorflow/tensorflow:latest

👉 Pod 只有带了对应容忍,才能调度到有该污点的节点。


5. NodeName

  • 直接指定 Pod 运行在哪个节点上。

  • 一般用于测试或特定场景,不推荐大规模使用,因为绕过了调度器。

示例:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  nodeName: k8s-node1
  containers:
  - name: web
    image: busybox
    command: ['/bin/sh', '-c', "sleep 1d"]

相关推荐
✎﹏赤子·墨筱晗♪1 小时前
Ansible Playbook 入门指南:从基础到实战
linux·服务器·ansible
小白不想白a1 小时前
【Ansible】使用ansible部署k8s集群前的准备工作脚本
容器·kubernetes·ansible
乌萨奇也要立志学C++2 小时前
【Linux】进程概念(六):进程地址空间深度解析:虚拟地址与内存管理的奥秘
linux·运维
月殇_木言6 小时前
Linux 线程
linux
wangjialelele6 小时前
Linux中的线程
java·linux·jvm·c++
极客天成ScaleFlash7 小时前
极客天成让统一存储从云原生‘进化’到 AI 原生: 不是版本升级,而是基因重组
人工智能·云原生
2301_800050998 小时前
DNS 服务器
linux·运维·笔记
Lin_Aries_04218 小时前
容器化简单的 Java 应用程序
java·linux·运维·开发语言·docker·容器·rpc
SELSL8 小时前
SQLite3的API调用实战例子
linux·数据库·c++·sqlite3·sqlite实战
小闫BI设源码8 小时前
Dockerfile
云原生·eureka·日志收集·自动重启·容器监控·健康检查·生产环境部署