调度器配置

特性状态: Kubernetes v1.25 [稳定]

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

调度配置文件允许您在 kube-scheduler(调度器) 中配置不同的调度阶段。每个阶段都暴露在一个扩展点中。插件通过实现一个或多个扩展点来提供调度行为。

您可以通过运行 kube-scheduler --config <filename>,使用 KubeSchedulerConfiguration v1 结构体来指定调度配置文件。

一个最小的配置如下所示

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

配置文件

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

您可以将 kube-scheduler 的单个实例配置为运行多个配置文件

扩展点

调度发生在一系列阶段中,这些阶段通过以下扩展点暴露出来

  1. queueSort:这些插件提供一个排序函数,用于对调度队列中的待处理 Pod 进行排序。一次只能启用一个队列排序插件。
  2. preFilter:这些插件用于在过滤之前预处理或检查 Pod 或集群的相关信息。它们可以将 Pod 标记为不可调度。
  3. filter:这些插件等效于调度策略中的谓词,用于过滤掉无法运行 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 插件按顺序调用,一旦一个插件完成绑定,其余插件将被跳过。至少需要一个绑定插件。
  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

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

调度插件

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

  • 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 卷限制。扩展点: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 在内部启用。但是,各个扩展点仍然可用,以便灵活地重新配置默认值(例如排序和 Score 权重)。例如,考虑两个 Score 插件 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
QueueSortScoreFilter
DefaultPlugin2Score
CustomPlugin1ScoreFilter
Score, Filter, BindScoreFilter

CustomPlugin2

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'

Score, PreFilter

这些插件的有效示例配置如下

  • 请注意,在特定扩展点中重新声明 MultiPoint 插件不会出错。重新声明将被忽略(并记录),因为特定扩展点优先。
  • 除了将大多数配置保存在一个位置之外,此示例还执行以下操作
  • 启用自定义 queueSort 插件并禁用默认插件
  • 启用 CustomPlugin1CustomPlugin2,它们将在所有扩展点上首先运行

禁用 DefaultPlugin1,但仅针对 filter

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

重新排序 DefaultPlugin2 以在 score 中首先运行(甚至在自定义插件之前)

v1beta3 之前的配置版本中,如果没有 multiPoint,上述代码段将等同于此

  • v1beta2 → v1beta3

    apiVersion: kubescheduler.config.k8s.io/v1beta2
    kind: KubeSchedulerConfiguration
    profiles:
    - pluginConfig:
      - args:
          scoringStrategy:
            resources:
            - name: cpu
              weight: 1
            type: MostAllocated
        name: NodeResourcesFit
    
  • v1beta3 → v1

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

  • 调度器插件 NodeLabel 已弃用;请改用NodeAffinity 插件(默认启用)来实现类似的行为。

  • 调度器插件 ServiceAffinity 已弃用;请改用 InterPodAffinity 插件(默认启用)来实现类似的行为。

  • 调度器插件 NodePreferAvoidPods 已弃用;请改用 节点污点 来实现类似的行为。

  • 在 v1beta2 配置文件中启用的插件优先于该插件的默认配置。
    • 为调度器 healthz 和指标绑定地址配置的无效 hostport 将导致验证失败。
    • 默认情况下,三个插件的权重会增加
    • InterPodAffinity 从 1 到 2

  • NodeAffinity 从 1 到 2

TaintToleration 从 1 到 3

  • 调度器插件SelectorSpread已被移除,请改用已启用的 PodTopologySpread 插件实现类似行为。
  • 后续步骤
  • 阅读 kube-scheduler 参考