当前位置: 首页 > 知识库问答 >
问题:

内存使用差异:cgroup Memory.usage_in_bytes与docker容器内部的RSS

潘阳舒
2023-03-14

“Kubernetes”(v1.10.2)说我的pod(包含一个容器)使用了大约5GB的内存。在容器内部,RSS更像是681MIB。anypony能否解释如何使用以下数据从681MIB到5GB(或者描述如何使用我省略的另一个命令来弥补差异,或者来自容器,或者来自在kubernetes中运行该容器的docker主机)?

kubectl top pods显示为5GB:

% kubectl top pods -l app=myapp
NAME                             CPU(cores)   MEMORY(bytes)
myapp-56b947bf6d-2lcr7           39m          5039Mi

Cadvisor报告了一个相似的数字(可能是来自一个稍微不同的时间,所以请忽略小的差异):

container_memory_usage_bytes{pod_name=~".*myapp.*"}      5309456384

5309456384 / 1024.0 / 1024 ~= 5063 ~= 5039

在容器中,这个文件似乎是cadvisor获取其数据的地方:

% kubectl exec -it myapp-56b947bf6d-2lcr7 bash
meme@myapp-56b947bf6d-2lcr7:/app# cat /sys/fs/cgroup/memory/memory.usage_in_bytes
5309456384

容器内的驻留集大小(RSS)不匹配(小于1GB):

meme@myapp-56b947bf6d-2lcr7:/app# kb=$(ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk | grep -v RSS | awk '{print $6}' | awk '{s+=$1} END {printf "%.0f", s}'); mb=$(expr $kb / 1024); printf "Kb: $kb\nMb: $mb\n"
Kb: 698076
Mb: 681

在有用的情况下,满ps aux:

meme@myapp-56b947bf6d-2lcr7:/app# ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
meme         1  0.0  0.0 151840 10984 ?        Ss   Jun04   0:29 /usr/sbin/apache2 -D FOREGROUND
www-data    10  0.0  0.0 147340  4652 ?        S    Jun04   0:00 /usr/sbin/apache2 -D FOREGROUND
www-data    11  0.0  0.0 148556  4392 ?        S    Jun04   0:16 /usr/sbin/apache2 -D FOREGROUND
www-data    12  0.2  0.0 2080632 11348 ?       Sl   Jun04  31:58 /usr/sbin/apache2 -D FOREGROUND
www-data    13  0.1  0.0 2080384 10980 ?       Sl   Jun04  18:12 /usr/sbin/apache2 -D FOREGROUND
www-data    68  0.3  0.0 349048 94272 ?        Sl   Jun04  47:09 hotapp
www-data   176  0.2  0.0 349624 92888 ?        Sl   Jun04  43:11 hotapp
www-data   179  0.2  0.0 349196 94456 ?        Sl   Jun04  42:20 hotapp
www-data   180  0.3  0.0 349828 95112 ?        Sl   Jun04  44:14 hotapp
www-data   185  0.3  0.0 346644 91948 ?        Sl   Jun04  43:49 hotapp
www-data   186  0.3  0.0 346208 91568 ?        Sl   Jun04  44:27 hotapp
www-data   189  0.2  0.0 350208 95476 ?        Sl   Jun04  41:47 hotapp

Docker的容器状态API中的内存部分:

curl --unix-socket /var/run/docker.sock 'http:/v1.24/containers/a45fc651e7b12f527b677e6a46e2902786bee6620484922016a135e317a42b4e/stats?stream=false' | jq . # yields:

