调度器配置

功能状态: Kubernetes v1.25 [稳定]

你可以通过编写配置文件并将其路径作为命令行参数传递,来定制 kube-scheduler 的行为。

调度 Profile 允许你配置 kube-scheduler 中调度过程的不同阶段。每个阶段都暴露在一个扩展点中。插件通过实现这些扩展点中的一个或多个来提供调度行为。

你可以通过运行 kube-scheduler --config <filename>,使用 KubeSchedulerConfiguration v1 结构体来指定调度 Profile。

一个最小的配置如下所示

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig

Profiles

调度 Profile 允许你配置 kube-scheduler 中调度过程的不同阶段。每个阶段都暴露在一个 扩展点 中。 插件 通过实现这些扩展点中的一个或多个来提供调度行为。

你可以配置单个 kube-scheduler 实例来运行 多个 Profile

扩展点

调度过程发生在通过以下扩展点暴露的一系列阶段中

  1. queueSort:这些插件提供一个排序函数,用于对调度队列中的待处理 Pod 进行排序。一次只能启用一个队列排序插件。
  2. preFilter:这些插件用于在过滤之前预处理或检查 Pod 或集群的信息。它们可以将 Pod 标记为不可调度。
  3. filter:这些插件等效于调度策略中的 Predicates,用于过滤掉无法运行 Pod 的节点。过滤器按配置的顺序调用。如果所有过滤器都没有通过的节点,则 Pod 会被标记为不可调度。
  4. postFilter:这些插件在未找到 Pod 的可行节点时,按其配置的顺序调用。如果任何 postFilter 插件将 Pod 标记为可调度,则不会调用其余插件。
  5. preScore:这是一个信息性扩展点,可用于执行预评分工作。
  6. score:这些插件为通过过滤阶段的每个节点提供一个分数。然后,调度器将选择加权分数之和最高的节点。
  7. reserve:这是一个信息性扩展点,用于在为给定 Pod 预留资源时通知插件。插件还实现一个 Unreserve 调用,该调用在 Reserve 期间或之后发生故障时被调用。
  8. permit:这些插件可以防止或延迟 Pod 的绑定。
  9. preBind:这些插件执行在 Pod 绑定之前所需的任何工作。
  10. bind:这些插件将 Pod 绑定到节点。bind 插件按顺序调用,并且一旦完成绑定,其余插件将被跳过。至少需要一个 bind 插件。
  11. postBind:这是一个信息性扩展点,在 Pod 绑定后调用。
  12. multiPoint:这是一个仅配置的字段,允许同时为它们适用的所有扩展点启用或禁用插件。

对于每个扩展点,你可以禁用特定的 默认插件 或启用你自己的。例如

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - plugins:
      score:
        disabled:
        - name: PodTopologySpread
        enabled:
        - name: MyCustomPluginA
          weight: 2
        - name: MyCustomPluginB
          weight: 1

你可以使用 * 作为禁用数组中的名称来禁用该扩展点的所有默认插件。如果需要,这也可以用于重新排列插件顺序。

调度插件

以下插件默认启用,实现一个或多个这些扩展点

  • ImageLocality:优先选择已经拥有 Pod 运行的容器镜像的节点。扩展点:score
  • TaintToleration:实现 污点和容忍度。实现扩展点:filterpreScorescore
  • NodeName:检查 Pod 规范节点名称是否与当前节点匹配。扩展点:filter
  • NodePorts:检查节点是否具有请求的 Pod 端口的空闲端口。扩展点:preFilterfilter
  • NodeAffinity:实现 节点选择器节点亲和性。扩展点:filterscore
  • PodTopologySpread:实现 Pod 拓扑传播。扩展点:preFilterfilterpreScorescore
  • NodeUnschedulable:过滤掉 .spec.unschedulable 设置为 true 的节点。扩展点:filter
  • NodeResourcesFit:检查节点是否具有 Pod 请求的所有资源。分数可以使用三种策略之一:LeastAllocated(默认)、MostAllocatedRequestedToCapacityRatio。扩展点:preFilterfilterscore
  • NodeResourcesBalancedAllocation:优先选择如果 Pod 调度到那里,将获得更平衡的资源使用的节点。扩展点:score
  • VolumeBinding:检查节点是否具有请求的 或是否可以绑定请求的卷。扩展点:preFilterfilterreservepreBindscore
  • VolumeRestrictions:检查节点上安装的卷是否满足特定于卷提供商的限制。扩展点:filter
  • VolumeZone:检查请求的卷是否满足它们可能具有的任何区域要求。扩展点:filter
  • NodeVolumeLimits:检查是否可以满足节点的 CSI 卷限制。此插件还可以防止 Pod 放置到节点,如果节点上未安装 CSI 驱动程序,则需要启用 VolumeLimitScaling 特性门控。它还允许集群自动缩放器准确计算调度待处理的 Pod 所需的节点数量,这些 Pod 具有可附加的 CSI 卷。扩展点:filter
  • EBSLimits:检查是否可以满足节点上的 AWS EBS 卷限制。扩展点:filter
  • GCEPDLimits:检查是否可以满足节点上的 GCP-PD 卷限制。扩展点:filter
  • AzureDiskLimits:检查是否可以满足节点上的 Azure 磁盘卷限制。扩展点:filter
  • InterPodAffinity:实现 Pod 间亲和性和反亲和性。扩展点:preFilterfilterpreScorescore
  • PrioritySort: 提供默认的优先级排序。扩展点:queueSort
  • DefaultBinder: 提供默认的绑定机制。扩展点:bind
  • DefaultPreemption: 提供默认的抢占机制。扩展点:postFilter

