以百分比形式获取 Docker 容器 CPU 使用率

Posted

技术标签:

【中文标题】以百分比形式获取 Docker 容器 CPU 使用率【英文标题】:Get Docker Container CPU Usage as Percentage 【发布时间】:2015-07-28 02:41:52 【问题描述】:

Docker 提供了一个交互式统计命令docker stats [cid],它提供了有关 CPU 使用情况的最新信息,如下所示:

CONTAINER      CPU %          MEM USAGE/LIMIT       MEM %       NET I/O
36e8a65d       0.03%          4.086 MiB/7.798 GiB   0.05%       281.3 MiB/288.3 MiB

我正在尝试以易于理解的格式获取 CPU 使用率的百分比以进行一些分析。

我已经看到 /sys/fs 中的统计信息似乎提供了与 Docker Remote API 相似的值,它给了我这个 JSON blob:


    "cpu_usage": 
        "usage_in_usermode": 345230000000, 
        "total_usage": 430576697133, 
        "percpu_usage": [
            112999686856, 
            106377031910, 
            113291361597, 
            97908616770
        ], 
        "usage_in_kernelmode": 80670000000
    , 
    "system_cpu_usage": 440576670000000, 
    "throttling_data": 
        "throttled_time": 0, 
        "periods": 0, 
        "throttled_periods": 0
    

但我不确定如何从中获得准确的 CPU 使用率百分比。

有什么想法吗?

【问题讨论】:

上例中你的值不是百分比还是我有什么问题? 他的意思是他如何从 api 中获取百分比,与 docker 客户端显示的方式相同 【参考方案1】:

如果你打算使用 Stats API 调用 - 你可以看看 docker 客户端是如何做到的:https://github.com/docker/docker/blob/eb131c5383db8cac633919f82abad86c99bffbe5/cli/command/container/stats_helpers.go#L175-L188

func calculateCPUPercent(previousCPU, previousSystem uint64, v *types.StatsJSON) float64 
    var (
        cpuPercent = 0.0
        // calculate the change for the cpu usage of the container in between readings
        cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU)
        // calculate the change for the entire system between readings
        systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem)
    )

    if systemDelta > 0.0 && cpuDelta > 0.0 
        cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0
    
    return cpuPercent

基本上,您获取一个参考点,然后查看 10 秒内的差异,然后您就可以知道容器使用了多少时间。比如说,我们从容器的 0 SystemCPUUsage 和 0 CPUUsage 开始。如果 10 秒后,我们有 10 个 SystemCPUUsage 和 1 个 CPUUsage,那么我们有 10% 的使用率。在 API 中,您只会以纳秒而不是秒为单位给出结果。实际时间并不重要,重要的是 SystemCPUUsage 的总变化,然后将 CPUUSage 与之比较。

【讨论】:

以上链接已损坏。在以下位置找到它:github.com/docker/docker/blob/… 值得注意的是,v.CPUStats.CPUUsage.PercpuUsage 是一个包含所有 CPU 内核使用情况的数组。不幸的是,如果内核未使用,它会返回值 0。这意味着如果 docker 列出未使用的核心,则百分比将出现偏差。当我的百分比没有加起来时,我很难发现这一点。此外,cpu_stats.online_cpus 在 API 的较新版本中可用,因此您可以直接使用它。【参考方案2】:

在我们使用远程 api 后,我们得到以下字段:precpu_stats/cpu_stats

然后,基本上这里是代码:(javascript示例)

var res <---- remote api response

var cpuDelta = res.cpu_stats.cpu_usage.total_usage -  res.precpu_stats.cpu_usage.total_usage;
var systemDelta = res.cpu_stats.system_cpu_usage - res.precpu_stats.system_cpu_usage;
var RESULT_CPU_USAGE = cpuDelta / systemDelta * 100;

只是为了澄清 RESULT_CPU_USAGE...这是从您的物理硬件消耗的资源量,因此假设您的 RESULT_CPU_USAGE50%,这意味着 50% 的所有 PC 电源都被容器 X 使用了

【讨论】:

您的计算没有考虑 CPU 数量。 我认为将结果乘以 CPU 的数量没有多大意义。我的意思是……我的笔记本有 4 个核心,如果我从 docker 容器中对这些核心施加压力,然后从外部运行docker stats……我会得到大约 400% 的 cpu 使用率。如果我正在监控一个 docker 主机,我宁愿有一个从 0% 到 100% 的范围 这个cpu使用百分比似乎是一秒。有没有办法让容器在一分钟内使用的平均 cpu 而不会每分钟调用 60 次这个 api 调用? 有人计算正确吗?这个答案不正确。 @user3241084 由Michael 给出的答案给出了正确的计算。我已经验证结果类似于 docker stats CLI 的输出【参考方案3】:

所以我也需要这个,下面给出了正确的 CPU 使用率,包括核心数量。

var cpuDelta = metric.cpu_stats.cpu_usage.total_usage -  metric.precpu_stats.cpu_usage.total_usage;
var systemDelta = metric.cpu_stats.system_cpu_usage - metric.precpu_stats.system_cpu_usage;
var RESULT_CPU_USAGE = cpuDelta / systemDelta * metric.cpu_stats.cpu_usage.percpu_usage.length * 100;

console.log(RESULT_CPU_USAGE);

【讨论】:

以上是关于以百分比形式获取 Docker 容器 CPU 使用率的主要内容,如果未能解决你的问题,请参考以下文章

在 Grafana 中为 Docker 容器构建 CPU 使用率图

如何获取在docker容器中运行的tomcat的CPU使用率[关闭]

怎么让Docker容器在后台以守护态形式运行

如何在 JMeter 中测量 Docker 容器 CPU 和内存并将其与其他 Docker 容器进行比较

Docker资源控制

Docker-数据卷以直接命令和Dockerfile的形式添加,数据卷容器的概念及容器间继承实现