您的位置 首页 > 腾讯云社区

cgroup oom引发Pod重建问题分析---CD

业务在上容器云的过程中发现容器不知原因被重建,查看message信息可以看到当 oom_score_adj配置为1,对应score值为0的进程杀完后如果系统还是触发oom时就开始杀pause进程:

为什么CGROUP OOM,剩余进程oom_score_adj都配置为-998的情况下,系统杀的不是占用内存最多的java进程而是选择杀pause进程呢?

查看业务Pod的yaml文件,request和limit配置相等,也就是使用的是Guranteed模式,

在该模式下oom_score_adj会被设置为-998:

另外容器的pause进程无论采用哪种Qos模式,oom_score_adj都为-998。

内核计算oom score的实现如下:

根据内核代码算法推导出oom score的计算方式

points = rss + nr_ptes + swapents

points = points - (points *3) /100 //for root

//若point很小,oom_adj为负数(比如-100),则算出来的point可能是负值

points = points + (oom_score_adj * (total_pages/1000) )

//若point为负值,则此处返回1

points = points > 0 ? points : 1;

//若points值很小,此处得到的score将为0

score = points * 1000 / totalpages;

现在我们根据message打印出的被杀容器内存的情况计算出Guaranteed模式下pause进程和java进程的score值:

Java进程63130:

points=(247047+972)=248019 pages

total_pages=1048576kB/4k=262144 pages

points = points + (oom_score_adj * (total_pages/1000) ) =248019+(-998*262)=(248019-261476) < 0

points < 0 则取值1,即points=1

score=1*1000/262144=0

pause进程59675:

points=(69+7)=86 pages

total_pages=1048576kB/4k=262144 pages

points = points + (oom_score_adj * (total_pages/1000) ) =86+(-998*262)=(248019-261476) < 0

points < 0 则取值1,即points=1

score=1*1000/262144=0

pause进程和占用内存最多的业务进程score值都为0。

由于pause是创建pod时第一个创建的进程,所以kernel在遍历pod对应的cgroup及子cgroup时会先找到pause进程,所以当容器内剩余的进程算出来的score值都是想等时,pause进程就会kill掉导致pod重建。

根据kubernetes官网介绍可知:

采用Guaranteed模式时oom_score_adj值为-998

采用Burstable模式时oom_score_adj的值根据request动态调整,范围为2-999之间

那么我们再看看如果采用Burstable模式是什么结果:

由于采用Burstable模式,oom_score_adj是一个范围在2~999的浮动值,所以这里采用最小值2来计算(oom_score_adj大于0时其值与score值成正比):

Java进程63130:

points=(247047+972)=248019 pages

total_pages=1048576kB/4k=262144 pages

points = points + (oom_score_adj * (total_pages/1000) ) =248019+(2*262)= 248543

score=248543*1000/262144=948

pause进程59675:

points=(69+7)=86 pages

total_pages=1048576kB/4k=262144 pages

points = points + (oom_score_adj * (total_pages/1000) ) =86+(-998*262) < 0

points < 0 则取值1,即points=1

score=1*1000/262144=0

通过上面的计算结果可知占用内存最多的进程java score值为948 远大于pause进程的值oom score值0,这种情况内核会优先杀掉score值更大的java进程,也就不会导致容器被杀触发pod重建。

---来自腾讯云社区的---CD

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: