当前位置: 首页 > news >正文

Kubernetes 调度器 详解

1. 调度器在 K8s 中的位置与核心流程

API Server ←→ etcd ←→ kube-scheduler ←→ kubelet

  1. 创建:用户提交 Pod 描述(YAML/Helm/Operator)。

  2. 监听:调度器通过 Watch 机制捕获到 spec.nodeName="" 的 Pod。

  3. 过滤:根据资源、污点、亲和性等“硬性条件”过滤出可行节点(Feasible Nodes)。

  4. 打分:对可行节点按策略打分,最高分胜出。

  5. 绑定:将 spec.nodeName 写入 Pod 对象,目标节点的 kubelet 开始真正启动容器。

  6. 重调度:节点故障或资源不足 → 删除原 Pod → 回到步骤 2。

调度器是控制面唯一的“决策大脑”,但它不做网络/存储分配;它只是给 Pod 选“座位”。


2. 调度方式全景图

级别方法典型场景备注
强制nodeName排障、DaemonSet优先级最高,绕过调度器
标签nodeSelector指定 gpu=true、ssd=true简单,功能有限
亲和nodeAffinity软/硬亲和支持 In/NotIn/Gt/Lt/Exists
Pod 间podAffinity / podAntiAffinity同域部署、打散需大量计算,大集群慎用
污点taint + toleration隔离生产/测试、驱逐NoSchedule / PreferNoSchedule / NoExecute
高级多调度器、扩展器、Score 插件自定义算法自 1.19 支持 Scheduling Framework

3. 手把手实战:从简单到高阶

3.1 nodeName —— 一把梭,但风险高

apiVersion: v1
kind: Pod
metadata:name: one-shot-tool
spec:nodeName: k8s-node2      # 直接绑定,不经过调度器containers:- name: debugimage: alpine:latestcommand: ["sleep", "3600"]

缺点:节点不存在或资源不足时直接 Pending,调度器不会帮你重试。


3.2 nodeSelector —— 80% 场景已够用

# 给节点打标签
kubectl label node k8s-node1 disktype=ssd zone=beijing
spec:nodeSelector:disktype: ssdzone: beijing

小技巧:对同一类节点批量打标签 kubectl label node -l node-role.kubernetes.io/worker= tier=frontend


3.3 nodeAffinity —— 软/硬策略组

  • nodeaffinity支持多种规则匹配条件的配置如

匹配规则功能
lnlabel 的值在列表内
Notlnlabel 的值不在列表内
Gtlabel 的值大于设置的值,不支持Pod亲和性
Ltlabel 的值小于设置的值,不支持pod亲和性
Exists设置的label 存在
DoesNotExist设置的 label 不存在
affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:   # 必须满足nodeSelectorTerms:- matchExpressions:- {key: disktype, operator: In/NotIn(#在节点中或不在), values: ["ssd"]}preferredDuringSchedulingIgnoredDuringExecution:  # 尽量满足- weight: 50preference:matchExpressions:- {key: zone, operator: In, values: ["beijing"]}
  • IgnoreDuringExecution:节点标签变更后,已运行 Pod 不动。

  • 支持 Gt/Lt 做资源范围筛选,如 cpu 核数大于 32。


3.4 Pod 间亲和与反亲和

  • 那个节点有符合条件的POD就在那个节点运行

  • podAffinity 主要解决POD可以和哪些POD部署在同一个节点中的问题

  • podAntiAffinity主要解决POD不能和哪些POD部署在同一个节点中的问题。它们处理的是Kubernetes集群内部POD和POD之间的关系。

  • Pod 间亲和与反亲和在与更高级别的集合(例如 ReplicaSets,StatefulSets,Deployments 等)一起使用时,

  • Pod 间亲和与反亲和需要大量的处理,这可能会显著减慢大规模集群中的调度。

3.4.1 亲和:主要解决POD可以和哪些POD部署在同一个节点中的问题

3.4.2 反亲和:主要解决POD不能和哪些POD部署在同一个节点中的问题

经验值:大规模集群开启 topologyKey: topology.kubernetes.io/zone 可实现跨可用区打散。


3.5 Taint & Toleration —— 隔离与驱逐双杀

3.5.1 概念
  • Taints(污点)是Node的一个属性,设置了Taints后,默认Kubernetes是不会将Pod调度到这个Node上

  • Kubernetes如果为Pod设置Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去

  • 可以使用命令 kubectl taint 给节点增加一个 taint:

