在K8S中,Scheduler 作用及实现原理有哪些?
在 Kubernetes 中,Scheduler(调度器) 是集群的「智能调度大脑」,负责将新创建的 Pod 分配到最优的 Node 上运行。其核心目标是:在满足资源需求和策略约束的前提下,最大化集群资源的利用率与业务稳定性。以下是其作用与实现原理的深度解析:
一、Scheduler 的核心作用
1. 资源供需匹配
- 解决:Pod 的资源请求(CPU/Memory/GPU)与 Node 的可用资源匹配。
- 示例:避免将 8GB 内存需求的 Pod 分配到只剩 4GB 内存的 Node。
2. 策略约束实施
- 关键策略:
- 节点亲和性(
nodeAffinity
):优先选择高配置 SSD 节点。 - Pod 亲和/反亲和(
podAffinity/podAntiAffinity
):- 亲和:将同一服务的多个 Pod 部署到同一区域(减少延迟)。
- 反亲和:避免同一服务的 Pod 全部署在同一节点(防单点故障)。
- 污点与容忍(
Taint/Toleration
):- 污点节点(如
dedicated=gpu:NoSchedule
)只允许声明容忍的 Pod 调度。
- 污点节点(如
- 节点亲和性(
3. 拓扑感知调度
- 优化:将 Pod 分散到不同故障域(如机架、可用区),提升容灾能力。
- 实现:通过
topologySpreadConstraints
控制 Pod 在区域/节点的分布密度。
4. 资源碎片整理
- 场景:避免小资源请求 Pod 散布导致大资源请求 Pod 无法分配。
- 机制:通过
RequestedToCapacityRatio
策略优先选择资源碎片少的节点。
二、Scheduler 工作流程(四阶段调度)
graph LR
A[新 Pod 创建] --> B(调度队列)
B --> C{调度周期开始}
C --> D[预选阶段<br>Filter]
D --> E[优选阶段<br>Scoring]
E --> F[绑定阶段<br>Bind]
F --> G[节点执行]
阶段 1:预选(Filter)—— 海选节点
- 目标:淘汰不满足硬性条件的节点(如资源不足、策略冲突)。
- 关键过滤器:
NodeResourcesFit
:检查 CPU/Memory/GPU 是否足够。NodeAffinity
:检查节点亲和性规则。PodTopologySpread
:检查拓扑分布约束。TaintToleration
:检查污点容忍。
- 结果:生成候选节点列表(如从 100 个节点筛选出 10 个)。
阶段 2:优选(Scoring)—— 节点打分
- 目标:对候选节点评分,选择最优节点。
- 核心评分策略:
LeastAllocated
:优先选择资源利用率低的节点(平衡负载)。BalancedAllocation
:优先选择 CPU/Memory 使用比例均衡的节点(防单资源瓶颈)。InterPodAffinity
:根据 Pod 亲和性规则加分。ImageLocality
:优先选择已缓存 Pod 所需镜像的节点(加速启动)。
- 评分公式:
\text{Node Score} = \sum (\text{评分插件权重} \times \text{插件分数})
- 结果:得分最高的节点胜出(如 Node A:82分 > Node B:76分)。
阶段 3:预留(Reserve)—— 资源预占
- 将 Pod 资源需求“预占”到目标节点,防止其他 Scheduler 进程争抢。
- 若后续阶段失败(如绑定网络失败),释放预留资源。
阶段 4:绑定(Bind)—— 提交分配结果
- 向 API Server 发送
Binding
对象,将 Pod 与 Node 绑定。 - 目标节点上的
kubelet
检测到绑定事件后,启动容器。
三、Scheduler 高级特性
1. 调度框架(Scheduling Framework)
- 可扩展性:允许开发者注入自定义逻辑(如企业级调度策略)。
- 扩展点示例:
PreFilter
:预处理 Pod 信息。PostBind
:绑定成功后触发通知(如发送审计日志)。
2. 动态资源感知
- 实时监控节点资源变化(如 GPU 卡被释放),重新调度等待中的 Pod。
- 工具:结合
Metrics Server
和Vertical Pod Autoscaler
。
3. 抢占调度(Preemption)
- 场景:高优先级 Pod 因资源不足无法调度时,驱逐低优先级 Pod。
- 策略:
- 选择牺牲品(优先级最低的 Pod)。
- 优雅驱逐(等待 30 秒终止期)。
- 调度高优先级 Pod。
4. 批处理与并发控制
- 批处理调度:一次调度多个 Pod(如 Job 的 100 个任务 Pod)。
- 并发限制:避免大规模集群中调度请求风暴(默认 100 并发)。
四、Scheduler 配置实践
1. 调度策略定制(示例)
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
filter: # 预选插件
enabled:
- name: NodeResourcesFit
- name: NodeAffinity
score: # 优选插件
enabled:
- name: LeastAllocated
weight: 5 # 权重
- name: InterPodAffinity
weight: 3
2. 调度器高可用
- 运行多个 Scheduler 实例(如
my-scheduler-1
、my-scheduler-2
)。 - Pod 通过
.spec.schedulerName
指定调度器。
五、调度失败排查指南
现象 | 常见原因 | 排查命令 |
---|---|---|
Pod 卡在 Pending |
无节点满足资源需求 | kubectl describe pod <pod> |
节点资源充足但调度失败 | 污点未容忍/节点亲和性冲突 | kubectl get node -o yaml |
抢占失败 | 低优先级 Pod 无法被驱逐(如 PDB 限制) | kubectl get pdb |
拓扑分布约束未满足 | 故障域节点不足 | kubectl top node |
六、总结:Scheduler 的核心价值
✅ 资源高效利用:智能匹配供需,减少资源碎片
✅ 业务稳定性保障:通过反亲和/拓扑分布防单点故障
✅ 策略驱动调度:灵活支持亲和性、GPU 调度等复杂场景
✅ 可扩展架构:通过 Scheduling Framework 定制企业级策略
一句话理解调度器:
🧠 它是 Kubernetes 的「资源调配大师」——
- 洞察全局(监控所有节点资源)
- 精打细算(过滤+评分选择最优节点)
- 运筹帷幄(通过策略保障业务 SLA)
确保每个 Pod 在正确的位置高效运行。