Pod优先级

Pod Priority 


 在Kubernetes集群环境中,可以设置Pod的优先级,优先级的高低代表Pod之间的重要性可以相互比较,如果一个Pod无法被调度器调度时,或者集群资源缺乏时,调度器会抢占与之优先级较低的Pod的资源

PriorityClass

在Kubernetes集群平台中,存在二个系统级别的PriorityClass(system-cluster-critical 和 system-node-critical)后者优先级在整个集群中最高级别

PriorityClass不受namespace所管,命名规则不能以system- 为前缀,优先级的值范围(10亿的32位整数)

PriorityClass 还有两个可选字段:globalDefault 和 description。 globalDefault 值为true功能是指当创建的Pod没有指定priorityClassName时会生成一个默认的Priority的值, 系统中只能存在一个 globalDefault 设置为 true 的 PriorityClass。 如果集群不存在globalDefault 的 PriorityClass, 则创建时Pod没有指定priorityClassName则Pod的优先级为0

Priority的注意事项

  1. 新增一个globaldefault设置为true的 PriorityClass 不会改变现有 Pod 的优先级,但是会影响之后合建的Pod优先级

  2. 如果删现有的PriorityClass时,并不影响已经生效的Pod的优先级,只是不能新建而已

  3. 具体参考配置,如下

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: gloabletruepriority
    globalDefault: true
    value: 1
    description: "globaldefaultpriority"

非抢占 PriorityClass

配置了 PreemptionPolicy: Never 的 Pod 不能抢占其他 Pod的资源(虽然会被放在优先等级低的Pod之前),直到Kubernetes集群中有足够的可用资源,调度器才会调度此类Pod。非抢占式 Pod也会受到调度器回退操作,意思就是当调度器无法调度时,会以更低的频率重复调度,取而代之的是比之优先等级低的Pod排在非抢占式前面

PreemptionPolicy 默认为 PreemptLowerPriority, 允许PriorityClass 的 Pod 可以抢占较低优先级的 Pod;但如果 PreemptionPolicy 设置为 Never,则该 PriorityClass 中的 Pod 将是非抢占式的

  • 参考示例
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: high-priority-nonpreempting
    value: 1000000
    preemptionPolicy: Never
    globalDefault: false
    description: "This priority class will not cause other pods to be preempted."

 Pod优先级配置

  • 参考配置
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      priorityClassName: high-priority
  • Pod的优先对调度器的影响

当Pod启用优先级时,Kubernetes针对pending Pod进行排序,按优先级进行排序高在前低在后分级进行调度,如果高级别的优先级高度失败或由于其它原因无法调度时,则调度器依次执行调度队列中优先级别低的Pod

抢占


Pod创建后被列入到调度队列中,调度器从队列中应该依照优先级进行排序首先选择一个等级高的Pod进行调度到Kubernetes节点上,由于客观原因比如资源缺乏等,则触发 pending Pod 的抢占逻辑,调度器会删除一个或者多个低于pending Pod优先级的Pod并等待删除完成后,将其pending Pod调度到该节点上

抢占限制

  • 被抢占的Pod优雅停止

当 Pod 被抢占时,Kubernetes会给予一个优雅停机宽限时间(terminationGracePeriodSeconds),如果没有宽限期那么直接kill掉

  • 支持PDB,但不保证

PodDisruptionBudget (PDB) Kubernetes 在抢占 Pod 时支持 PDB,但对 PDB 的支持是基于尽力而为原则,调度器在Kubernetes集群尝删除优先等级低的Pod,如果并没有找到相关的Pod,则即使违反了 PDB 约束条件也会删除优先级较低的 Pod

  • 与低优先级Pod之间的亲和性

如果从此节点上删除优先级低于pending Pod 的所有 Pod,pending Pod 是否可以在该节点上调度?答案是肯定的,如果不调度则就不会执行抢占

抢占并不一定会删除所有较低优先级的 Pod,清除pending Pod需要的资源即可,不需要清除所有低于pending Pod的优先级的Pod

如果pending Pod 与节点上的一个或多个较低优先级 Pod 具有 Pod 间亲和性, 但是在Kubernetes集群其它节点不满足低优先级Pod亲和性约束, 在这种情况下,调度器不会抢占节点上的任何 Pod;相反调度器可能会找到其它合适的节点, 也可能不会,无法保证pending Pod 可以被调度

  • 跨节点抢占
  1. pending Pod执行调度至节点1

  2. Pod A 运行位于node1同区域的另一个节点2上

  3. pending Pod与Pod A 具有 Zone 维度的反亲和(topologyKey:topology.kubernetes.io/zone)

  4. pending Pod 与同zone中的其它Pod之间没有反亲和性设置

  5. 为了在节点1上调度 Pod P,可以抢占 PodA,但调度器不会进行跨节点抢占。 因此,pending Pod 将被视为在节点 1 上不可调度

常见故障


  • Pod被抢占,但是没有被调度

