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"]

相关推荐
2302_799525743 小时前
【Hadoop】Hadoop集群安装中出现的问题
linux·hadoop
milanyangbo3 小时前
“卧槽,系统又崩了!”——别慌,这也许是你看过最通俗易懂的分布式入门
分布式·后端·云原生·架构
刘一说3 小时前
Linux调试命令速查:Java/微服务必备
java·linux·微服务
枫の准大一3 小时前
【Linux游记】基础指令篇
linux
ypf52083 小时前
OrbStack 配置国内镜像加速
linux
大咖分享课3 小时前
系统越拆越乱?你可能误解了微服务的本质!
微服务·云原生·架构
Hello.Reader3 小时前
一文通关 Proto3完整语法与工程实践
java·linux·数据库·proto3
Hello.Reader4 小时前
一文吃透 Protobuf “Editions” 模式从概念、语法到迁移与实战
linux·服务器·网络·protobuf·editions
陌上花开缓缓归以4 小时前
linux ubi文件系统
linux