阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker容器内存监控

239次阅读
没有评论

共计 5552 个字符,预计需要花费 14 分钟才能阅读完成。

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 上读出的数据

可以参考这里。http://www.linuxidc.com/Linux/2016-07/132856.htm

为方便说明,我对 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
名称 说明
total_mem 物理内存总量
used_mem 已使用的物理内存量
free_mem 空闲的物理内存量
shared_mem 共享内存量
buffer buffer 所占内存量
cache cache 所占内存量
real_used 实际使用的内存量
real_free 实际空闲的内存量
total_swap swap 总量
used_swap 已使用的 swap
free_swap 空闲的 swap

一般认为,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 监控相关的。

文件名 说明
memory.usage_in_bytes 已使用的内存量(包含 cache 和 buffer)(字节),相当于 linux 的 used_meme
memory.limit_in_bytes 限制的内存总量(字节),相当于 linux 的 total_mem
memory.failcnt 申请内存失败次数计数
memory.memsw.usage_in_bytes 已使用的内存和 swap(字节)
memory.memsw.limit_in_bytes 限制的内存和 swap 容量(字节)
memory.memsw.failcnt 申请内存和 swap 失败次数计数
memory.stat 内存相关状态

以下为一个容器的样例。

[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 包含有最丰富的

统计 描述
cache 页缓存,包括 tmpfs(shmem),单位为字节
rss 匿名和 swap 缓存,不包括 tmpfs(shmem),单位为字节
mapped_file memory-mapped 映射的文件大小,包括 tmpfs(shmem),单位为字节
pgpgin 存入内存中的页数
pgpgout 从内存中读出的页数
swap swap 用量,单位为字节
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 限制,单位为字节

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

可以考虑的改进计算方式

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

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)

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147501.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计5552字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中