在pending Pod等待被删除Pod后,恰好在这个时间节点出现一个更高优先级的 Pod 调度,在这种情况下,调度器将调度优先级更高的 Pod 而不是pending Pod

  • 优先级高的Pod被优先级低的Pod前抢占

当有多个节点提供执行抢占,调度器会尝试选择具有一组优先级最低的 Pod 的节点,但是如果此类 Pod 具有 PodDisruptionBudget,当它们被抢占时, 则会违反 PodDisruptionBudget,那么调度器可能会选择另一个具有更高优先级 Pod 的节点

Pod优先级与Qos的关系


Pod 优先级和 QoS 是两个正交(垂直)特征,交互很少,并且对基于 QoS 设置 Pod 的优先级没有默认限制。 调度器的抢占逻辑在选择抢占目标时不考虑 QoS。 抢占会考虑 Pod 优先级并尝试选择一组优先级最低的目标。 仅当移除优先级最低的 Pod 不足以让调度器调度抢占式 Pod, 或者最低优先级的 Pod 受 PodDisruptionBudget 保护时,才会考虑优先级较高的 Pod

kubelet 使用优先级来确定节点压力驱逐 Pod 的顺序。 你可以使用 QoS评估Pod 最有可能被驱逐的顺序,kubelet 根据以下因素对 Pod 进行驱逐排名

  1. 对紧缺资源的使用是否超过requests

  2. Pod 优先级

  3. 相对于请求的资源使用量

当某 Pod 的资源用量未超过其请求时,kubelet 节点压力驱逐不会驱逐该 Pod。 如果优先级较低的 Pod 没有超过其请求,则不会被驱逐。 另一个优先级高于其请求的 Pod 可能会被驱逐

因此具体的驱逐顺序,如下

  1. 首先考虑 BestEffort 或 Burstable Pod资源使用量超过requests的值, 这些 Pod 会根据它们的优先级以及它们的资源使用级别超过其请求的程度被逐出

  2. 资源使用量少于请求量的 Guaranteed Pod 和 Burstable Pod 根据其优先级被最后驱逐

kubelet 不使用 Pod 的 QoS 来确定驱逐顺序。 在回收内存等资源时,你可以使用 QoS 评估最有可能的 Pod 驱逐顺序。 QoS 不适用于临时存储(EphemeralStorage)请求, 因此如果节点在 DiskPressure 下,则上述场景将不适用

Guaranteed Pod的情况下,如何驱逐?

假如在kubernetes环境中,Pod的Qos都是Guaranteed级别时,那么此类的Pod代表是永远不会被驱逐的,那么如果在节点资源压力下,比如系统核心组件,系统守护进程(kubelet、docker、journald)的资源消耗已经超过了系统预留资源(system-reserved & kube-reserved)时,kubelet则根据Pod的优先级开始驱逐(驱逐顺序从优先级低到高)并且满足实际资源使用小于在初始化的requests的值

  • 当 kubelet 因 inode 或 PID 不足而驱逐 pod 时, 它使用优先级来确定驱逐顺序,因为 inode 和 PID 没有请求。

  • kubelet 根据节点是否具有专用的 imagefs 文件系统对 Pod 进行不同的排序

总结

  1. 当kubernetes的可用资源紧缺时,kubelet使用Qos的确保节点的的稳定性,系统正常运行

  2. 当kubernetes触发了驱逐时,那kubelet将使用PriorityClass进行调度,并不考虑Pod的Qos,抢占低优先级别的Pod的资源

配置参考


实际生产环境中,在集群中有以下几种分类的资源

  • Kubernetes平台组件
  • 监控组件 prometheus
  • 应用环境基础资源(rabbitmq zookeeper  xxl-job ingress-controller..)
  • 应用环境中dubbo provider
  • 应用环境中的dubbo consumer
  • 应用环境中相对低优先级的服务(相对manager后台管理系统、告警系统新橙的alarm等)

制定PriorityClass

按照以上顺序制定相对的优先级

资源角色
资源功能
优先级名称
优先级等级
网络插件 cilium-agent system-node-critical 2000001000
阿里云持久化存储 csi-plugin system-node-critical 2000001000
阿里云持久化存储 csi-provisioner system-node-critical 2000001000
API服务器 kube-apiserver system-cluster-critical 2000000000
资源控制管理器 kube-controller-manager system-cluster-critical 2000000000
调试器 kube-scheduler system-cluster-critical 2000000000
分布式数据库 etcd system-cluster-critical 2000000000
网络插件管理器 cilium-operator system-cluster-critical 2000000000
DNS服务器 coredns system-cluster-critical 2000000000
7层代理 ingress-controller base-resource 9999
应用基础资源组件 zookeeper/rabbitmq/xxl-job base-resource 9999
生产环境provider服务 Dubbo中的服务提供者 provider-service 8888
生产环境consumer服务 Dubbo中的服务消费者 consumer-service 7777
生产环境后台管理系统 生产管理后台,告警系统等 admin-service 6666
监控系统Prometheus 生产环境资源监控 monitor-service 5555
posted @ 2021-08-19 17:31  MacoPlus  阅读(662)  评论(0编辑  收藏  举报