容器实战高手课
李程远
eBay 总监级工程师,云平台架构师
24647 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
容器实战高手课
15
15
1.0x
00:00/00:00
登录|注册

06 | 容器CPU(2):如何正确地拿到容器CPU的开销?

计算各项CPU使用率的百分比值
通过/proc/stat文件获取系统各项CPU使用率的ticks值
计算进程CPU使用率的百分比值
通过/proc/[pid]/stat文件获取进程的用户态和内核态ticks数目
编写一个小程序,在容器中执行,显示当前容器中所有进程总的CPU使用率
单个容器CPU使用率=((utime_2 – utime_1) + (stime_2 – stime_1)) * 100.0 / (HZ * et * 1 )
通过CPU Cgroup每个控制组里的cpuacct.stat文件获取单个容器的CPU使用率
系统CPU使用率
进程CPU使用率
top命令只显示宿主机系统整体的CPU使用率
容器中运行top命令无法得到容器中总的CPU使用率
CPU开销异常是程序异常的明显指标
容器监控的需求
思考题
解决问题
进程CPU使用率和系统CPU使用率
问题重现
为什么要解决这个问题
如何正确地拿到容器CPU的开销

该思维导图由 AI 生成,仅供参考

你好,我是程远。今天我们聊一聊,如何正确地拿到容器 CPU 的开销。
为啥要解决这个问题呢,还是来源于实际工作中的需要。
无论是容器的所有者还是容器平台的管理者,我们想要精准地对运行着众多容器的云平台做监控,快速排查例如应用的处理能力下降,节点负载过高等问题,就绕不开容器 CPU 开销。因为 CPU 开销的异常,往往是程序异常最明显的一个指标。
在一台物理机器或者虚拟机里,如果你想得到这个节点的 CPU 使用率,最常用的命令就是 top 了吧?top 一下子就能看到整个节点当前的 CPU 使用情况。
那么在容器里,top 命令也可以做到这点吗?想要知道答案,我们还是得实际动手试一试。

问题重现

