Kubernetes的调度机制和基于节点的Pod调度

📅 2026/7/19 5:45:33
Kubernetes的调度机制和基于节点的Pod调度
Pod 调度框架调度机制基础知识Kubernetes的调度是指为新创建的Pod挑选一个最佳的运行节点kube-scheduler是 kubernetes 系统的核心组件之一主要负责整个集群Pod资源的调度功能kube-scheduler 负责分配调度 Pod 到集群内的节点上它 watch 监听 kube-apiserver查询还未分配Node 的 Pod (Pod 的 nodeName 字段为空),然后根据调度策略为这些 Pod 分配节点(更新 Pod 的nodeName 字段)。kube-scheduler 根据特定的调度算法和策略将 Pod 调度到最优的工作节点上面去从而更加合理、更加充分的利用集群的资源什么是最优节点满足Pod资源要求,包括资源限制 Resource limit ,QoS(Guaranteed/Burstable/BestEffort)等,资源配额 Resource quota满足Pod的特殊关系要求,包括Pod 亲和与反亲和满足Node限制条件要求,包括Node Selector, 污点和容忍实现集群资源合理利用image调度队列Scheduling Queue 产生的原因任务优先级的确定单个对象kubectl explain pod.spec.priority, 值越高,优先级越高,默认为0优先级分类kubectl explain pod.spec.priorityClassName调度过程当Scheduler通过API server 的watch接口监听到新建Pod副本的信息后它会检查所有符合该Pod要求的Node列表开始执行Pod调度逻辑。调度成功后将Pod绑定到目标节点上。Scheduler在整个系统中承担了承上启下的作用承上是负责接收创建的新Pod为安排一个落脚的地Node,启下是安置工作完成后目标Node上的kubelet服务进程接管后继工作负责Pod生命周期的后半生。具体来说Scheduler的作用是将待调度的Pod安装特定的调度算法和调度策略绑定到集群中的某个合适的Node上并将绑定信息传给API server 写入etcd中。若没有任何一个节点能满足Pod的资源需求则该Pod将被置于Pending状态直至出现合适的节点整个调度过程中涉及三个对象分别是待调度的Pod列表可以运行Pod的Node列表以及调度算法和策略。调度功能这个过程在实际的生产环境中需要考虑的问题就有很多如何保证全部的节点调度的公平性要知道并不是所有节点资源配置都是一样的如何保证每个节点都能被分配资源集群资源如何能够被高效利用集群资源如何才能被最大化使用如何保证 Pod 调度的性能和效率用户是否可以根据自己的实际需求定制自己的调度策略考虑到实际环境中的各种复杂情况kubernetes 的调度器采用插件化的形式实现可以方便用户进行定制或者二次开发我们可以自定义一个调度器并以插件形式和 kubernetes 进行集成。调度模型kubernetes 管理平台自动出现以来其资源调度策略一直在发展中。单从资源的调度框架的层面来分析先后经历了两个调度的阶段传统调度阶段、新型调度阶段调度模型kubernetes的调度框架 经历了两个大的阶段的模型传统调度模型最初的调度器基于一套预定义的规则和算法例如资源请求和节点容量的匹配。调度决策分为两个阶段预选Predicates阶段和优先级Priorities阶段。预选用于过滤不合适的节点优先级用于对剩余的节点打分并选择最优节点。image预选策略(predicate)预选即挑选出可以运行的节点, 过滤掉不合格的节点遍历nodelist排除不满足条件的节点剩余为符合要求的候选节点k8s内置了多种预选规则供用户选择。只要有一个预选算法不满足该Pod就不能被调度至该节点上如没有Node符合Predicates策略规则那该Pod就会被挂起直到有Node能够满足。优选策略(priority)优选即评分高的优先在选择出符合要求的候选节点中采用优选规则计算出每个节点的总积分最后选择得分最高的。选定(select)如果最高得分有多个节点select就会从中随机选择一个节点。扩展支持image虽然kubernetes 提供了非常多的预选策略函数和优选策略函数但仍可能需要实现定制更多的功能扩充支持两种扩展方案。多调度器 - 通过自定义调度器的方式让用户自己来选择使用哪一种调度策略(需要用户深度参与)扩展接口 - 通过扩展的调度接口将相关的扩展功能整合到当前的调度策略中(每次都要编译执行)新型调度模型Kubernetes 1.18 引入了一个新的调度框架这标志着调度器架构的重大变化。该框架旨在提高调度器的可扩展性和灵活性允许开发者以插件的形式扩展和定制调度行为。插件机制新的调度框架引入了插件机制调度过程被分解成多个可插拔的阶段如过滤、打分、预绑定等用户可以编写自定义插件来扩展或替换调度器的默认行为。调度阶段调度过程被划分为多个阶段包括预过滤Pre-filter、过滤Filter、后过滤Post-filter、打分Score、绑定Bind等。开发者可以针对这些阶段创建自定义插件。新型的调度框架是在传统调度逻辑的基础上进行了整合再拆分。Kubernetes 调度框架主要由以下几个组件组成调度队列Scheduling Queue: 存放待调度的 Pod。调度插件Scheduling Plugins: 在调度过程中用于筛选和评分节点的插件包括过滤插件Filter Plugins和打分插件Scoring Plugins。调度循环Scheduling Cycle: 调度器的运行循环它从队列中取出 Pod 并通过调度插件处理直到找到合适的节点。预选Predicate: 决定一个节点是否有资格运行 Pod 的初步检查包括节点资源、Pod 亲和性/反亲和性、节点选择器、污点和容忍度等。用于过滤掉不符合要求的节点优选Priority: 在通过预选的节点中进一步选择最佳节点的过程通常使用加权评分进行优先级排序。调度器的主要步骤包括1.预过滤Pre-filtering在过滤前进行一些初始化工作例如计算Pod资源需求的总和, 检查 Pod 是否具备必要的资源请求。2. 过滤Filtering计算节点剩余资源是否满足Pod需求过滤掉不满足 Pod 调度要求的节点例如资源不足的节点或存在污点但没有相应容忍的节点。3. 打分Scoring依据用户配置的资源分配策略(LeastAllocated,MostAllocated,RequestedCapacityRatio请求资源/可用资源的百分比)给节点打分选择得分最高的节点作为调度目标。打分规则可以基于多种因素如节点剩余资源、Pod 亲和性等。4. 预绑定Pre-binding在最终确定调度目标之前进行一些检查如绑定验证或准备工作。5. 绑定Binding将 Pod 绑定到选定的节点。基本流程和传统模型还是一样的队列-预选-评分-绑定将这个基本流程划分为了三个部分任务队列 - 接收所有待分配的任务任务本身会根据优先级合理调整队列的顺序。调度循环 - 通过扩展接口的方式整合大量的预选机制和评分(优选)机制同时为了方便扩展预留了备用接口实现预选和优选功能绑定循环 - 先通过等待线程后的预绑定PreBind队列此队列可以防止突发的高优先级任务出现然后再进行正常的节点任务绑定多调度器如果默认的调度器不满足要求还可以部署自定义的调度器。并且在整个集群中还可以同时运行多个调度器实例通过 pod.Spec.schedulerName 来选择使用哪一个调度器(默认使用内置的调度器)。https://github.com/kubernetes-sigs/descheduler范例: 默认调度器kubectl get pod myapp-5bf7bf57cd-ffntl -o yaml|grepschedulerNameschedulerName: default-scheduler新型 vs 传统调度所有的传统预选函数和优选函数都变成了扩展插件的方式实现了动态的灵活绑定一切皆代码所有的配置都可以通过代码的方式来进行实时调整避免传统的再编译或用户强干预调度功能调度函数解析无论是传统的调度功能还是新型的调度功能都是基于各种调度的功能函数实现默认情况下开启了一部分通用参数解析参考资料#预选函数https://github.com/kubernetes/kubernetes/blob/release1.17/pkg/scheduler/algorithm/predicates/predicates.gohttps://github.com/kubernetes/kubernetes/tree/master/pkg/scheduler/algorithm/predicates#优选函数:https://github.com/kubernetes/kubernetes/blob/release1.17/pkg/scheduler/algorithm/priorities/priorities.gohttps://github.com/kubernetes/kubernetes/tree/master/pkg/scheduler/algorithm/priorities常见的预选函数和优选函数下图中绿色部分为默认的插件蓝色部分为可选的插件image预选算法经典调度器的预选算法分类存储约束条件名称中带有Disk或Volume的算法Pod间的特殊关系限制MatchInterPodAffinityPod同Node的限制约束名称中带有Node的算法General PredicatesPod的散置性要求CheckServiceAffinityEvenPodsSpread调度策略调度策略有一些基于资源限制实现,有一些是基于关系实现调度调度策略 解析节点调度 为即将执行的任务选择合理的节点Pod调度 为即将执行的任务分配合理的逻辑关联搭配污点调度 避免调度到某些节点拓扑调度 在任务已确定调度的前提下合理的分配任务实现资源的高效利用调度分类名称 解析亲和与反亲和 满足条件后就分配或者远离指定的节点。硬亲和与软亲和 不会遵循绝对的条件阈值而是根据实际情况做出倾向性策略硬亲和会考量预选和优选策略而软亲和仅考虑优选策略imagePod 调度实现节点调度节点调度说明https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/节点调度即将Pod调度到哪个节点Pod 资源对于节点的调度方式pod.spec.nodeName直接指定目标节点pod.spec.nodeSelector map[string]string直接指定节点挑选条件使用节点选择器过滤节点标签直接将应用部署到指定的节点如果有多个条件节点必须同时符合才会调度即并且的关系pods.spec.affinity亲缘性判定节点亲和 - 根据任务的配置倾向选择合适的节点来进行资源的配置注意调度策略仅在调度时候有用一旦调度成功后后续如果节点状态即使无法满足调度要求也不会影响正常运行的podnodeName 和 nodeSelectorhttps://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes/nodeName和nodeSelector 将 Pod 分配给指定节点nodeName 直接指定节点的名称nodeName 可以忽略节点的污点如果指定的节点异常会导致Pod 处于Pending状态kubectl explain deploy.spec.template.spec.nodeNamekubectl explain pod.spec.nodeNamekubectl explain deployment.spec.template.spec.nodeNamenodeSelector 将Pod调度到有指定label的节点如果没有指定label的节点将无法调度Pod 处于Pending状态nodeSelector 如果指定多个label节点必须同时拥有多个label才会调度nodeSelector 不能忽略节点的污点如果指定标签的节点异常会导致Pod 处于Pending状态注意: nodeSelector 方式如果已经将Pod调度至某个节点, 即使后续再将此节点的label删除,也不会移除上面的Pod,即只在调度时有效,调度后将不再关注kubectl explain pod.spec.nodeSelector#kubectl explain deployment.spec.template.spec.nodeSelector