• k8s QoS与pod驱逐


    概述

    QoS是Quality of Service的缩写,即服务质量。每个pod属于某一个QoS分类,而Kubernetes会根据pod的QoS级别来决定pod的调度、抢占调度和驱逐优先级,而且pod的QoS级别也影响oomkiller对杀死进程的选择。

    pod QoS级别

    QoS主要分为GuaranteedBurstableBest-Effort三个级别,优先级从高到低。

    怎么决定某个pod属于哪个QoS分类呢?根据pod yaml中的cpu和内存资源定义决定。

    Guaranteed

    同时满足以下情形的pod属于Guaranteed级别:
    (1)pod中的所有容器都设置了cpu的request、limit值;
    (2)pod中每个容器的cpu的request值与limit值都相等;
    (1)pod中的所有容器都设置了内存的request、limit值;
    (2)pod中每个容器的内存的request值与limit值都相等;

    ...
    containers:
      - name: test-a
        resources:
          limits:
            cpu: 10m
            memory: 1Gi
          requests:
            cpu: 10m
            memory: 1Gi
    ...
      - name: test-b
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 100m
            memory: 100Mi
    ...
    

    Burstable

    同时满足以下情形的pod属于Burstable级别:
    (1)pod不符合Guaranteed的QoS级别标准;
    (2)pod中至少有一个容器设置了内存或cpu的request或limit值;

    ...
    containers:
      - name: test-a
    ...
      - name: test-b
        resources:
          limits:
            memory: 200Mi
          requests:
            memory: 100Mi
    ...
    

    Best-Effort

    同时满足以下情形的pod属于Best-Effort级别:
    (1)pod中的所有容器都没有设置内存的request与limit;
    (2)pod中的所有容器都没有设置cpu的request与limit;

    ...
    containers:
      - name: test-a
    ...
      - name: test-b
    ...
    

    kubelet驱逐pod顺序

    kubelet不使用pod的QoS级别来确定驱逐顺序,但注意,Guaranteed级别QoS的pod不会被驱逐。

    当node节点内存资源不足时,会触发kubelet的节点压力驱逐,pod驱逐顺序选择如下(排在前面的优先被驱逐):

    (1)先根据pod的内存使用量是否超过内存request排序,超过的排在前面;
    (2)再根据pod的priority值大小排序,值小的排在前面;
    (3)最后根据pod内存request值减去pod的内存使用量的值,得到值小的排在前面;

    关于pod的priority

    通过pod.spec.priorityClassNamepod.spec.priority可为pod设置priority值大小,另外,Guaranteed级别QoS的pod也会间接设置priority值;

    pod的priority值大小会影响kubelet驱逐pod的顺序,还会影响kube-scheduler对于pod调度、抢占调度的优先级顺序:

    (1)当kubelet驱逐pod时,pod其他条件相同的情况下,priority值越小的越容易被驱逐;
    (2)priority值越大,kube-scheduler对于pod调度的优先级越高;
    (3)当pod因资源不足而调度失败时,kube-scheduler会抢占调度该pod,即将priority值比它小的pod驱逐掉,然后将该pod调度上去;

    详细内容请查看官方文档:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/pod-priority-preemption/

    OOM killer机制

    当kubelet没来得及触发pod驱逐,使得节点内存耗尽时,将触发节点上的OOM killer机制;

    Linux上有个机制叫OOM killerOut Of Memory killer),这个机制会在系统内存耗尽的情况下发挥作用,即根据一定的算法规则,选择性的杀死一些进程,以释放部分内存,让系统继续稳定运行。

    如何选择杀死哪个进程

    当发生oomkill时,OOM killer给进程打分,得到oom_score,然后优先把oom_score最大的进程先杀死;

    oom_score怎么计算获得呢?oom_score=oom_score_adj+进程内存占用大小

    oom_score_adj则是可以人工给每个进程设置的,从而让用户通过设置进程的oom_score_adj值来影响OOM killer杀死进程的选择;

    oom_score_adj的值设置为-1000时,表示该进程将不会被OOM killer杀死,但如果设置的值不是-1000,那这个进程还是会参与打分,会受oom_score_adj以及进程内存占用大小的影响,需要注意的是,即使oom_score_adj的值设置的很小,比如-999,但当你的进程占用内存很大时,该进程同样有很大的概率会被杀死;

    pod中容器进程的oom_score_adj

    对于Guaranteed级别的pod,其oom_score_adj的值被设置为-998,对于Best-Effort级别的pod,其oom_score_adj的值被设置为1000,对于Burstable级别的pod,其oom_score_adj的取值为2到999。

    怎么避免OOM Killer杀死某个业务进程?

    (1)将进程oom_score_adj的值设置为-1000;
    (2)关闭OOM killer机制;

    pod抢占调度

    pod抢占调度机制,解决的是 Pod 调度失败时该怎么办的问题。

    正常情况下,当一个 pod 调度失败后,就会被暂时 “搁置” 处于 pending 状态,直到 pod 被更新或者集群状态发生变化,调度器才会对这个 pod 进行重新调度。

    但是有的时候,我们希望给pod分等级,即分优先级。当一个高优先级的 Pod 调度失败后,该 Pod 并不会被“搁置”,而是会“挤走”某个 Node 上的一些低优先级的 Pod(请求apiserver,删除pod),这样一来就可以保证高优先级 Pod 会优先调度成功。

    这里所讲的优先级就是前面提到的pod的priority值大小。

    关于pod优先级,具体请参考:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/pod-priority-preemption/

    抢占发生的原因,一定是一个高优先级的 pod 调度失败,我们称这个 pod 为“抢占者”,称被抢占的 pod 为“牺牲者”(victims)。

  • 相关阅读:
    七、Thymeleaf对象的访问
    Git和GitHub(尚硅谷的视频教学)
    随笔-那些快乐的日子
    APIServerHandler及ServeHTTP流程分析
    身份认证——手机验证码的登录、邮箱密码登录、二维码登录等——cookie和session的原理
    sqli-labs(3)
    Python itertools教程(python中的迭代器与组合迭代器)
    将算力普惠到底 阿里云开启金秋上云季:数百款爆品享专属特惠价阿里云上新金秋云创季:上百款云产品享特惠 全能爆品仅99元/年
    软考 - 04 分布式缓存系统
    代码随想录算法训练营day60|84.柱状图中最大的矩形 |完结撒花~
  • 原文地址:https://www.cnblogs.com/lianngkyle/p/16536591.html