输出结果如下,可以看到pod的qosClass为Guaranteed
... ... name: pod-burstable uid: 7d858afc-f88a-454e-85dc-81670a0ddb8b ... ... status: qosClass: Burstable ... ... BestEffort定义:pod中所有的容器都没有设置任何内存和CPU的限制和请求。
这个很好理解,我们创建个pod试试
apiVersion: v1 kind: Pod metadata: name: pod-besteffort spec: containers: - name: pod-besteffort image: zerchin/network创建pod
kubectl create -f pod-besteffort.yaml查看pod 详细信息
kubectl get pod pod-besteffort -oyaml输出结果如下,可以看到pod的qosClass为BestEffort
... ... name: pod-besteffort uid: 1316dbf7-01ed-415b-b901-2be9d650163c ... ... status: qosClass: BestEffort那么,在CGroup中对应的路径为kubepods/besteffort/pod1316dbf7-01ed-415b-b901-2be9d650163c
QoS优先级当集群资源被耗尽时,容器会被杀死,此时会根据QoS优先级对pod进行处理,即优先级高的会尽量被保护,而优先级低的会优先被杀死
三种Qos类型优先级(由高到低):Guaranteed > Burstable > BestEffort
其中CPU属于可压缩资源,而内存属于不可压缩资源,这里我们主要讨论一下当内存耗尽时,是如何根据QoS优先级处理pod
BestEffort:BestEffort类型的pod没有设置资源限制,此类pod被认为是最低优先级,当系统内存不足时,这些pod会首先被杀死
Burstable :Burstable 类型的pod设置有部分资源的请求和限制,此类pod的优先级高于BestEffort类型的pod,当系统内存不足且系统中不存在BestEffort类型的pod时才会被杀死
Guaranteed :Guaranteed类型的pod同时设置了CPU和内存的资源限制和请求,此类pod的优先级最高,只有在系统内存不足且系统系统中不存在BestEffort和Burstable 的pod时才会被杀死
OOM score在前面讲内存限制时提到过,就是当进程申请的内存超出了已有的内存资源,那么为了保证主机的稳定运行,就会基于进程oom_score的值,有选择性的杀死某个进程,这个过程就是OOMKilled。
这里我们先了解一下什么是oom_score:
当系统内存资源被耗尽时,就需要释放部分内存保证主机的运行。而内存是被进程所占用的,所以释放内存实际上就是要杀死进程。那么系统是如何选择进程进行杀死的呢?答案就是基于oom_score的值选择可以杀死的进程。oom_score的值在0-1000范围,其中oom_score的值越高,则被杀死的可能性越大。
oom_score的值还会受到oom_score_adj影响,最后的得分会加上oom_score_adj的值,也就是说,可以通过设置oom_score_adj的大小从而影响最终oom_score的大小。
其中正常情况下,oom_score是该进程消耗的内存百分比的10倍,通过oom_score_adj进行调整,例如如果某个进程使用了100%的内存,则得分为1000;如果使用0%的内存,则得分为0(其他例如root用户启动的进程会减去30这里不讨论)
那么我们来看看不同的QoS类型的score值是如何设置的
BestEffort:由于它的优先级最低,为了保证BestEffort类型的pod最先被杀死,所以设置oom_score_adj为1000,那么BestEffort类型pod的oom_score值为1000
Guaranteed:由于它的优先级最高,为了保证Guaranteed类型的pod的不被杀死,所以设置oom_score_adj为-998,那么Guaranteed类型pod的oom_score值为0或者1
Burstable:这里要分几种情况讨论
如果总内存请求 > 可用内存的99.8%,则设置oom_score_adj的值为2,否则将oom_score_adj设置为1000 - 10 x 内存请求的百分比,这样可以确保Burstable类型的pod的oom_score > 1。
如果内存请求为0,则设置oom_score_adj的值为999。所以,如果Burstable类型的pod和Guaranteed类型的发生冲突时,保证Burstable类型的pod被杀死。
如果Burstable类型的pod使用的内存少于请求的内存,则其oom_score<1000,因此,如果BestEffort类型的pod与使用少于请求内存的Burstable类型的pod发生冲突时,则BestEffort类型的pod将被杀死
如果Burstable类型的pod使用的内存大于内存请求时,oom_score=1000,否则oom_score<1000
如果一个使用的内存多于请求内存的Burstable类型的pod,与另一个使用的内存少于请求内存的Burstable类型的pod发生冲突时,则前者将被杀死
如果Burstable类型的pod与多个进程发生冲突,则OOM分数的计算公式是一种启发式的,它不能保证“请求和限制”的保证
infra 容器(pause)或init 容器,oom_score_adj为-998
默认kubelet和docker的oom_score_adj为-999
基于上述oom_score,就能保证当系统资源耗尽时,首先被杀死的是BestEffort类型的pod,其次是Burstable类型的pod,最后才是Guaranteed类型的pod