在过去的几天里,我的一些Pod一直出现panic,操作系统系统日志显示OOMKiller杀死了容器进程。我做了一些研究以了解这些东西是如何工作的。Pod内存限制和cgroup内存设置创建一个内存限制设置为128Mi的Pod:kubectlrun--restart=Never--rm-it--image=ubuntu--limits='memory=128Mi'--shIfyoudon'如果看不到命令??提示符,请尝试按enter.root@sh:/#打开另一个终端并使用以下方法获取Pod的uid:kubectlgetpodssh-oyaml|grepuiduid:98f587f8-8994-4eb4-a7b6-d62be890cc08通过以下命令找到Pod运行的node节点:kubectlgetpods-owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESsh1/1Running052s10.107.1.13610.67.62.22在运行Pod的服务器(10.67.62.22)上,根据Pod的uid查看cgroup设置,首先进入Pod对应的cgroup:cd/sys/fs/cgroup/memory/kubepods/burstable/pod98f587f8-8994-4eb4-a7b6-d62be890cc08执行ls可以看到如下:lsbdc2f6d0b9791f9a8b86c1e877c830e387170c955cdc09866350344b19e08a6ememory.kmem.failcntmemory.kmem.tcp.usage_in_bytesmemory.memsw.usage_in_bytesmemory.swappinesscgroup.clone_childrenmemory.kmem.limit_in_bytesmemory.kmem.usage_in_bytesmemory.move_charge_at_immigratememory.usage_in_bytescgroup.event_controlmemory.kmem.max_usage_in_bytesmemory.limit_in_bytesmemory.numa_statmemory.use_hierarchycgroup.procsmemory.kmem.slabinfomemory.max_usage_in_bytesmemory.oom_controlnotify_on_releaseffe85090722bdfbb94fab8a7b58ce714191c3456c2b405240afd58756664cc88memory.kmem.tcp.failcntmemory.memsw.failcntmemory.pressure_leveltasksmemory.failcntmemory.kmem.tcp.limit_in_bytesmemory.memsw.limit_in_bytesmemory.soft_limit_in_bytesmemory.force_emptymemory.kmem.tcp.max_usage_in_bytes内存.memsw.max_usage_in_bytesmemory.stat查看限制值:catmemory.limit_in_bytes134217728数字134217728正好是128Mi(128*1024*1024)所以现在更清楚Kubernetes通过cgroups设置内存限制了。一旦pod消耗的内存超过限制,cgroup就会开始杀掉容器进程。压力测试让我们通过一个开放的shell会话在Pod上安装压力工具。root@sh:/#更新;aptinstall-ystress同时在节点上运行dmesg-Tw监控Syslog。首先在100M的内存限制内运行压力工具。root@sh:/#stress--vm1--vm-bytes100M&[1]253root@sh:/#stress:info:[253]dispatchinghogs:0cpu,0io,1vm,0hdd和开始第二次压力测试:root@sh:/#stress--vm1--vm-bytes=100Mstress:info:[256]dispatchinghogs:0cpu,0io,1vm,0hddstress:FAIL:[253](415)<--worker254得到信号9stress:WARN:[253](417)nowreapingchildworkerprocessresstress:FAIL:[253](451)failedruncompletedin66sfirststressprocess(processid253)immediatelyKilledby信号9.此时,查看,syslog:[thu5月21日08:48:412020]强调oom-killer:gfp_mask=0xD0,订单=0,oom_score_adj=999=999[thu5月2108:48:412020]mems_allowed=0-1[ThuMay2108:48:412020]CPU:22PID:5222Comm:stressTainted:GO----------3.10.0-862.14.1.5.h328.eulerosv2r7.x86_64#1[ThuMay2108:48:412020]硬件名称:OpenStackFoundationOpenStackNova,BIOSrel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci1000004/01/2014[ThuMay2108:48:412020]呼叫跟踪:[2020年5月21日星期四08:48:41][]dump_stack+0x19/0x1b[2020年5月21日星期四08:48:41][]dump_header+0x90/0x229[星期四2020年5月21日08:48:41][]?find_lock_task_mm+0x56/0xc0[2020年5月21日08:48:41][]oom_kill_process+0x254/0x3d0[2020年5月21日08:48:41][]mem_cgroup_oom_synchronize+0x553/0x580[2020年5月21日星期四08:48:41][]?mem_cgroup_charge_common+0xc0/0xc0[2020年5月21日星期四08:48:41][]pagefault_out_of_memory+0x14/0x90[2020年5月21日星期四08:48:41][]mm_fault/error[huMay+0x672108:48:412020][]__do_page_fault+0x4a6/0x4f0[2020年5月21日星期四08:48:41][]trace_do_page_fault+0x56/0x150[5月21日星期四08:202:41][]do_async_page_fault+0x22/0xf0[2020年5月21日星期四08:48:41][]async_page_fault+0x28/0x30[2020年5月21日星期四08:48:41]/kubepods/88burstable/7中的任务-8994-4eb4-a7b6-d62be890cc08/ffe85090722bdfbb94fab8a7b58ce714191c3456c2b405240afd58756664cc88killedasaresultoflimitof/kubepods/burstable/pod98f587f8-8994-4eb4-a7b6-d62be890cc08[ThuMay2108:48:412020]memory:usage131072kB,limit131072kB,failcnt6711[2020年5月21日星期四08:48:41]内存ory+swap:使用量131072kB,限制9007199254740988kB,failcnt0[2020年5月21日星期四08:48:41]kmem:使用量0kB,限制9007199254740988kB,failcnt0[2020年5月21日星期四08:48:41]/burstable/pod98f587f8-8994-4eb4-a7b6-d62be890cc08:缓存:0KBrss:0KBrss_huge:0KB映射文件:0KB交换:0KBinactive_anon:0KBactive_anon:0KBinactive_file:0KBactive_file:0KBunevictable:0KB[ThuMay2108:48:412020]Memorycgroupstatsfor/kubepods/burstable/pod98f587f8-8994-4eb4-a7b6-d62be890cc08/bdc2f6d0b9791f9a8b86c1e877c830e387170c955cdc09866350344b19e08a6e:cache:0KBrss:1656KBrss_huge:0KBmapped_file:0KBswap:0KBinactive_anon:0KBactive_anon:1656KBinactive_file:0KBactive_file:0KBunevictable:0KB[ThuMay2108:48:412020]Memorycgroupstatsfor/kubepods/burstable/pod98f587f8-8994-4eb4-a7b6-d62be890cc08/ffe85090722bdfbb94fab8a7b58ce714191c3456c2b405240afd58756664cc88:cache:100KBrss:129316KBrss_huge:98304KBmapped_file:4KBswap:0KB娜娜ctive_anon:0KBactive_anon:129268KBinactive_file:0KBactive_file:0KBunevictable:0KB[2020年5月21日星期四08:48:41][pid]uidtgidtotal_vmrssnr_ptesswapentsoom_score_adjname[2020年5月21日星期四08:48:41][25078]025078110439770-998暂停[2020年5月21日星期四08:48:41][25519]0255194624104140999bash[2020年5月21日星期四08:48:41][5221]052219205780999压力[2020年5月21日星期四08:48:41][5222]052222765817581420999压力[2020年5月21日08:48:41][6772]0677220571980999压力[星期四2020年5月21日08:48:41][6774]067742765814566360999压力[2020年5月21日08:48:41星期四]内存cgroup内存不足:杀死进程5222(压力)分数1513或牺牲孩子[星期四May2108:48:412020]终止进程5222(压力)total-vm:110632kB,anon-rss:70320kB,file-rss:4kB,shmem-rss:0kB主机上的进程ID5222被OOM杀死我们需要详细查看syslog日志的最后一部分:[ThuMay2108:48:412020]Memorycgroupoutofmemory:Killprocess5222(stress)score1513orsacrificchild[ThuMay2108:48:412020]Killedprocess5222(stress)total-vm:110632kB,匿名-rss:70320kB,file-rss:4kB,shmem-rss:0kB对于这个Pod,有一些进程是OOMKiller选择杀掉的候选进程。确保网络进程命名空间中pause容器的oom_score_adj值为-998,保证不被kill。容器中的所有其他进程的oom_score_adj值为999。我们可以根据Kubernetes文档中的公式验证这个值,如下所示,min(max(2,1000-(1000*memoryRequestBytes)/machineMemoryCapacityBytes),999)来找出一个节点可以分配多少内存:kubectldescribenodes10.67.62.22|grepAllocatable-A7Allocatable:attachable-volumes-csi-disk.csi.everest.io:58cce/eni:15cpu:31850mephemeral-storage:28411501317hugepages-1Gi:0hugepages-2Mi:0memory:60280908Ki如果没有设置,requestMemory默认和limit值一样。根据公式,我们计算出oom_score_adj应该为999。具体为:min(max(2,1000-128*1024/60280908),999)注意容器内所有进程的oom_score_adj值相同。OOMkiller会根据内存使用情况计算OOM值,并使用oom_score_adj值进行微调。最后,它终止了第一个使用内存最多的压力进程,即进程ID为5222的进程。结论我们只详细介绍了Qos为Burstable类型的Pod的内存限制。对于其他类型,您可以自行测试。不同类型的Pod的oom_score_adj是不同的。