K8s知识(3) Pod亲和性,调度

一、 Pod 调度策略深度解析

Kubernetes 的默认调度器(default-scheduler)通过三个核心步骤将 Pod 分配到节点上:

  1. 预选(Predicates):排除不满足基本条件的节点(如内存不足、端口冲突)。

  2. 优选(Priorities):在剩余节点中,根据权重进行打分(如选择资源利用率低的节点)。

  3. 绑定:将 Pod 绑定到得分最高的节点。

除了默认的调度逻辑,我们可以通过以下策略控制 Pod 的去向:

1. 节点标签与调度
  • 指定节点名称调度(硬指定)

    • 特点:绕过调度器,强制 Pod 运行在特定节点。

    • 场景:测试环境或特殊硬件需求的节点。

    • 配置 :在 spec.nodeName中指定节点名。

  • 指定节点标签调度(软指定)

    • 特点:通过节点标签(Labels)进行匹配,需经过调度器。

    • 逻辑步骤

      1. 给节点打标签:kubectl label nodes <node-name> <key>=<value>

      2. 编辑 Pod YAML,使用 nodeSelector指定标签。

2. 亲和性策略(Affinity)

亲和性用于表达"偏好"或"强制要求",分为节点亲和性(Node Affinity)Pod 亲和性(Pod Affinity)

  • 节点亲和性 (nodeAffinity)

    • 作用:让 Pod 倾向于运行在带有特定标签的节点上。

    • 策略类型

      • requiredDuringSchedulingIgnoredDuringExecution硬策略,必须满足,否则 Pod 处于 Pending 状态。

      • preferredDuringSchedulingIgnoredDuringExecution软策略,尽量满足,不满足也能运行。

    • 匹配逻辑(操作符)

      • In, NotIn:包含/不包含(最常用)。

      • Exists, DoesNotExist:存在/不存在(只需判断键,无需值)。

      • Gt, Lt:大于/小于(针对整数值)。

  • Pod 亲和性 (podAffinity)

    • 作用:让 Pod 倾向于与其他 Pod 运行在同一拓扑域(如同一节点、同一可用区)。

    • 场景:微服务间的低延迟通信(如前端与后端同节点)。

    • 反亲和性 (podAntiAffinity) :让 Pod 尽量与其他 Pod 运行在同一拓扑域。

    • 核心配置

      • labelSelector:选择哪些 Pod 的标签作为参照。

      • topologyKey:定义"拓扑域"的键(通常使用 kubernetes.io/hostname表示节点级别,或使用云平台标签表示可用区级别)。

3. 实战示例
  • 示例 1:节点亲和性(软策略)

    复制代码

    yaml

    yaml

    复制代码
    affinity:
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
            - key: env
              operator: In
              values: [ "production" ]
    • 解释 :尽量将 Pod 调度到 env=production的节点,如果没有,也可以运行在其他节点。
  • 示例 2:Pod 反亲和性(硬策略)

    复制代码

    yaml

    yaml

    复制代码
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values: [ "myapp" ]
          topologyKey: kubernetes.io/hostname
    • 解释 :强制要求同一个节点上不能运行两个 app=myapp的 Pod(实现高可用,避免单点故障)。

二、 污点与容忍度(Taints & Tolerations)

污点是节点的属性,用于排斥 ​ Pod;容忍度是 Pod 的属性,用于允许被调度到有污点的节点。

1. 污点的作用
  • NoSchedule:不将 Pod 调度到带有该污点的节点(除非 Pod 有容忍度)。

  • PreferNoSchedule:尽量避免调度,但不是强制。

  • NoExecute:不调度新 Pod,并驱逐节点上已有的 Pod(除非 Pod 有容忍度)。

2. 设置污点
复制代码

bash

bash

复制代码
kubectl taint node <node-name> <key>=<value>:<effect>
  • 示例

    复制代码

    bash

    bash

    复制代码
    kubectl taint node k8s-node01 key1=value1:NoSchedule
