×

您可以在集群中启用 Pod 优先级和预占。Pod 优先级表示 Pod 相对于其他 Pod 的重要性,并根据该优先级对 Pod 进行排队。Pod 预占允许集群驱逐或预占低优先级 Pod,以便在合适的节点上没有可用空间时可以调度高优先级 Pod。Pod 优先级还会影响 Pod 的调度顺序以及节点上的资源不足驱逐顺序。

要使用优先级和预占,请在 Pod 规范中引用优先级类以应用该权重进行调度。

理解 Pod 优先级

使用 Pod 优先级和预占功能时,调度程序会按其优先级对挂起的 Pod 进行排序,并且挂起的 Pod 会在调度队列中排在优先级较低的其他挂起 Pod 之前。因此,如果满足其调度要求,则高优先级 Pod 可能比低优先级 Pod 更早调度。如果无法调度 Pod,调度程序将继续调度其他低优先级 Pod。

Pod 优先级类

您可以为 Pod 分配优先级类,这是一个非命名空间对象,它定义了从名称到优先级整数值的映射。值越高,优先级越高。

优先级类对象可以取任何小于或等于 1000000000(十亿)的 32 位整数值。将大于或等于十亿的数字保留给必须不被预占或驱逐的关键 Pod。默认情况下,Red Hat OpenShift Service on AWS 为关键系统 Pod 保留了两个优先级类,以保证调度。

$ oc get priorityclasses
示例输出
NAME                      VALUE        GLOBAL-DEFAULT   AGE
system-node-critical      2000001000   false            72m
system-cluster-critical   2000000000   false            72m
openshift-user-critical   1000000000   false            3d13h
cluster-logging           1000000      false            29s
  • system-node-critical - 此优先级类的值为 2000001000,用于所有不应从节点中驱逐的 Pod。具有此优先级类的 Pod 示例包括ovnkube-node 等。许多关键组件默认包含system-node-critical 优先级类,例如

    • master-api

    • master-controller

    • master-etcd

    • ovn-kubernetes

    • sync

  • system-cluster-critical - 此优先级类的值为 2000000000(二十亿),用于对集群重要的 Pod。在某些情况下,可以从节点中驱逐具有此优先级类的 Pod。例如,配置了system-node-critical 优先级类的 Pod 可以优先。但是,此优先级类确实确保了保证调度。可以具有此优先级类的 Pod 示例包括 fluentd、descheduler 等附加组件。许多关键组件默认包含system-cluster-critical 优先级类,例如

    • fluentd

    • metrics-server

    • descheduler

  • openshift-user-critical - 您可以将priorityClassName 字段与无法绑定其资源消耗且资源消耗行为不可预测的重要 Pod 一起使用。openshift-monitoringopenshift-user-workload-monitoring 命名空间下的 Prometheus Pod 使用openshift-user-critical priorityClassName。监控工作负载使用system-critical 作为其第一个priorityClass,但这会在监控使用过多的内存且节点无法驱逐它们时导致问题。因此,监控会降低优先级以提高调度程序的灵活性,从而在各个工作负载之间进行迁移,以保持关键节点的运行。

  • cluster-logging - Fluentd 使用此优先级来确保 Fluentd Pod 比其他应用程序优先调度到节点上。

Pod 优先级名称

拥有一个或多个优先级类后,您可以创建在Pod规范中指定优先级类名称的 Pod。优先级准入控制器使用优先级类名称字段填充优先级的整数值。如果找不到指定的优先级类,则会拒绝该 Pod。

理解 Pod 预占

当开发人员创建 Pod 时,Pod 会进入队列。如果开发人员为 Pod 配置了 Pod 优先级或预占,则调度程序会从队列中选择一个 Pod 并尝试将 Pod 调度到节点上。如果调度程序无法在满足 Pod 所有指定要求的适当节点上找到空间,则会针对挂起的 Pod 触发预占逻辑。