您还可以通过组件配置 API 启用以下默认未启用的插件

  • CinderLimits: 检查 OpenStack Cinder 卷限制是否能满足节点的需要。扩展点:filter

多个配置

您可以配置 kube-scheduler 运行多个配置。每个配置都有一个关联的调度器名称,并且可以为其配置不同的插件集在其 扩展点 中。

使用以下示例配置,调度器将使用两个配置运行:一个使用默认插件,另一个禁用所有评分插件。

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
  - schedulerName: no-scoring-scheduler
    plugins:
      preScore:
        disabled:
        - name: '*'
      score:
        disabled:
        - name: '*'

希望根据特定配置进行调度的 Pod 可以在其 .spec.schedulerName 中包含相应的调度器名称。

默认情况下,会创建一个配置,其调度器名称为 default-scheduler。此配置包括上述默认插件。声明多个配置时,每个配置都需要一个唯一的调度器名称。

如果 Pod 没有指定调度器名称,kube-apiserver 会将其设置为 default-scheduler。因此,应该存在一个具有此调度器名称的配置才能调度这些 Pod。

适用于多个扩展点的插件

kubescheduler.config.k8s.io/v1beta3 开始,配置文件中有一个额外的字段,multiPoint,它允许轻松地在多个扩展点上启用或禁用插件。multiPoint 配置的意图是简化用户和管理员在使用自定义配置时的配置需求。

考虑一个插件,MyPlugin,它实现了 preScorescorepreFilterfilter 扩展点。要为所有可用扩展点启用 MyPlugin,配置文件的外观如下

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:
      multiPoint:
        enabled:
        - name: MyPlugin

这等同于手动为所有扩展点启用 MyPlugin,如下所示

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: non-multipoint-scheduler
    plugins:
      preScore:
        enabled:
        - name: MyPlugin
      score:
        enabled:
        - name: MyPlugin
      preFilter:
        enabled:
        - name: MyPlugin
      filter:
        enabled:
        - name: MyPlugin

使用 multiPoint 的一个好处是,如果 MyPlugin 在未来实现另一个扩展点,multiPoint 配置将自动为其启用该扩展点。

可以使用该扩展点的 disabled 字段从 MultiPoint 扩展中排除特定的扩展点。这适用于禁用默认插件、非默认插件或使用通配符 ('*') 禁用所有插件。例如,禁用 ScorePreScore 的示例是

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: non-multipoint-scheduler
    plugins:
      multiPoint:
        enabled:
        - name: 'MyPlugin'
      preScore:
        disabled:
        - name: '*'
      score:
        disabled:
        - name: '*'

kubescheduler.config.k8s.io/v1beta3 开始,所有 默认插件 都在内部通过 MultiPoint 启用。但是,仍然可以使用各个扩展点来灵活地重新配置默认值(例如排序和评分权重)。例如,考虑两个评分插件 DefaultScore1DefaultScore2,每个插件的权重为 1。可以使用如下方式重新排序它们,并具有不同的权重

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:
      score:
        enabled:
        - name: 'DefaultScore2'
          weight: 5

在此示例中,无需在 MultiPoint 中显式指定插件,因为它们是默认插件。并且 Score 中指定的唯一插件是 DefaultScore2。这是因为通过特定扩展点设置的插件始终优先于 MultiPoint 插件。因此,此片段基本上是在无需指定两者的情况下重新排序这两个插件。

