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 利用率的底层实现方式主要为:
- 两次读取
/sys/fs/cgroup/cpuacct/docker/containerID/cpuacct.usage
的值,获取其差值,单位为 ns、记为container_cpu_total_delta
; - 两次读取
/proc/stat
中的cpu
字段的值,获取其差值,单位为tick
,记为system_cpu_usage_delta
; - 将步骤 2 中的
system_cpu_usage_delta
转换为 ns 表示,即system_cpu_usage_delta * nanoSecondsPerSecond / clockTicksPerSecond
,记为system_cpu_total_delta
; - 最后计算容器的 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