$ kubectl taint nodes <nodename> key=string:effect   #命令执行方法
$ kubectl taint nodes node1 key=value:NoSchedule    #创建
$ kubectl describe nodes server1 | grep Taints        #查询
$ kubectl taint nodes node1 key-                  #删除

其中[effect] 可取值:

effect作用常用场景
NoSchedule新 Pod 不来GPU 节点仅跑 AI 任务
PreferNoSchedule尽量不调度线上节点留有余量
NoExecute已运行 Pod 驱逐节点维护、内核升级
3.5.2 实战:

测试污点容忍,node1,node2都设置为NoSchedule

未设置容忍的则显示为pending


4. 调度器扩展:自定义策略与性能

4.1 多调度器

当默认调度器无法满足业务场景(如 GPU Binpack、Spark 动态资源)时,可部署自定义调度器并指定:

spec:schedulerName: volcano

4.2 Scheduling Framework(1.19+)

通过插件链在 PreFilter / Filter / Score / Reserve / Permit / Bind 阶段插入自定义逻辑,无需重编 kube-scheduler。
示例:NodeResourcesFit、PodTopologySpread、Coscheduling(gang scheduling)。

4.3 性能调优

  • 大规模集群建议开启 percentageOfNodesToScore(默认 50%),减少打分节点数量。

  • 监控指标:scheduler_binding_duration_secondsscheduler_scheduling_attempt_duration_seconds


5. 排查 Pod 无法调度的一页速查

现象可能原因排查命令
Pending资源不足kubectl describe pod → Events
Pending节点污点kubectl get node -o json | jq '.items[].spec.taints'
Pending亲和冲突kubectl get pod -o wide 查标签
PendingPVC 未绑定kubectl get pvc
Node Lost节点 NotReadykubectl get node, 查 kubelet / 网络 / 磁盘

6. 总结与最佳实践

  1. 90% 场景
    nodeSelector + nodeAffinity + podAntiAffinity 即可满足。

  2. 污点策略
    • 生产节点:dedicated=production:NoSchedule
    • 测试节点:env=test:PreferNoSchedule

  3. 大规模集群
    • 避免 topologyKey 过细,减少计算量。
    • 使用 namespace + 污点做物理隔离,而非反亲和暴力打散。

  4. 持续治理
    • 每个季度 review 节点标签、污点、调度策略。
    • 用 Gatekeeper / Kyverno 做策略即代码(Policy as Code)。


附录:一键清理实验资源
kubectl delete pod,deploy --all --grace-period=0 --force

http://www.dtcms.com/a/344990.html

相关文章:

  • 加密货币与区块链:六大刑事重灾区
  • Vue3源码reactivity响应式篇之Reactive
  • 阿里云日志服务与Splunk集成方案(Splunk Add-on方式)实战
  • GitGithub相关(自用,持续更新update 8/23)
  • 通义万相:AI生视频提示词生成秘籍/指南
  • 高空作业智能安全带如何监控使用异常行为
  • Linux 下的网络编程
  • Linux笔记8——shell编程基础-2
  • ROS学习笔记1-幻宇机器人为模板
  • Windows11 家庭版永久解密BitLocker加密移动硬盘
  • 【Java并发编程】Java多线程深度解析:状态、通信与停止线程的全面指南
  • RK3506-PWM计数功能
  • c#实现鼠标mousemove事件抽稀,避免大数据阻塞网络
  • 【COMSOL】Comsol学习案例时的心得记录分享(三)
  • 罗技鼠标驱动下载教程 多种方法详细说明
  • 排序---插入排序
  • CS 创世 SD NAND 助力 T-BOX:破解智能汽车数字中枢的存储密码
  • 110、【OS】【Nuttx】【周边】效果呈现方案解析:查找最新构建件
  • C++/QT 开发技能树详解
  • 钉钉 Stream 模式SpringBoot接入配置与事件监听
  • Maxscript如何清理3dMax场景?
  • react样式问题
  • git旧仓库迁移到新仓库
  • [系统架构设计师]安全架构设计理论与实践(十八)
  • Web3与AI语境下的审美积累:HAQQ品牌识别解析
  • 多人编程新方式:cpolar 让 OpenHands 远程开发更轻松
  • 区块链技术原理(17)-以太坊网络
  • SpringBoot中的条件注解
  • 常用三角函数公式推导体系
  • LLM应用场景能力边界趋势全览