配置 MultiPoint 插件时的优先级的一般层次结构如下

  1. 特定的扩展点首先运行,并且其设置会覆盖其他地方设置的内容
  2. 通过 MultiPoint 手动配置的插件及其设置
  3. 默认插件及其默认设置

为了演示上述层次结构,以下示例基于这些插件

插件扩展点
DefaultQueueSortQueueSort
CustomQueueSortQueueSort
DefaultPlugin1Score, Filter
DefaultPlugin2Score
CustomPlugin1Score, Filter
CustomPlugin2Score, Filter

这些插件的有效示例配置是

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:
      multiPoint:
        enabled:
        - name: 'CustomQueueSort'
        - name: 'CustomPlugin1'
          weight: 3
        - name: 'CustomPlugin2'
        disabled:
        - name: 'DefaultQueueSort'
      filter:
        disabled:
        - name: 'DefaultPlugin1'
      score:
        enabled:
        - name: 'DefaultPlugin2'

请注意,在特定扩展点中重新声明 MultiPoint 插件不会导致错误。重新声明会被忽略(并记录),因为特定的扩展点优先。

除了将大部分配置放在一个位置之外,此示例还执行以下几项操作

  • 启用自定义 queueSort 插件并禁用默认插件
  • 启用 CustomPlugin1CustomPlugin2,它们将首先为所有扩展点运行
  • 禁用 DefaultPlugin1,但仅针对 filter
  • 重新排序 DefaultPlugin2,使其首先在 score 中运行(甚至在自定义插件之前)

在配置版本早于 v1beta3 的情况下,没有 multiPoint,上述片段等同于此

apiVersion: kubescheduler.config.k8s.io/v1beta2
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: multipoint-scheduler
    plugins:

      # Disable the default QueueSort plugin
      queueSort:
        enabled:
        - name: 'CustomQueueSort'
        disabled:
        - name: 'DefaultQueueSort'

      # Enable custom Filter plugins
      filter:
        enabled:
        - name: 'CustomPlugin1'
        - name: 'CustomPlugin2'
        - name: 'DefaultPlugin2'
        disabled:
        - name: 'DefaultPlugin1'

      # Enable and reorder custom score plugins
      score:
        enabled:
        - name: 'DefaultPlugin2'
          weight: 1
        - name: 'DefaultPlugin1'
          weight: 3

虽然这是一个复杂的示例,但它展示了 MultiPoint 配置的灵活性以及它与配置扩展点的现有方法的无缝集成。

调度器配置迁移

  • 使用 v1beta2 配置版本,可以使用新的评分扩展点来扩展 NodeResourcesFit 插件。新的扩展点结合了 NodeResourcesLeastAllocatedNodeResourcesMostAllocatedRequestedToCapacityRatio 插件的功能。例如,如果您之前使用过 NodeResourcesMostAllocated 插件,则应改用 NodeResourcesFit(默认启用),并添加一个具有类似于以下内容的 scoreStrategypluginConfig

    apiVersion: kubescheduler.config.k8s.io/v1beta2
    kind: KubeSchedulerConfiguration
    profiles:
    - pluginConfig:
      - args:
          scoringStrategy:
            resources:
            - name: cpu
              weight: 1
            type: MostAllocated
        name: NodeResourcesFit
    
  • 调度器插件 NodeLabel 已弃用;相反,使用 NodeAffinity 插件(默认启用)以实现类似的行为。

  • 调度器插件 ServiceAffinity 已弃用;相反,使用 InterPodAffinity 插件(默认启用)以实现类似的行为。

  • 调度器插件 NodePreferAvoidPods 已弃用;相反,使用 节点污点 以实现类似的行为。

  • 在 v1beta2 配置文件中启用的插件优先于该插件的默认配置。

  • 为调度器 healthz 和指标绑定地址配置的无效 hostport 将导致验证失败。

  • 三个插件的权重默认增加
    • InterPodAffinity 从 1 增加到 2
    • NodeAffinity 从 1 增加到 2
    • TaintToleration 从 1 增加到 3

  • 调度器插件 SelectorSpread 已删除,相反,使用 PodTopologySpread 插件(默认启用)以实现类似的行为。

接下来

最后修改时间为 2025 年 12 月 02 日下午 9:34 PST:添加 KEP-5030 更改的文档 (#52893) (bf510474aa)