实际上,你在使用容器的时候,如果运行 top 命令来查看当前容器总共使用了多少 CPU,你肯定马上就会失望了。
这是因为我们在容器中运行 top 命令,虽然可以看到容器中每个进程的 CPU 使用率,但是 top 中"%Cpu(s)"那一行中显示的数值,并不是这个容器的 CPU 整体使用率,而是容器宿主机的 CPU 使用率。
就像下面的这个例子,我们在一个 12 个 CPU 的宿主机上,启动一个容器,然后在容器里运行 top 命令。
这时我们可以看到,容器里有两个进程 threads-cpu,总共消耗了 200% 的 CPU(2 CPU Usage),而"%Cpu(s)"那一行的"us cpu"是 58.5%。对于 12CPU 的系统来说,12 * 58.5%=7.02,也就是说这里显示总共消耗了 7 个 CPU,远远大于容器中 2 个 CPU 的消耗。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了在容器环境下准确获取CPU开销的方法。首先指出使用top命令无法准确获取容器整体的CPU使用率,因为top命令显示的是宿主机的CPU使用率。文章详细介绍了Linux中计算单个进程CPU使用率的原理,包括utime和stime的含义,ticks的概念以及计算进程CPU使用率的公式。作者通过实际验证证实了自己推导的公式可以准确计算进程的CPU使用率。对于系统整体的CPU使用率计算方法也进行了详细解释,包括如何从/proc/stat文件中获取数据并计算CPU使用率。文章还介绍了在容器中获取整个容器的CPU使用率的方法,通过读取CPU Cgroup每个控制组里的统计文件cpuacct.stat来计算。最后,文章提出了一个思考题,鼓励读者写一个小程序,在容器中执行,可以显示当前容器中所有进程总的CPU使用率。总的来说,本文提供了深入的技术解析和实用的计算方法,对需要在容器环境下准确监控CPU开销的读者来说具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《容器实战高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(17)

  • 最新
  • 精选
  • 上邪忘川
    随便写了一个,比较粗糙 #!/bin/bash cpuinfo1=$(cat /sys/fs/cgroup/cpu,cpuacct/cpuacct.stat) utime1=$(echo $cpuinfo1|awk '{print $2}') stime1=$(echo $cpuinfo1|awk '{print $4}') sleep 1 cpuinfo2=$(cat /sys/fs/cgroup/cpu,cpuacct/cpuacct.stat) utime2=$(echo $cpuinfo2|awk '{print $2}') stime2=$(echo $cpuinfo2|awk '{print $4}') cpus=$((utime2+stime2-utime1-stime1)) echo "${cpus}%"

    作者回复: 赞!

    2020-11-29
    4
    24
  • Geek2014
    多谢老师的分享,之前想去搞明白进程CPU时间的计算,一直没有去花时间研究,今天终于透彻地明白了。 我有个问题不太明白,想请教下,容器运行时比如docker,在做容器化的时候,有没有办法构造出一个和物理机一样的proc文件系统呢?这样的话,容器环境和虚拟机也没啥差别了,物理机上的应用也可以无障碍运行在容器环境中。

    作者回复: 很高兴,这篇文章对你有帮助。 https://github.com/lxc/lxcfs, lxcfs可以为每个容器虚拟一些/proc下的文件,比如/proc/stat

    2020-11-27
    20
  • 东方奇骥
    老师,ticks 1s中是100次,这个怎么查呢?

    作者回复: USER_HZ, 可以用命令 "getconf CLK_TCK"拿

    2020-11-27
    16
  • 蒋悦
    老师您好, 我有一个问题。根据我的理解,容器的cpu使用就必须要在容器内进行,从宿主机是无法计算的,是这样吗?如果是的,那么,这个监控cpu的代码就需要侵入程序代码(容器中跑的业务代码),这会不会有些无奈啊?另外,这个侵入的代码,所在的线程如果不能被实时调度,则瞬时速度就算的不准确了吧? 望解答。

    作者回复: @蒋悦 > 容器的cpu使用就必须要在容器内进行,从宿主机是无法计算的,是这样吗? 不是这样的,从宿主机也可以得到容器对应的CPU Cgroup里的值。

    2020-11-27
    8
  • 争光 Alan
    老师,非常感谢,之前都是模糊知道大概这个意思,这次明白了 另外有个问题: 我当然做监控的时候发现docker stats 和cadvisor(或通过cgroup直接计算)通过cgroup拿到的cpu使用率,内存使用率都是不一样的,您这边知道根本的原因吗?

    作者回复: @争光 Alan 你是指 cpu/memory 使用率在分别在docker stats 和cadvisor里是不一样的? 我们用cadvisor, 看到的结果大致和cgroup差不多,docker stats也是通过cgroup计算的。 你看到的差异有多大?或者你看到的结果,和你自己通过cgroup里的值计算比较一下,哪个更加接近一些?

    2020-12-02
    3
    4
  • 路一直在
    老师,如果计算容器整体的cpu使用率,使用cpuacct.stat是否完整,因为cpuacct.stat中只有us和sys的ticks,其他的类似iowait、idle等的ticks不用计算吗?

    作者回复: 其他的cpu usage, 如io/hi/si等更多的是从宿主机角度统计的,也不能知道这些开销是属于哪个进程的,也就很难放到每一个cgroup里。

    2021-08-04
    2
    3
  • 水蒸蛋
    老师,/sys/fs/cgroup/cpu 和 cpuacc,这2个有什么区别 还有这个获取容器中是获取容器的CPU使用,宿主机是获取宿主机的CPU使用吗

    作者回复: 这两个目录是一样的, lrwxrwxrwx 1 root root 11 Dec 14 23:51 cpu -> cpu,cpuacct lrwxrwxrwx 1 root root 11 Dec 14 23:51 cpuacct -> cpu,cpuacct dr-xr-xr-x 5 root root 0 Dec 14 23:51 cpu,cpuacct

    2020-12-15
    2
  • 笃定
    老师问一下,像Prometheus或者k8s自己的metrics server获取到的pod各个资源使用率(cpu men net io)也是这样通过查看进程/proc来计算得出的吗?如果是这样的话,指标数据太多,运算太大会不会也会消耗节点资源呢

    作者回复: cAdvisor就是通过读取sys cgroup 或者 /proc下的状态信息来得到container cpu/mem/net/io metrics的。 一般一个节点上的container数量是小于1000的,metrics获取的周期在10s 的情况下, 这个资源消耗不会很大。

    2021-03-27
    1
  • GCC?
    老师,在k8s集群中,使用metrics查看到整个pod的资源用量,这个粒度已经够了吧?我的理解是如果pod内不是单一容器,或者容器内有多个进程,这个时候才应该考虑进程级的cpu用量。

    作者回复: 是的。

    2020-12-02
    2
    1
  • 李兵
    老师,如已经是高负载的情况下。应该会有很多正常的进程被安排在D进程中,如何区分造成高负载的D进程呢?

    作者回复: 如果是单纯的高计算的进程,状态多为R.

    2021-07-22
收起评论
显示
设置
留言
17
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部