Kubernetes Scheduler 是 Kubernetes 控制平面的核心组件之一,负责将新创建的 Pod 分配到集群中合适的节点上运行。 Scheduler的核心职责包括:
-
过滤:从所有节点中筛选出符合 Pod 要求的候选节点
-
评分:对候选节点进行评分,选择最优节点
-
绑定:将 Pod 与选定的节点绑定
调度流程详解
当一个pod创建时,API Server会将这个pod放入到调度队列中,等待被具体调度部署在某个节点上。具体的调度流程如下:
-
Pod 进入调度队列
-
新创建的 Pod 进入调度器的待调度队列
-
队列按优先级排序
-
-
调度上下文创建
-
为当前 Pod 创建调度上下文
-
-
预选阶段 (Filtering)
-
执行一系列预选策略 (Predicates)
-
排除不满足条件的节点
-
-
优选阶段 (Scoring)
-
对通过预选的节点进行评分
-
选择分数最高的节点
-
-
绑定阶段 (Binding)
-
将 Pod 绑定到选定节点
-
更新 API Server
-
一个pod完整的调度过程被称为一个调度周期 (Scheduling Cycle)
各阶段详细说明
调度队列 (Scheduling Queue)
调度队列的主要功能包括
-
接收来自API Server的新Pod
-
根据优先级对Pod进行排序
-
管理待调度Pod的生命周期
当API Server收到调度请求时,会将待调度的Pod放入ActiveQ队列,使用堆(Heap)数据结构实现优先级排序,默认优先级由Pod的priorityClassName
决定,调度器从ActiveQ头部取出Pod进行处理。如果一个pod调度时,无法满足调度要求,则会将pod暂时放入UnschedulableQ,等待后续处理。
调度上下文创建 (Scheduling Context)
当某个pod被调度器选中,进入调度时,调度器会为当前调度周期创建执行环境,保存调度过程中的状态信息。每个调度周期都有自己的上下文,当调度周期结束时,上下文信息同步销毁。
预选阶段 (Filtering/Predicates)
调度器为pod选择调度节点时,包含两个阶段:预选阶段和优选节点。预选节点会从集群所有节点中筛选出符合Pod要求的候选节点,并排除明显不满足条件的节点,具体流程如下:
节点信息获取
从调度器缓存(Scheduler Cache)获取最新节点信息,检查节点是否Ready,并检查节点资源信息是否最新。
预选策略执行
调度器依次执行以下检查(可通过--policy-config-file
配置):
通用检查:检查节点资源是否足够、检查主机端口是否冲突、检查是否指定了特定节点
卷检查:检查卷区域限制、检查卷绑定状态
亲和性检查:检查节点亲和性规则
污点检查:检查污点和容忍度匹配
候选节点确定
收集通过所有预选检查的节点,并进入优选阶段;如果没有节点通过,Pod将进入UnschedulableQ并记录无法调度的原因。
优选阶段 (Scoring/Priorities)
优选阶段主要对通过预选的节点进行评分,并选择最优节点将pod与节点进行绑定,详细流程如下:
节点评分
调度器执行以下评分策略(可配置,或者自定义开发评分策略):
-
LeastRequestedPriority:
score = (cpu((capacity - requested) * 10 / capacity) + memory((capacity - requested) * 10 / capacity)) / 2
-
BalancedResourceAllocation:
score = 10 - abs(cpuFraction - memoryFraction) * 10
-
NodeAffinityPriority:
-
根据节点亲和性规则计算权重
-
-
TaintTolerationPriority:
-
根据污点容忍度计算权重
-
节点排序
汇总所有评分策略的结果,按总分从高到低排序,选择最高分的节点(分数相同时随机选择),进入绑定阶段。
绑定阶段 (Binding)
将Pod绑定到选定的节点,更新API Server状态,详细流程如下:
绑定决策
检查节点是否仍然可用,验证绑定操作是否允许,准备绑定对象。
API更新
向API Server发送绑定请求,处理绑定结果,更新调度器缓存。