当调度程序预占节点上的一个或多个 Pod 时,高优先级Pod规范的nominatedNodeName字段将设置为节点的名称,以及nodename字段。调度程序使用nominatedNodeName字段来跟踪为 Pod 保留的资源,并向用户提供有关集群中预占的信息。

调度程序预占低优先级 Pod 后,调度程序会遵守 Pod 的优雅终止期限。如果在调度程序等待低优先级 Pod 终止时出现其他可用节点,则调度程序可以在该节点上调度高优先级 Pod。因此,Pod规范的nominatedNodeName字段和nodeName字段可能不同。

此外,如果调度器抢占节点上的 Pod 并等待其终止,而一个优先级高于待定 Pod 的 Pod 需要调度,则调度器可以改而调度该高优先级 Pod。在这种情况下,调度器会清除待定 Pod 的nominatedNodeName,使其能够在另一个节点上调度。

抢占并不一定会从节点中移除所有低优先级 Pod。调度器可以通过移除部分低优先级 Pod 来调度待定 Pod。

只有在待定 Pod 能够在节点上调度的情况下,调度器才会考虑该节点进行 Pod 抢占。

非抢占优先级类

将抢占策略设置为Never的 Pod 会排在低优先级 Pod 的前面进入调度队列,但它们不能抢占其他 Pod。等待调度的非抢占 Pod 会一直留在调度队列中,直到有足够的资源可用并可以调度它。非抢占 Pod 与其他 Pod 一样,也受调度器回退的影响。这意味着如果调度器尝试调度这些 Pod 不成功,则会降低重试频率,允许其他低优先级 Pod 先被调度。

非抢占 Pod 仍然可能被其他高优先级 Pod 抢占。

Pod 抢占和其他调度器设置

如果启用 Pod 优先级和抢占,请考虑您的其他调度器设置。

Pod 优先级和 Pod 扰动预算

Pod 扰动预算指定了必须同时保持运行的副本的最小数量或百分比。如果您指定了 Pod 扰动预算,则 AWS 上的 Red Hat OpenShift 服务会在抢占 Pod 时尽力遵守它们。调度器尝试在不违反 Pod 扰动预算的情况下抢占 Pod。如果找不到这样的 Pod,则即使考虑了它们的 Pod 扰动预算要求,也可能会抢占低优先级 Pod。

Pod 优先级和 Pod 亲和性

Pod 亲和性要求将新的 Pod 调度到与具有相同标签的其他 Pod 相同的节点上。

如果待定 Pod 与节点上一个或多个低优先级 Pod 存在 Pod 间亲和性,则调度器在不违反亲和性要求的情况下无法抢占低优先级 Pod。在这种情况下,调度器会寻找另一个节点来调度待定 Pod。但是,调度器无法保证能够找到合适的节点,并且待定 Pod 可能无法被调度。

为避免这种情况,请仔细配置具有相同优先级的 Pod 的 Pod 亲和性。

被抢占 Pod 的优雅终止

抢占 Pod 时,调度器会等待 Pod 的优雅终止时间到期,允许 Pod 完成工作并退出。如果 Pod 在该时间段后未退出,调度器将终止该 Pod。此优雅终止时间段会在调度器抢占 Pod 的时间点和待定 Pod 可以在节点上调度的之间产生时间差。

为了最小化这个时间差,请为低优先级 Pod 配置较短的优雅终止时间。

配置优先级和抢占

您可以通过创建优先级类对象并在 Pod 规范中使用priorityClassName将 Pod 与优先级关联来应用 Pod 优先级和抢占。

您不能直接将优先级类添加到已调度的 Pod。

步骤

要将集群配置为使用优先级和抢占

  1. 通过创建一个类似于以下内容的 YAML 文件来定义包含优先级类名称的 Pod 规范

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      priorityClassName: system-cluster-critical (1)
    1 指定要与此 Pod 一起使用的优先级类。
  2. 创建 Pod

    $ oc create -f <file-name>.yaml

    您可以直接将优先级名称添加到 Pod 配置或 Pod 模板中。