docker stats 命令统计CPU利用率的底层实现

2021-08-21  本文已影响0人  Jamza

命令简介

在容器的使用过程中,可以通过 docker stats 命令,及时查看容器使用的系统资源情况,默认情况下,docker stats 命令会间隔 1 秒钟刷新一次输出的容器系统资源使用情况数据。命令输出的主要内容包括容器 ID、CPU 使用率、内存使用率、网络 IO、磁盘 IO 等信息。

比如,某个输出实例为:

[root@vm_rp0_cpu0_docker ~]# docker stats
CONTAINER           CPU %               MEM USAGE / LIMIT      MEM %               NET I/O             BLOCK I/O           PIDS
9c5b90413b6b        0.00%               3.711 MiB / 2.71 GiB   0.13%               0 B / 0 B           99.4 MB / 360 kB    9

命令统计 CPU 利用率的底层实现

docker stats 命令统计 CPU 利用率的底层实现方式主要为:

  1. 两次读取 /sys/fs/cgroup/cpuacct/docker/containerID/cpuacct.usage 的值,获取其差值,单位为 ns、记为 container_cpu_total_delta
  2. 两次读取 /proc/stat 中的 cpu 字段的值,获取其差值,单位为 tick,记为 system_cpu_usage_delta
  3. 将步骤 2 中的 system_cpu_usage_delta 转换为 ns 表示,即 system_cpu_usage_delta * nanoSecondsPerSecond / clockTicksPerSecond,记为 system_cpu_total_delta
  4. 最后计算容器的 CPU 利用率,即 CPU_percent = container_cpu_total_delta / system_cpu_total_delta * getNumberOnlineCPUs,其中 getNumberOnlineCPUs 为系统的核数。至于为什么需要使用该值,可参考 https://github.com/moby/moby/issues/13626 中的说明。

根据以上的原理,可以整理为 shell 脚本,如下:

#!/bin/sh

while [ 1 ]
do
    CPU_TOTAL_ONE=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
    CPU_TOTAL_ONE_SUM=$(echo $CPU_TOTAL_ONE | awk '{print $1+$2+$3+$4+$5+$6+$7}')
    CONTAINER_USE_1=$(cat /sys/fs/cgroup/cpuacct/docker/contaienrdID/cpuacct.usage) 
    sleep 1
    CPU_TOTAL_TWO=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
    CPU_TOTAL_TWO_SUM=$(echo $CPU_TOTAL_TWO | awk '{print $1+$2+$3+$4+$5+$6+$7}')
    CONTAINER_USE_2=$(cat /sys/fs/cgroup/cpuacct/docker/contaienrdID/cpuacct.usage)
    CGROUP_USAGE=`expr $CONTAINER_USE_2 - $CONTAINER_USE_1`
    SYSTEM_TOTAL_DELTA=`expr $CPU_TOTAL_TWO_SUM - $CPU_TOTAL_ONE_SUM`
    CPU_PERCENT_RESULT=`expr $CGROUP_USAGE*4/$SYSTEM_TOTAL_DELTA/10000000*100|bc -l`   
    #clockTicksPerSecond=100, 4核, 核数根据实际情况调整
    #clockTicksPerSecond 可以使用clockTicksPerSecond = uint64(system.GetClockTicks())获取,一般为100
    echo  $CPU_PERCENT_RESULT
done
上一篇下一篇

猜你喜欢

热点阅读