调度器配置

特性状态: Kubernetes v1.25 [stable]

你可以通过编写配置文件并将其路径作为命令行参数传递来定制 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

Profile

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

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

扩展点

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

  1. queueSort: 这些插件提供一个排序函数,用于对调度队列中的待处理 Pod 进行排序。一次只能启用一个 queue sort 插件。
  2. preFilter: 这些插件用于在过滤之前预处理或检查关于 Pod 或集群的信息。它们可以将 Pod 标记为不可调度。
  3. filter: 这些插件相当于调度 Policy 中的 Predicate,用于过滤掉无法运行 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

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

调度插件

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

  • ImageLocality: 优先选择已经拥有 Pod 运行所需容器镜像的节点。扩展点:score
  • TaintToleration: 实现了污点和容忍度。实现的扩展点:filter, preScore, score
  • NodeName: 检查 Pod spec 中的节点名称是否与当前节点匹配。扩展点:filter
  • NodePorts: 检查节点是否有请求的 Pod 端口的空闲端口。扩展点:preFilter, filter
  • NodeAffinity: 实现了节点选择器节点亲和性。扩展点:filter, score
  • PodTopologySpread: 实现了Pod 拓扑分布。扩展点:preFilter, filter, preScore, score
  • NodeUnschedulable: 过滤掉 .spec.unschedulable 设置为 true 的节点。扩展点:filter
  • NodeResourcesFit: 检查节点是否具有 Pod 请求的所有资源。评分可以使用以下三种策略之一:LeastAllocated(默认)、MostAllocatedRequestedToCapacityRatio。扩展点:preFilter, filter, score
  • NodeResourcesBalancedAllocation: 优先选择如果 Pod 调度到该节点会获得更均衡资源使用率的节点。扩展点:score
  • VolumeBinding: 检查节点是否拥有或能否绑定请求的。扩展点:preFilter, filter, reserve, preBind, score
  • VolumeRestrictions: 检查挂载在节点上的卷是否满足特定于卷提供者的限制。扩展点:filter
  • VolumeZone: 检查请求的卷是否满足可能有的任何区域要求。扩展点:filter
  • NodeVolumeLimits: 检查 CSI 卷限制是否能够满足节点的需求。扩展点:filter
  • EBSLimits: 检查 AWS EBS 卷限制是否能够满足节点的需求。扩展点:filter
  • GCEPDLimits: 检查 GCP-PD 卷限制是否能够满足节点的需求。扩展点:filter
  • AzureDiskLimits: 检查 Azure 磁盘卷限制是否能够满足节点的需求。扩展点:filter
  • InterPodAffinity: 实现了Pod 间亲和性与反亲和性。扩展点:preFilter, filter, preScore, score
  • PrioritySort: 提供了默认的基于优先级的排序。扩展点:queueSort
  • DefaultBinder: 提供了默认的绑定机制。扩展点:bind
  • DefaultPreemption: 提供了默认的抢占机制。扩展点:postFilter

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

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

多 Profile

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

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

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

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

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

如果 Pod 没有指定调度器名称,kube-apiserver 将其设置为 default-scheduler。因此,应该存在一个使用此调度器名称的 Profile,以便调度这些 Pod。

应用于多个扩展点的插件

kubescheduler.config.k8s.io/v1beta3 开始,Profile 配置中新增了一个字段 multiPoint,该字段允许在多个扩展点上轻松启用或禁用插件。multiPoint 配置的目的是简化用户和管理员使用自定义 Profile 时所需的配置。

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

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 和 metrics 绑定地址配置的无效 hostport 将导致验证失败。

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

  • 调度器插件 SelectorSpread 已移除,请改用 PodTopologySpread 插件(默认启用)来实现类似的行为。

下一步

上次修改时间:2024 年 10 月 16 日上午 10:55 PST:Add StorageCapacityScoring feature gate documents (9ef3b68238)