3. 容忍度(Tolerations)

在 Pod 的 YAML 中添加 tolerations字段,允许 Pod 被调度到有特定污点的节点。

  • 配置示例

    复制代码

    yaml

    yaml

    复制代码
    tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"
  • 解释 :该 Pod 可以容忍 key1=value1:NoSchedule的污点,因此可以被调度到 k8s-node01

4. 典型应用场景
  • 专用节点 :给 GPU 节点打上 dedicated=gpu:NoSchedule污点,只有带有容忍度的 Pod(如 AI 训练任务)才能运行。

  • 维护模式 :给节点打上 maintenance=true:NoExecute污点,驱逐所有非必要 Pod,进行维护。

  • 弹性伸缩:在云平台上,通过污点标记节点即将被销毁,让 Pod 自动迁移。


三、 综合实战场景

场景:我们有一个 Redis 集群,希望:

  1. Redis Pod 尽量运行在可用区 A(杭州)。

  2. Redis Pod 之间不能运行在同一节点(避免单点故障)。

  3. 只有带有 redis-role=master标签的节点才能运行 Redis Pod。

YAML 配置

复制代码

yaml

yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: redis-pod
  labels:
    app: redis
spec:
  containers:
  - name: redis
    image: redis:latest
  affinity:
    # 1. 节点亲和性:尽量运行在可用区A(假设可用区A的标签是 zone=hangzhou)
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values: [ "hangzhou" ]
    # 2. Pod反亲和性:不能运行在同一节点
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: [ "redis" ]
        topologyKey: kubernetes.io/hostname
  # 3. 节点亲和性(硬策略):必须运行在带有 redis-role=master 标签的节点
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - matchExpressions:
      - key: redis-role
        operator: In
        values: [ "master" ]

四、 总结

概念 作用 方向 示例
节点亲和性 Pod 倾向于运行在特定标签的节点 Pod → Node env=production
Pod 亲和性 Pod 倾向于与其他 Pod 同拓扑域 Pod → Pod 同节点、同可用区
Pod 反亲和性 Pod 倾向于不与其他 Pod 同拓扑域 Pod → Pod 不同节点、不同可用区
**污点 (Taint)**​ 节点排斥 Pod Node → Pod dedicated=gpu:NoSchedule
**容忍度 (Toleration)**​ Pod 允许被调度到有污点的节点 Pod → Node 容忍 dedicated=gpu:NoSchedule

通过合理组合亲和性和污点,可以实现复杂的调度策略,满足生产环境的高可用、资源隔离、成本优化等需求。

相关推荐
Linux-18743 小时前
分布式链路追踪系统之二进制安装skywalking
elasticsearch·云原生·skywalking·分布式链路追踪系统·应用程序性能监控
BullSmall7 小时前
Anolis OS 8.10 完整安装 Docker CE(生产可用,解决 podman 冲突)
docker·容器·podman
heimeiyingwang8 小时前
【架构实战】可观测性三支柱:日志、指标、链路的融合
elasticsearch·架构·kubernetes
阿里云云原生10 小时前
阿里云 AgentTeams 7月第二周产品动态
云原生
CodexDave14 小时前
数据库连接池耗尽:排查顺序与三层兜底
服务器·前端·数据库·git·云原生·容器·kubernetes
java_logo14 小时前
ELK Docker Compose 部署指南:轻松搭建日志检索平台
elk·elasticsearch·docker·容器·kibana·logstash·轩辕镜像
ShallWeL14 小时前
Orin 上用 Docker 跑通目标检测功能
人工智能·目标检测·docker·容器
辰同学ovo16 小时前
用“舞台换景”讲清 Docker 的 Restart 与 Recreate
运维·docker·容器
名字还没想好☜16 小时前
Kubernetes Ingress 实战:域名路由、TLS 证书与 502/404 排查
运维·云原生·容器·kubernetes·ingress
Zhu75817 小时前
在k8s部署alist 3.62.0
云原生·容器·kubernetes