"memory_stats": {
  "usage": 5327712256,
  "max_usage": 5368344576,
  "stats": {
    "active_anon": 609095680,
    "active_file": 74457088,
    "cache": 109944832,
    "dirty": 28672,
    "hierarchical_memory_limit": 5368709120,
    "inactive_anon": 1687552,
    "inactive_file": 29974528,
    "mapped_file": 1675264,
    "pgfault": 295316278,
    "pgmajfault": 77,
    "pgpgin": 85138921,
    "pgpgout": 84964308,
    "rss": 605270016,
    "rss_huge": 0,
    "shmem": 5513216,
    "total_active_anon": 609095680,
    "total_active_file": 74457088,
    "total_cache": 109944832,
    "total_dirty": 28672,
    "total_inactive_anon": 1687552,
    "total_inactive_file": 29974528,
    "total_mapped_file": 1675264,
    "total_pgfault": 295316278,
    "total_pgmajfault": 77,
    "total_pgpgin": 85138921,
    "total_pgpgout": 84964308,
    "total_rss": 605270016,
    "total_rss_huge": 0,
    "total_shmem": 5513216,
    "total_unevictable": 0,
    "total_writeback": 0,
    "unevictable": 0,
    "writeback": 0
  },
  "limit": 5368709120
},

对https://github.com/google/cadvisor/issues/638的评论断言:

总计(memory.usage_in_bytes)=rss+缓存

https://www.cernel.org/doc/documentation/cgroup-v1/memory.txt说:

usage_in_bytes:为了效率,与其他内核组件一样,memory cgroup使用一些优化来避免不必要的缓存线错误共享。usage_in_bytes受方法的影响,不显示内存(和交换)使用的“确切”值,它是一个有效访问的模糊值。(当然,必要时,它是同步的。)如果希望了解更确切的内存使用情况,应该在memory.stat中使用rss+cache(+swap)值(参见5.2)。

https://docs.docker.com/engine/reference/commandline/stats/#parent-命令显示:

注意:在Linux上,Docker CLI通过从总内存使用量中减去页面缓存使用量来报告内存使用量。API不执行这样的计算,而是提供总内存使用量和页面缓存的数量,以便客户机可以根据需要使用数据。

事实上,容器中的/sys/fs/cgroup/memory/memory.stat中的大部分内容都显示在上面的docker stats api响应中(与在不同时间获取样本有细微区别,抱歉):

meme@myapp-56b947bf6d-2lcr7:/app# cat /sys/fs/cgroup/memory/memory.stat
cache 119492608
rss 607436800
rss_huge 0
shmem 5525504
mapped_file 1675264
dirty 69632
writeback 0
pgpgin 85573974
pgpgout 85396501
pgfault 296366011
pgmajfault 80
inactive_anon 1687552
active_anon 611213312
inactive_file 32800768
active_file 81166336
unevictable 0
hierarchical_memory_limit 5368709120
total_cache 119492608
total_rss 607436800
total_rss_huge 0
total_shmem 5525504
total_mapped_file 1675264
total_dirty 69632
total_writeback 0
total_pgpgin 85573974
total_pgpgout 85396501
total_pgfault 296366011
total_pgmajfault 80
total_inactive_anon 1687552
total_active_anon 611213312
total_inactive_file 32800768
total_active_file 81166336
total_unevictable 0

来自Kubectl Description pod 的内存信息:

Limits:
  memory:  5Gi
Requests:
  memory:   4Gi

以下是pmap在容器中的内容。在这个单行程序中,我获取所有进程ID,对它们运行pmap-x,并从pmap结果中提取Kbytes列。总的结果是256兆字节(比PS的RSS少得多,我想部分是因为许多进程没有从pmap-x返回输出):

ps aux | awk '{print $2}' | grep -v PID | xargs sudo pmap -x | grep total | grep -v grep | awk '{print $3}' | awk '{s+=$1} END {printf "%.0f", s}'; echo
256820

ps_mem.py在https://stackoverflow.com/A/133444/6090676中提到。它检查/proc/$pid/statm/proc/$pid/smaps。这里没有说明(同样,它似乎忽略了一些过程):

# python ps_mem.py
Private  +   Shared  =  RAM used    Program

  1.7 MiB +   1.0 MiB =   2.7 MiB   apache2
  2.0 MiB +   1.0 MiB =   3.0 MiB   bash (3)
---------------------------------
                          5.7 MiB
=================================

还有一个与此类似的问题(但信息较少)是由cadvisor错误报告容器内存使用情况。谢谢!

共有2个答案

郎经纶
2023-03-14

看起来它使用的是VSZ,虚拟内存大小,而不是RSS。Kubernetes看到了这一点:

