$ oc get priorityclasses
您可以在集群中启用Pod优先级和抢占。Pod优先级指示Pod相对于其他Pod的重要性,并根据该优先级对Pod进行排队。Pod抢占允许集群驱逐或抢占低优先级Pod,以便在合适的节点上没有可用空间时可以调度高优先级Pod。Pod优先级还会影响Pod的调度顺序以及节点上资源不足时的驱逐顺序。
要使用优先级和抢占,您可以创建定义Pod相对权重的优先级类。然后,在Pod规范中引用优先级类以应用该权重进行调度。
使用Pod优先级和抢占功能时,调度器会按其优先级对挂起的Pod进行排序,并且挂起的Pod会在调度队列中排在优先级较低的其他挂起Pod之前。因此,如果满足高优先级Pod的调度要求,它可能会比低优先级Pod更早被调度。如果无法调度Pod,调度器将继续调度其他低优先级Pod。
您可以为Pod分配优先级类,这是一个非命名空间对象,它定义了从名称到优先级整数值的映射。值越高,优先级越高。
优先级类对象可以采用任何小于或等于1000000000(十亿)的32位整数值。保留大于或等于十亿的数字,用于必须不被抢占或驱逐的关键Pod。默认情况下,OpenShift Container Platform 为关键系统 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-monitoring
和openshift-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
规范的nominatedNodeName
字段将设置为节点的名称,以及nodename
字段。调度器使用nominatedNodeName
字段来跟踪为Pod保留的资源,并向用户提供有关集群中抢占的信息。
调度器抢占低优先级Pod后,调度器会遵守Pod的优雅终止时间段。如果在调度器等待低优先级Pod终止时另一个节点可用,则调度器可以在该节点上调度高优先级Pod。因此,Pod
规范的nominatedNodeName
字段和nodeName
字段可能不同。
此外,如果调度器抢占节点上的Pod并正在等待终止,并且需要调度比挂起Pod优先级更高的Pod,则调度器可以调度高优先级Pod。在这种情况下,调度器会清除挂起Pod的nominatedNodeName
,使该Pod有资格在另一个节点上调度。
抢占并不一定会从节点中删除所有低优先级Pod。调度器可以通过删除部分低优先级Pod来调度挂起的Pod。
只有当挂起的Pod可以在节点上调度时,调度器才会考虑将该节点用于Pod抢占。
将抢占策略设置为Never
的Pod会排在低优先级Pod之前的调度队列中,但它们不能抢占其他Pod。等待调度的非抢占式Pod会一直停留在调度队列中,直到有足够的资源可用并可以调度它。非抢占式Pod与其他Pod一样,会受到调度器回退的影响。这意味着如果调度器尝试调度这些Pod失败,则会以较低的频率重试,从而允许其他低优先级Pod先被调度。
非抢占式 Pod 仍然可能被其他高优先级 Pod 抢占。
如果启用 Pod 优先级和抢占,请考虑您的其他调度器设置。
Pod disruption budget 指定了必须同时运行的副本的最小数量或百分比。如果您指定了 Pod disruption budget,OpenShift Container Platform 会尽力遵守它们来抢占 Pod。调度器会尝试在不违反 Pod disruption budget 的情况下抢占 Pod。如果没有找到这样的 Pod,即使有 Pod disruption budget 要求,也可能会抢占低优先级的 Pod。
Pod 亲和性要求新 Pod 调度到与具有相同标签的其他 Pod 相同的节点上。
如果待处理的 Pod 与节点上一个或多个低优先级 Pod 具有 Pod 间亲和性,则调度器无法在不违反亲和性要求的情况下抢占低优先级 Pod。在这种情况下,调度器会寻找另一个节点来调度待处理的 Pod。但是,调度器无法保证能找到合适的节点,并且待处理的 Pod 可能无法调度。
为避免这种情况,请仔细配置具有相同优先级的 Pod 的 Pod 亲和性。
您可以通过创建优先级类对象并在 Pod 规范中使用priorityClassName
将 Pod 与优先级关联来应用 Pod 优先级和抢占。
您不能直接将优先级类添加到已调度的 Pod。 |
配置集群以使用优先级和抢占
创建一个或多个优先级类
创建一个类似于以下内容的 YAML 文件
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority (1)
value: 1000000 (2)
preemptionPolicy: PreemptLowerPriority (3)
globalDefault: false (4)
description: "This priority class should be used for XYZ service pods only." (5)
1 | 优先级类对象的名称。 |
2 | 对象的优先级值。 |
3 | 可选。指定此优先级类是抢占式还是非抢占式。抢占策略默认为PreemptLowerPriority ,这允许该优先级类的 Pod 抢占低优先级 Pod。如果抢占策略设置为Never ,则该优先级类中的 Pod 为非抢占式。 |
4 | 可选。指定是否应将此优先级类用于未指定优先级类名称的 Pod。此字段默认为false 。集群中只能存在一个globalDefault 设置为true 的优先级类。如果没有globalDefault:true 的优先级类,则没有优先级类名称的 Pod 的优先级为零。添加globalDefault:true 的优先级类只会影响添加优先级类后创建的 Pod,并且不会更改现有 Pod 的优先级。 |
5 | 可选。描述开发人员应将哪些 Pod 与此优先级类一起使用。输入任意文本字符串。 |
创建优先级类
$ oc create -f <file-name>.yaml
创建 Pod 规范以包含优先级类的名称
创建一个类似于以下内容的 YAML 文件
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
priorityClassName: high-priority (1)
1 | 指定要与此 Pod 一起使用的优先级类。 |
创建 Pod
$ oc create -f <file-name>.yaml
您可以直接将优先级名称添加到 Pod 配置或 Pod 模板中。