page contents

Docker容器内存监控

要明白docker容器内存是如何计算的,首先要明白linux中内存的相关概念。使用free命令可以查看当前内存使用情况。

attachments-2020-09-Iaa2pmAV5f62feaf5bdb3.jpg

https://www.cnblogs.com/xuxinkun/


linux内存监控


要明白docker容器内存是如何计算的,首先要明白linux中内存的相关概念。

使用free命令可以查看当前内存使用情况。

[root@localhost ~]$ free 
             total       used       free     shared    buffers     cached
Mem:     264420684  213853512   50567172   71822688    2095364  175733516
-/+ buffers/cache:   36024632  228396052
Swap:     16777212    1277964   15499248

这里有几个概念:

  • mem: 物理内存
  • swap: 虚拟内存。即可以把数据存放在硬盘上的数据
  • shared: 共享内存。存在在物理内存中。
  • buffers: 用于存放要输出到disk(块设备)的数据的
  • cached: 存放从disk上读出的数据

为方便说明,我对free的结果做了一个对应。

[root@localhost ~]$ free 
             total       used       free        shared    buffers   cached
Mem:     total_mem   used_mem    free_mem   shared_mem    buffer     cache
-/+ buffers/cache:  real_used   real_free
Swap:   total_swap  used_swap   free_swap

attachments-2020-09-tLGIHGjk5f62ff17e6b51.jpg


一般认为,buffer和cache是还可以再进行利用的内存,所以在计算空闲内存时,会将其剔除。
因此这里有几个等式:

real_used = used_mem - buffer - cache
real_free = free_mem + buffer + cache
total_mem = used_mem + free_mem


了解了这些,我们再来看free的数据源。其实其数据源是来自于/proc/memeinfo文件。

[root@localhost ~]$ cat /proc/meminfo 
MemTotal:       264420684 kB
MemFree:        50566436 kB
Buffers:         2095356 kB
Cached:         175732644 kB
SwapCached:       123688 kB
Active:         165515340 kB
Inactive:       37004224 kB
Active(anon):   92066880 kB
Inactive(anon):  4455076 kB
Active(file):   73448460 kB
Inactive(file): 32549148 kB
Unevictable:      362900 kB
Mlocked:           74696 kB
SwapTotal:      16777212 kB
SwapFree:       15499248 kB
Dirty:              2860 kB
Writeback:             0 kB
AnonPages:      24932928 kB
Mapped:         58165040 kB
Shmem:          71822688 kB
Slab:            8374496 kB
SReclaimable:    8163096 kB
SUnreclaim:       211400 kB
KernelStack:       45824 kB
PageTables:       606296 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    148987552 kB
Committed_AS:   114755628 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      772092 kB
VmallocChunk:   34225428328 kB
HardwareCorrupted:     0 kB
AnonHugePages:  22083584 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        7168 kB
DirectMap2M:     2015232 kB
DirectMap1G:    266338304 kB


docker


说完linux的内存,我们再来看下docker的内存监控。docker自身提供了一种内存监控的方式,即可以通过docker stats对容器内存进行监控。
该方式实际是通过对cgroup中相关数据进行取值从而计算得到。


cgroup


cgroup中的memory子系统为hierarchy提供了如下文件。

[root@localhost ~]$ ll /cgroup/memory/docker/53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f/
总用量 0
--w--w--w- 1 root root 0 2月  22 12:51 cgroup.event_control
-rw-r--r-- 1 root root 0 5月  25 17:07 cgroup.procs
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.failcnt
--w------- 1 root root 0 2月  22 12:51 memory.force_empty
-rw-r--r-- 1 root root 0 3月  30 17:06 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 3月  30 17:06 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 2月  22 12:51 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.move_charge_at_immigrate
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.oom_control
-rw-r--r-- 1 root root 0 3月  30 17:06 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 2月  22 12:51 memory.stat
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.swappiness
-r--r--r-- 1 root root 0 2月  22 12:51 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 2月  22 12:51 memory.use_hierarchy
-rw-r--r-- 1 root root 0 2月  22 12:51 notify_on_release
-rw-r--r-- 1 root root 0 2月  22 12:51 tasks

这些文件的具体含义可以查看相关资料cgroup memory。
这里主要介绍几个与docker监控相关的。

attachments-2020-09-IS0pkUHu5f62ff50ebe0d.jpg

[root@localhost 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.usage_in_bytes 
135021858816

[root@localhost 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.memsw.usage_in_bytes 
135679291392

[root@localhost 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.stat 
cache 134325506048
rss 695980032
mapped_file 16155119616
pgpgin 21654116032
pgpgout 21705492352
swap 655171584
inactive_anon 4218880
active_anon 74202603520
inactive_file 8365199360
active_file 52449439744
unevictable 0
hierarchical_memory_limit 137438953472
hierarchical_memsw_limit 274877906944
total_cache 134325506048
total_rss 695980032
total_mapped_file 16155119616
total_pgpgin 21654116032
total_pgpgout 21705492352
total_swap 655171584
total_inactive_anon 4218880
total_active_anon 74202603520
total_inactive_file 8365199360
total_active_file 52449439744
total_unevictable 0


memory.stat


memory.stat包含有最丰富的

attachments-2020-09-TRRYPU2W5f62fffe6c37e.jpg

active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cache

active_file + inactive_file = cache - size of tmpfs


docker原生内存监控


再来说到docker原生的docker stats。其具体实现在libcontainer中可以看到。其将容器的内存监控分为cache,usage,swap usage,kernel usage,kernel tcp usage。

其中cache是从memory.stat中的cache中获取。

usage是使用memory.usage_in_bytes和memory.limit_in_bytes进行相除来计算使用率。这一方式有一个弊端,就是不够细化,没有区分出cache部分,不能真正反映内存使用率。因为一般来说cache是可以复用的内存部分,因此一般将其计入到可使用的部分。


可以考虑的改进计算方式


改进方式在统计内存使用量时将cache计算排除出去。类似于linux中计算real_used时将buffer和cache排除一样。

cache并不能直接应用memory.stat中的cache,因为其中包括了tmpfs,而tmpfs算是实际使用的内存部分。

tmpfs即share memory,共享内存

因为在memory.stat中存在有

active_file + inactive_file = cache - size of tmpfs

因此可以计算实际使用的内存量为

real_used = memory.usage_in_bytes - (rss + active_file + inactive_file)


attachments-2020-09-zXEDKKln5f62fec80bc0a.jpg

  • 发表于 2020-09-17 14:15
  • 阅读 ( 498 )

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1474 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章