% kubectl top pods -l app=myapp
NAME                             CPU(cores)   MEMORY(bytes)
myapp-7b4b4f84f8-fxbns           39m          7136Mi

容器内的ps在对第5列(VSZ)求和时表示:

meme@myapp-7b4b4f84f8-fxbns:/app# kb=$(ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk | grep -v RSS | awk '{print $5}' | awk '{s+=$1} END {printf "%.0f", s}'); mb=$(expr $kb / 1024); printf "Kb: $kb\nMb: $mb\n"
Kb: 7032172
Mb: 6867

VSZ在7GB附近(不完全匹配,但很接近),而RSS显示为665MB,所以这使我相信Kubernetes和/sys/fs/cgroup/memory/memory.usage_in_bytes使用的是VSZ线上的东西,至少在本例中是这样。

楚俊逸
2023-03-14

有一件事我没有看到你检查这里是内核内存。这在memory.usage_in_bytes图中也有说明,但在memory.stat中没有出现。您可以查看/sys/fs/cgroup/memory/memory.kmem.usage_in_bytes

我曾经在我们的一个.NET核心应用程序中看到过类似的情况,但我不知道到底发生了什么(可能是.NET核心中的内存泄漏,因为它是我们的应用程序无法控制的非托管内存)。

也许这是另一个面包屑给你。这将取决于您的应用程序是否正常使用,但就cgroups而言,我相信默认情况下内核内存使用是不受限制的。

 类似资料:
  • 问题内容: 我面临以下问题:我创建了一个Jenkins Docker容器,并将主机上的Docker套接字与该容器链接。像这样: 然后,当我尝试在詹金斯上创建一些作业时,我收到通常的“权限被拒绝”消息: 尝试在unix:///var/run/docker.sock上连接到Docker守护程序套接字时获得的权限被拒绝:获取 http://%2Fvar%2Frun%2Fdocker.sock/v1.29

  • 问题内容: 我有1个进程写入docker容器中共享内存的特定部分(即“ / falcon”)。 Docker映像:dockersharedmemory / shmclient 我有另一个进程,它最初在另一个Docker容器中每秒创建和读取共享内存的同一部分(即“ / falcon”)。 Docker映像:dockersharedmemory / shmserver 使用以下命令运行两个容器时,我可

  • 我经常听说,与在线程之间访问进程内存相比,在进程之间访问共享内存段没有性能损失。换句话说,多线程应用程序不会比使用共享内存的一组进程快(不包括锁定或其他同步问题)。 但我有我的怀疑: 1)shmat()将本地进程虚拟内存映射到共享段。这种转换必须为每个共享内存地址执行,并且可能表示一个很大的开销。在多线程应用程序中,不需要额外的转换:所有VM地址都转换为物理地址,就像在不访问共享内存的常规进程中一

  • 问题内容: 我注意到人们在1:1的比较中涵盖了某些显示属性的细节,但是在说明差异时还没有涉及很多。可能有人解释各种inline-之间的差异 的东西 显示标签? 对w3schools之类的地方进行更详细的定义会产生奇迹。 问题答案: 对于任何具有块和内联变体的显示类型,唯一的区别是,该显示类型具有以内联方式放置的框(即,[以内联格式设置的上下文),而另一种具有格式化为块级框的框,这取决于大多数情况。

  • 问题内容: 带有 Windows的Docker桌面的Docker Windows容器是否具有默认内存限制?我有一个在容器中运行时崩溃的应用程序,但是当我尝试为命令指定参数时,它似乎运行良好。至少在以前崩溃的情况下。这给我的印象是有默认的内存限制,但是我在文档中找不到它。所以我的问题是是否存在内存限制,并且是否在记录的地方? 问题答案: 根据关于Windows的Docker Github问题的讨论(

  • 问题内容: 我有一个Wordpress / MySQL docker容器,用于开发主题和插件。我在localhost:8000上访问它。 它使用了Gulp构建过程,我正在尝试将browsersync添加到组合中。我很难让browsersync真正代理出容器。从Gulp输出中,我可以看到它正在生成更改,只是实际上并未在浏览器中进行任何更改。 这是我的docker-compose.yml,gulpfi