Cgroup限制内存使用

Cgroup限制内存使用

2023年8月2日发(作者:)

Cgroup限制内存使⽤⼀、简述:1、不设置如果不设置-m,--memory和--memory-swap,容器默认可以⽤完宿舍机的所有内存和 swap 分区。不过注意,如果容器占⽤宿主机的所有内存和swap 分区超过⼀段时间后,会被宿主机系统杀死2、设置-m,--memory,不设置--memory-swap如果在容器中运⾏⼀个⼀直不停申请内存的程序,你会观察到该程序最终能占⽤的内存⼤⼩为 2a。⽐如$ docker run -m 1G ubuntu:16.04,该容器能使⽤的内存⼤⼩为 1G,能使⽤的 swap 分区⼤⼩也为 1G。容器内的进程能申请到的总内存⼤⼩为 2G。3、Memory reservation这种 memory reservation 机制不知道怎么翻译⽐较形象。Memory reservation 是⼀种软性限制,⽤于节制容器内存使⽤。给--memory-reservation设置⼀个⽐-m⼩的值后,虽然容器最多可以使⽤-m使⽤的内存⼤⼩,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占⽤回到--memory-reservation设置的值⼤⼩。docker run -it -m 500M --memory-reservation 200M ubuntu:16.04 /bin/bash如果容器使⽤了⼤于 200M 但⼩于 500M 内存时,下次系统的内存回收会尝试将容器的内存锁紧到 200M 以下。4、OOM killer默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。这个杀死进程来节省内存的进程,我们姑且叫它 OOM killer。我们可以通过设置--oom-kill-disable选项来禁⽌ OOM killer 杀死容器内进程。但请确保只有在使⽤了-m/--memory选项时才使⽤--oom-kill-disable禁⽤ OOM killer。如果没有设置-m选项,却禁⽤了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。下⾯的例⼦限制了容器的内存为 100M 并禁⽌了 OOM killer:$ docker run -it -m 100M --oom-kill-disable ubuntu:16.04 /bin/bash ⼆、案例OOM排查背景: 微服务架构,⼏百个服务,运⾏在不同的容器上,总是莫名的同时出现⼗⼏个服务不可⽤,伴随着各个容器的状态异常,⽆法ping通,⽆法ssh上去,⼤量告警。。。总是莫名的有物理机宕机,每次查的时候总是⽆疾⽽终1、⼤量的容器⽆法ping通,登录上主机,查看资源抢占情况*(⽰例图):

在以上的图中,主要看四个指标,⼀个是load,Emmm,假设CPU是56个,实际的load值达到了3K,那么这个时候,系统已经不堪重负了;⼀个是Tasks,主要看任务的运⾏数量,在图中,才2个在运⾏,实际也就⼏百个,但是sleeping状态的有⼏万个,⽽zombie状态的有300多个;⼀个就是内存的使⽤量,在实际情况中,内存基本使⽤完毕;最后⼀个就是使⽤交换空间,图中的未使⽤,实际上已经全部使⽤完毕CPU的load太⾼,那么说起来其实也就两个队列,⼀个是运⾏的队列,⼀个block的队列,从⽽需要收集相关的进程信息,从⽽可以使⽤ps来查看进程的状态信息1、查看R状态,D状态和Z状态的进程ps h -eo pid,state,ucmd,start | awk '{if ($2=="D"||$2=="R"){print $0}}' | grep -v ps| sort | uniq -c |sort -nr -k12、查看所有R状态,D状态的线程ps -eL h o pid,state,ucmd | awk '{if ($2=="D"||$2=="R"){print $0}}' | grep -v ps| sort | uniq -c |sort -nr -k1-e 查看所有进程,等价于-A-o ⾃定义输出格式-f 全部列出,列出每个进程更详细的信息-L 显⽰线程

以上主要是为了统计:⼀个是进程的数量,⼀个是线程的数量。。。(需要多次执⾏,从⽽进⾏对⽐,可以知道哪些进程造成了相关的阻塞,数量庞⼤的必有蹊跷。。),统计的结果是⼤量状态为D的进程。。。在线程多的结果中,可以看到相关的PID,从⽽可以知道是哪个进程产⽣了⼤量的阻塞统计容器的数量,从容器的内存限制来查看是否容器的内存都达到了限制排查相关的⽇志:

在⽇志⾥⾯查看到⼤量的OOM信息,也就可以看到相关的进程被杀死,从⽽可以找到是哪些进程导致了内存泄漏,从⽽进⾏整改。。。在kern⽇志中可以看到被杀死的进程名,在dmesg中可以看到OOM,在message中,能追查到相关的容器id总结:排查思路:根据load值偏⾼,查询进程的数量和线程的数量,从⽽从增加的数量查看到是什么样的进程阻塞了CPU的调度,查看系统⽇志,主要查看oom,从⽽对⽐两者的结果进程是否⼀致,从⽽看哪个进程OOM需要整改。。疑问:在以上的问题追踪中,可以产⽣两个疑点:第⼀既然oom都杀死了进程,为什么内存还会溢出,杀死了进程应该已经将相关的内存进⾏回收了;第⼆:是什么导致了那么⾼的load值回答第⼀个问题就是:在oom killer进⾏杀死进程的时候,使⽤的是kill -9 ,从⽽能强⾏杀死进程,但是在进⾏oom的时候,oom的分值是给占⽤内存⼤的进程,⽽这个进程在等待IO,也就是等待分配内存,Emm。。。读取内存也是⼀种IO,所谓的缺页中断。。。在杀死这个进程的时候,这个进程的状态为D,也就是表⽰这个进程是不可中断睡眠,在等待分配内存。。。从⽽杀死这个进程可能根本就⽆法杀死。。。 还有⼀种情况是,进程已经变成了僵⼫进程,从⽽在oom killer在进⾏杀死进程的时候,根据当前的进程号id杀,⽽僵⼫进程要想杀死,必须杀掉其⽗进程,⽽当僵⼫进程的⽗进程为1的时候,这个时候就相当于服务器重启了

发布者:admin,转转请注明出处:http://www.yc00.com/news/1690959716a473273.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信