2. Kubernetes 调度基础回顾:调度器架构、调度队列、预选与优选策略、节点亲和性
Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 绑定到合适 Node 的核心组件。理解其内部架构与调度流程,是后续进行调度优化、网络拓扑感知及流量追踪的前提。本节将系统回顾调度器的三大核心模块:调度器架构、调度队列与调度策略,并重点解析节点亲和性在实际生产中的使用模式。
2.1 调度器整体架构
kube-scheduler 采用“事件驱动 + 异步循环”的设计,主要包含以下核心组件:
| 组件 | 职责 | 关键说明 |
|---|---|---|
| 调度队列 | 管理待调度的 Pod,支持优先级排序与重试 | 分为 activeQ、backoffQ、unschedulableQ |
| 调度框架(Scheduling Framework) | 定义调度周期与绑定周期的扩展点 | 插件化架构,支持自定义调度插件 |
| 预选(Filter) | 过滤不满足条件的 Node | 硬约束,如资源不足、端口冲突、污点容忍 |
| 优选(Score) | 对通过预选的 Node 打分排序 | 软约束,如资源均衡、亲和性权重 |
| 绑定(Bind) | 将 Pod 与最优 Node 的绑定关系写入 API Server | 默认通过 Lease 对象实现乐观锁 |
架构要点: 调度器本身不直接管理 Pod 生命周期,而是通过 watch API Server 中的 Pod 与 Node 变化来驱动调度循环。调度框架的插件化设计使得我们可以注入网络拓扑感知、流量采样等自定义逻辑。
2.2 调度队列:三级队列模型
调度队列是调度器的“待办事项列表”,采用三级队列模型来管理 Pod 的调度状态:
- activeQ(活跃队列):存放所有等待调度的 Pod,按优先级排序。调度器每次从中取出一个 Pod 进行调度。
- backoffQ(退避队列):存放调度失败但可以重试的 Pod。每次重试间隔指数退避(base=1s,max=120s)。
- unschedulableQ(不可调度队列):存放因资源不足、污点不匹配等原因无法调度的 Pod。当集群资源发生变化(如新 Node 加入)时,会重新移回 activeQ。
生产建议: 当 Pod 长时间处于 Pending 状态时,优先检查 unschedulableQ 中的 Pod 数量。如果该队列持续堆积,说明集群资源严重不足或调度策略配置不当。在后续的 TC 追踪中,我们会通过调度器指标
scheduler_queue_incoming_pods_total 来监控队列积压情况。
2.3 预选与优选策略
调度策略分为两个阶段:预选(Filter)和优选(Score)。预选是硬约束,优选是软约束。
2.3.1 预选策略(硬约束)
预选阶段会检查每个 Node 是否满足 Pod 的基本运行条件。常见的预选插件包括:
| 插件名称 | 检查内容 | 典型场景 |
|---|---|---|
| NodeResourcesFit | CPU、内存、GPU 等资源是否充足 | Pod 请求资源超过 Node 可分配量 |
| NodePorts | Pod 申请的 hostPort 是否已被占用 | DaemonSet 使用固定端口 |
| NodeAffinity | 检查 Node 标签是否满足 Pod 的 nodeSelector 或 required 规则 | 将 Pod 调度到特定地域的 Node |
| TaintToleration | 检查 Pod 是否容忍 Node 上的污点 | 隔离 GPU 节点或专用节点池 |
| InterPodAffinity | 检查 Pod 间的亲和/反亲和规则 | 将同服务的 Pod 调度到同一拓扑域 |
2.3.2 优选策略(软约束)
优选阶段对通过预选的 Node 进行打分(0-100),最终选择得分最高的 Node。常见优选插件:
| 插件名称 | 打分依据 | 权重 |
|---|---|---|
| NodeResourcesBalancedAllocation | CPU 与内存使用率的均衡程度 | 1 |
| NodeResourcesLeastAllocated | 剩余资源越多得分越高 | 1 |
| NodeAffinity | 满足 preferred 规则的 Node 加分 | 可配置(默认 100) |
| InterPodAffinity | 满足 Pod 间亲和规则的 Node 加分 | 可配置(默认 100) |
| ImageLocality | Node 上已存在所需镜像的加分 | 1 |
性能注意: 在大型集群(1000+ Node)中,预选阶段会遍历所有 Node。如果预选插件过多或逻辑复杂,会显著增加调度延迟。建议在生产环境中通过
--perf-scheduler 指标监控每个插件的执行耗时,优先优化耗时最高的插件。
2.4 节点亲和性(Node Affinity)
节点亲和性是调度策略中最常用的功能之一,允许用户通过 Node 标签来约束 Pod 的调度目标。它分为两种类型:
- requiredDuringSchedulingIgnoredDuringExecution:硬约束,调度时必须满足,类似
nodeSelector的增强版。 - preferredDuringSchedulingIgnoredDuringExecution:软约束,调度时尽量满足,但不强制。
节点亲和性支持丰富的匹配表达式:
| 操作符 | 含义 | 示例 |
|---|---|---|
| In | 标签值在指定集合中 | topology.kubernetes.io/zone In [us-east-1a, us-east-1b] |
| NotIn | 标签值不在指定集合中 | node-type NotIn [spot] |
| Exists | 标签存在(不关心值) | gpu-node Exists |
| DoesNotExist | 标签不存在 | dedicated DoesNotExist |
| Gt / Lt | 标签值大于/小于指定数值 | memory-rank Gt 3 |
2.5 节点亲和性实战配置示例
以下是一个完整的 Pod 配置,同时使用了 required 和 preferred 节点亲和性:
apiVersion: v1
kind: Pod
metadata:
name: affinity-demo
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east-1a
- us-east-1b
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: gpu-node
operator: Exists
containers:
- name: nginx
image: nginx:1.25
关键解读:
- required 规则:Pod 只能调度到
zone=us-east-1a或zone=us-east-1b的 Node 上,其他 Zone 的 Node 在预选阶段直接被过滤。 - preferred 规则:在满足 required 的 Node 中,如果 Node 带有
gpu-node标签,则在优选阶段获得 100 分的额外加分。 - 权重(weight):取值范围 1-100,权重越高,对最终得分的影响越大。
2.6 调度策略与网络拓扑的关联
在后续的 TC 追踪与样本抽检课程中,调度策略将直接影响网络拓扑的分布:
- 节点亲和性:决定了 Pod 分布在哪些 Zone 或 Region,进而影响跨区域网络延迟和流量路径。
- Pod 间亲和性:将同服务的 Pod 调度到同一拓扑域,减少东西向流量跨节点转发。
- 污点与容忍:用于隔离网络密集型 Pod 到专用节点池,避免干扰其他业务。
课程衔接: 第 4 章将介绍如何通过
tc (traffic control) 在调度后的节点上模拟网络延迟与丢包,从而验证调度策略对网络拓扑的实际影响。第 6 章则会讲解如何通过调度器日志和指标进行样本抽检,定位调度异常。