kubernetes借助系统的OOM KILL提升服务质量,至于什么是OOM KILL可以去网上搜一下这里不再班门弄斧,下面我们就看一下Kubernetes是按照什么规则来分别设置容器的oom_score_adj
。
其实规则也比较简单只有一段代码:
//pkg/kubelet/qos/policy.go
func GetContainerOOMScoreAdjust(pod *v1.Pod, container *v1.Container, memoryCapacity int64) int {
switch v1qos.GetPodQOS(pod) {
case v1.PodQOSGuaranteed:
// Guaranteed containers should be the last to get killed.
return guaranteedOOMScoreAdj
case v1.PodQOSBestEffort:
return besteffortOOMScoreAdj
}
// Burstable containers are a middle tier, between Guaranteed and Best-Effort. Ideally,
// we want to protect Burstable containers that consume less memory than requested.
// The formula below is a heuristic. A container requesting for 10% of a system's
// memory will have an OOM score adjust of 900. If a process in container Y
// uses over 10% of memory, its OOM score will be 1000. The idea is that containers
// which use more than their request will have an OOM score of 1000 and will be prime
// targets for OOM kills.
// Note that this is a heuristic, it won't work if a container has many small processes.
memoryRequest := container.Resources.Requests.Memory().Value()
oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity
// A guaranteed pod using 100% of memory can have an OOM score of 10. Ensure
// that burstable pods have a higher OOM score adjustment.
if int(oomScoreAdjust) < (1000 + guaranteedOOMScoreAdj) {
return (1000 + guaranteedOOMScoreAdj)
}
// Give burstable pods a higher chance of survival over besteffort pods.
if int(oomScoreAdjust) == besteffortOOMScoreAdj {
return int(oomScoreAdjust - 1)
}
return int(oomScoreAdjust)
}
这段代码就是讲的如何计算每个容器的oom score的。
首先看这个容器所属的Pod是属于什么级别的,如果是Guaranteed级别的直接返回-998也是最高级最后被Kill掉的,如果是BestEffort级别则直接返回1000是最低级别的,最有可能被杀掉。如果是Burstable则是中间级别需要按照资源的申请量来计算oom score。
oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity
就是这段公式计算出容器的score,最后得到的值会在2-999之间,从这个公式能够看出来Burstable级别的如果越是资源申请的越多则给的分越低,这就意味着容器越不容易被杀掉,如果是申请量越少得出的分越高则越容易被杀掉。