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

linux - docker 的 python sdk 如何计算docker 容器的 res 内存使用量?

姬衡
2023-10-03

起了一个 mysql 的 docker 容器

version: "3"services:  mysql8:    container_name: mysql8    image: mysql:8    restart: always    ports:      - "3306:3306"    environment:      - MYSQL_ROOT_PASSWORD=123456    volumes:      - ./volumes/:/var/lib/mysql      - ./my-custom.cnf:/etc/mysql/conf.d/my-custom.cnf

然后使用 htop 看到 mysql8 容器占用的 res 内存是 556MB

图片.png

使用 docker stats 看到的内存使用量是 739.5MB,和 htop 不一致

图片.png

使用 docker 的 python sdk 读取 mysql8 容器的信息

代码如下

from typing import List, Dict, Optionalfrom concurrent.futures.thread import ThreadPoolExecutorimport clickimport dockerfrom rich.console import Consolefrom docker.models.containers import Containerimport jsondef get_container_info(container: Container):    short_id: str = container.short_id    status: str = container.attrs['State']['Status']    name: str = container.attrs['Name']    from docker.models.images import Image    image: Image = container.image    image_name = image.tags[0] if image.tags else image.short_id    container_stats: Dict = container.stats(decode=True).__next__()    print(json.dumps(container_stats,indent=4))client = docker.from_env()container = client.containers.get('c50ca07d3d41')get_container_info(container)

输出内容:

{    "read": "2023-10-03T03:27:20.913142192Z",    "preread": "0001-01-01T00:00:00Z",    "pids_stats": {        "current": 47,        "limit": 33438    },    "blkio_stats": {        "io_service_bytes_recursive": [            {                "major": 259,                "minor": 0,                "op": "read",                "value": 301391872            },            {                "major": 259,                "minor": 0,                "op": "write",                "value": 1556733952            }        ],        "io_serviced_recursive": null,        "io_queue_recursive": null,        "io_service_time_recursive": null,        "io_wait_time_recursive": null,        "io_merged_recursive": null,        "io_time_recursive": null,        "sectors_recursive": null    },    "num_procs": 0,    "storage_stats": {},    "cpu_stats": {        "cpu_usage": {            "total_usage": 114408426000,            "usage_in_kernelmode": 37930579000,            "usage_in_usermode": 76477847000        },        "system_cpu_usage": 105739260000000,        "online_cpus": 16,        "throttling_data": {            "periods": 0,            "throttled_periods": 0,            "throttled_time": 0        }    },    "precpu_stats": {        "cpu_usage": {            "total_usage": 0,            "usage_in_kernelmode": 0,            "usage_in_usermode": 0        },        "throttling_data": {            "periods": 0,            "throttled_periods": 0,            "throttled_time": 0        }    },    "memory_stats": {        "usage": 1346535424,        "stats": {            "active_anon": 4096,            "active_file": 208646144,            "anon": 546168832,            "anon_thp": 0,            "file": 779718656,            "file_dirty": 0,            "file_mapped": 36380672,            "file_writeback": 0,            "inactive_anon": 546164736,            "inactive_file": 571072512,            "kernel_stack": 770048,            "pgactivate": 50248,            "pgdeactivate": 0,            "pgfault": 213604,            "pglazyfree": 0,            "pglazyfreed": 0,            "pgmajfault": 453,            "pgrefill": 0,            "pgscan": 0,            "pgsteal": 0,            "shmem": 0,            "slab": 17898776,            "slab_reclaimable": 17314312,            "slab_unreclaimable": 584464,            "sock": 0,            "thp_collapse_alloc": 0,            "thp_fault_alloc": 0,            "unevictable": 0,            "workingset_activate": 0,            "workingset_nodereclaim": 0,            "workingset_refault": 0        },        "limit": 29296934912    },    "name": "/mysql8",    "id": "c50ca07d3d41b26b9fca21bb90b942919066352c0f1866750afb7f2ab611d5ea",    "networks": {        "eth0": {            "rx_bytes": 169903746,            "rx_packets": 423759,            "rx_errors": 0,            "rx_dropped": 0,            "tx_bytes": 18029112,            "tx_packets": 228139,            "tx_errors": 0,            "tx_dropped": 0        }    }}

可以看到 memory_stats 的 usage 是 1346535424,换算一下就是 1346535424/1024/1024/1024=1.25GB,这个结果和 htop 和 docker stats 都不一样

所以有两个问题:
问题一:看来需要组合计算 memory_stats 下面的 stats 中的某些参数才能获取和 htop 和 docker stats 一致的结果,但是我不知道该用哪些参数
问题二:为什么 htop 和 docker stats 的结果不一样

共有1个答案

孙星鹏
2023-10-03

docker stats 是怎么算出来的,我倒是知道了,参考:docker stats Description

On Linux, the Docker CLI reports memory usage by subtracting cache usage from the total memory usage. The API does not perform such a calculation but rather provides the total memory usage and the amount from the cache so that clients can use the data as needed. The cache usage is defined as the value of total_inactive_file field in the memory.stat file on cgroup v1 hosts.
在 Linux 上,Docker CLI 通过从总内存使用量中减去缓存使用量来报告内存使用量。 API 不执行此类计算,而是提供总内存使用量和缓存量,以便客户端可以根据需要使用数据。缓存使用情况定义为 cgroup v1 主机上 memory.stat 文件中 total_inactive_file 字段的值。

On Docker 19.03 and older, the cache usage was defined as the value of cache field. On cgroup v2 hosts, the cache usage is defined as the value of inactive_file field.
在 Docker 19.03 及更早版本中,缓存使用情况定义为 cache 字段的值。在 cgroup v2 主机上,缓存使用情况定义为 inactive_file 字段的值。

因为我的主机是 cgroupv2 的,所以要想和 docker stats 一样,那就要 usage 减去 inactive_file

float(container_stats['memory_stats']['usage'])-float(container_stats['memory_stats']['stats']['inactive_file'])

至于第二个问题「问题二:为什么 htop 和 docker stats 的结果不一样」,我还得研究研究

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

  • 我正在docker容器中设置一个应用程序。我希望这个应用程序能够与localstack堆栈容器localstack文档连接。当我运行时,容器会成功启动。我可以运行docker-compose文件中未包含的独立java应用程序,它将成功连接到localstack容器。但与localstack一起启动的应用程序无法连接。我看过docker文档和localstack文档,我想不出如何让这些东西彼此通信。

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

  • 我有很多运行docker容器的测试。每个都有一个卷。 如何知道需要删除的卷名? 例如: 手动停止并删除容器后,卷仍然存在。 我不想删除所有卷,因为其中一些卷仍在使用中。

  • 我有一个Java应用程序,基于Java8 OpenJDK。它运行在一个限制为20GB的docker容器中。 tomcat的-xms和-xmx设置如下: -xms=容器内存的60%(由cgroup指定)-so 12gb-xmx=容器内存的80%(由cgroup指定)-so 16gb 通常情况下是使用MaxRAM还是-xmx,还是两者都设置有什么好处? 如果我使用MaxRAM而不是-xmx,java将

  • 我无法用redis数据库中的数据创建docker redis容器的图像。目前,我正在这样做: 很明显,我对一些基本的东西不太了解。docker commit不是从现有容器创建新映像吗? 好吧,我一直在挖掘。hub上的默认redis图像。docker使用一个数据卷,然后将其装入容器中的/data。为了在容器之间共享此卷,必须使用以下参数启动一个新容器: 请注意,参数的顺序很重要,否则docker r