2023年7月6日发(作者:)
linux压测出现⼤量anon进程,docker内存监控与压测⽅式⼀直运⾏的docker容器显⽰内存已经耗尽,并且容器内存耗尽也没出现重启情况,通过后台查看发现进程没有占⽤多少内存。内存的监控使⽤的是cadvisor,计算⽅式也是使⽤cadvisor的页⾯计算⽅式,所以决定对docker的内存计算做下研究。docker version:Client:Version: 1.12.6API version: 1.24Go version: go1.6.4Git commit: 78d1802Built: Tue Jan 10 20:20:01 2017OS/Arch: linux/amd64Server:Version: 1.12.6API version: 1.24Go version: go1.6.4Git commit: 78d1802Built: Tue Jan 10 20:20:01 2017OS/Arch: linux/amd64kubernetes version:Client Version: {Major:"1", Minor:"8", GitVersion:"v1.8.2+coreos.0",GitCommit:"4c0769e81ab01f47eec6f34d7f1bb80873ae5c2b", GitTreeState:"clean", BuildDate:"2017-10-25T16:24:46Z",GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}Server Version: {Major:"1", Minor:"8", GitVersion:"v1.8.2+coreos.0",GitCommit:"4c0769e81ab01f47eec6f34d7f1bb80873ae5c2b", GitTreeState:"clean", BuildDate:"2017-10-25T16:24:46Z",GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}1.创建pod yaml⽂件,使⽤busybox镜像做测试,对镜像设定2核2G内存的限制[docker@k8s busybox]$ cat iVersion: v1kind: Podmetadata:name: busyboxnamespace: defaultspec:containers:- image: :8021/public/busybox:latestcommand:- sleep- "3600"imagePullPolicy: IfNotPresentname: busyboxresources:limits:cpu: "2"memory: 2Girequests:cpu: 100mmemory: 64MirestartPolicy: Always2.通过kubectl命令⽣成busybox服务[docker@k8s busybox]$ kubectl create -f d "busybox" created3.进⼊容器的/sys/fs/cgroup/memory⽬录,ls查看得到如下⽂件-rw-r--r-- 1 root root 0 May 31 03:18 _children--w--w--w- 1 root root 0 May 31 03:18 _control-rw-r--r-- 1 root root 0 May 31 03:18 -rw-r--r-- 1 root root 0 May 31 03:18 t--w------- 1 root root 0 May 31 03:18 _empty-rw-r--r-- 1 root root 0 May 31 03:18 t-rw-r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _usage_in_bytes-r--r--r-- 1 root root 0 May 31 03:18 fo-rw-r--r-- 1 root root 0 May 31 03:18 t-rw-r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _usage_in_bytes-r--r--r-- 1 root root 0 May 31 03:18 _in_bytes-r--r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _usage_in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 t-rw-r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _usage_in_bytes-r--r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _charge_at_immigrate-r--r--r-- 1 root root 0 May 31 03:18 _stat-rw-r--r-- 1 root root 0 May 31 03:18 _control---------- 1 root root 0 May 31 03:18 re_level-rw-r--r-- 1 root root 0 May 31 03:18 _limit_in_bytes-r--r--r-- 1 root root 0 May 31 03:18 -rw-r--r-- 1 root root 0 May 31 03:18 ness-r--r--r-- 1 root root 0 May 31 03:18 _in_bytes-rw-r--r-- 1 root root 0 May 31 03:18 _hierarchy-rw-r--r-- 1 root root 0 May 31 03:18 notify_on_release-rw-r--r-- 1 root root 0 May 31 03:18 tasks我们主要关注⼀下⼏个⽂件⽂件名含义_in_bytes已使⽤的内存量(包含cache和buffer)(字节),相当于linux的used__in_bytes限制的内存总量(字节),相当于linux的total_t申请内存失败次数计数内存相关状态的⽂件包含的内容字段含义cache页缓存,包括 tmpfs(shmem),单位为字节rss匿名和 swap 缓存,不包括 tmpfs(shmem),单位为字节mapped_filememory-mapped 映射的⽂件⼤⼩,包括 tmpfs(shmem),单位为字节pgpgin存⼊内存中的页数pgpgout从内存中读出的页数swapswap ⽤量,单位为字节active_anon在活跃的最近最少使⽤(least-recently-used,LRU)列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节inactive_anon不活跃的 LRU 列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节active_file活跃 LRU 列表中的 file-backed 内存,以字节为单位inactive_file不活跃 LRU 列表中的 file-backed 内存,以字节为单位unevictable⽆法再⽣的内存,以字节为单位hierarchical_memory_limit包含 memory cgroup 的层级的内存限制,单位为字节hierarchical_memsw_limit包含 memory cgroup 的层级的内存加 swap 限制,单位为字节查看_in_bytes⽂件/sys/fs/cgroup/memory # cat _in_bytes2147483648计算容器的限制内存为2g,和yaml⽂件⾥⾯定义的限制内存⼀样。查看_in_bytes⽂件/sys/fs/cgroup/memory # cat _in_bytes2739376通过docker stats 容器id查看容器的占⽤内存,和_in_bytes的数据相符。4.使⽤dd命令快速⽣成1.5g⼤⽂件~ # dd if=/dev/zero of=test bs=1M count=15001500+0 records in1500+0 records out1572864000 bytes (1.5GB) copied, 1.279989 seconds, 1.1GB/s再次通过docker stats 容器id查看容器的占⽤内存查看_in_bytes⽂件/sys/fs/cgroup/memory # cat _in_bytes1619329024发现容器的占⽤内存达到了1.5g,查看/sys/fs/cgroup/memory # cat che 1572868096rss 147456rss_huge 0mapped_file 0dirty 1572868096writeback 0swap 0pgpgin 384470pgpgout 433pgfault 607pgmajfault 0inactive_anon 77824active_anon 12288inactive_file 1572864000active_file 4096unevictable 0hierarchical_memory_limit 2147483648hierarchical_memsw_limit 4294967296total_cache 1572868096total_rss 147456total_rss_huge 0total_mapped_file 0total_dirty 1572868096total_writeback 0total_swap 0total_pgpgin 384470total_pgpgout 433total_pgfault 607total_pgmajfault 0total_inactive_anon 77824total_active_anon 12288total_inactive_file 1572864000total_active_file 4096total_unevictable ⽂件中的cache字段添加了1.5g,⽽inactive_file字段为1.5g,因此,dd所产⽣的⽂件cache计算在inactive_file上。这就导致了所看到的容器内存的监控居⾼不下,因为cache是可重⽤的,并不能反映进程占⽤内存。⼀般情况下,计算监控内存可根据计算公式:active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cacheThereforeactive_anon + inactive_anon ≠ rss, because rss does not include _file + inactive_file = cache - size of tmpfs所以实际内存使⽤计算为:real_used = _in_bytes - (active_file + inactive_file)5.压测(1)准备tomcat镜像和jmeter压测⼯具,tomcat的yaml⽂件如下apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: tomcat-deploymentspec:replicas: 1template:metadata:labels:app: tomcatspec:containers:- name: tomcatimage: :8021/public/tomcat:8ports:- containerPort: 8080resources:limits:cpu: "1"memory: 300Mi---apiVersion: v1kind: Servicemetadata:labels:name: tomcatname: tomcatnamespace: defaultspec:ports:- name: tomcatport: 8080protocol: TCPtargetPort: 8080type: NodePortselector:app: tomcatyaml⽂件中限制tomcat镜像的使⽤内存为300Mi,执⾏命令⽣成⽂件。通过docker stats查看没有负载情况下tomcat容器的内存占⽤。(2)提取tomcat的service nodePort端⼝[docker@ecs-5f72-0006 ~]$ kubectl get svc tomcat -o=custom-columns=nodePort:.[0].nodePortnodePort31401(3)登陆jmeter官⽹下载压测⼯具在windows上运⾏jmeter⼯具,到bin⽬录点击运⾏jmeter,配置jmeter如下:配置好测试选项后点击启动按钮开始压测,通过docker stats查看容器内存使⽤情况发现已经到达限制。通过kubectl get pods查看pod的运⾏情况发现tomcat由于内存超过限制值被kill掉。总结关于docker stats内存监控的问题⼀直存在,docker将cache/buffer纳⼊内存计算引起误解。docker内存的计算⽅式和linux的内存使⽤计算⽅式⼀致,也包含了cache/buffer。但是cache是可重复利⽤的,经常使⽤在I/O请求上,使⽤内存来缓解可能被再次访问的数据,为提⾼系统性能。在官⽅github上,也有很多⼈提交了关于内存监控的issue,直到了Docker 17.06版本,docker stats才解决了这个问题。但是这也仅仅是docker stats的显⽰看起来正常了,⽽进⼊容器查看内存的使⽤还是包含的cache,如果直接使⽤cadvisor搜集的数据,还是会出现包含了cache的情况。通过压测docker,最后发现当压测到程序的限制内存时,pod出现重启,这也解释了我们在使⽤docker监控时,即使内存占⽤99%+,却不出现pod重启的情况,这⾥⾯有相当⼀部分的内存是cache占⽤。以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持我们。如有错误或未考虑完全的地⽅,望不吝赐教。时间: 2021-03-18
发布者:admin,转转请注明出处:http://www.yc00.com/web/1688593105a153158.html
评论列表(0条)