如何获取Kubernetes Pod的单核心CPU使用统计(类mpstat效果)
如何获取Kubernetes Pod的单核心CPU使用统计(类mpstat效果)
我完全懂你的痛点——给容器分配了2.5核CPU限制,在容器里跑mpstat却直接显示宿主机的16核数据,kubectl top和常规Prometheus指标又只能看整体CPU使用率,根本看不到像宿主机mpstat那样的单核心详细统计对吧?下面几个实用方法可以帮你解决这个问题:
方法1:调整mpstat参数,只统计容器允许使用的CPU核心
容器的CPU亲和性/可用核心是通过cgroup的cpuset控制的,你可以先拿到容器被允许使用的CPU列表,再让mpstat只针对这些核心输出统计:
- 先在容器内执行以下命令,获取允许使用的CPU核心:
输出类似cat /sys/fs/cgroup/cpuset/cpuset.cpus0-2或者0,2,3这样的格式。 - 把这个结果传给mpstat的
-P参数,就能只统计容器可用核心的情况:
这里mpstat -P $(cat /sys/fs/cgroup/cpuset/cpuset.cpus) 1 101 10表示每1秒统计一次,共统计10次,和你在宿主机上用的mpstat参数逻辑一致。
注意:如果你的容器用的是CPU份额限制(比如2500m,也就是2.5核)而不是绑定特定核心,那么
cpuset.cpus可能会显示宿主机所有核心。这种情况下,这个方法就不太适用,得看下面的方法。
方法2:利用Prometheus + cAdvisor的细分CPU指标
其实Prometheus的container_cpu_usage_seconds_total指标是带有cpu标签的,这个标签对应宿主机的每个CPU核心,你可以通过PromQL查询来提取单个Pod/容器的单核心使用率:
- 查询每个核心的总CPU使用率(百分比):
rate(container_cpu_usage_seconds_total{pod="你的Pod名称", container="你的容器名称"}[1m]) by (cpu) * 100 - 如果需要拆分用户态、系统态的使用率(和mpstat的%usr、%sys对应),可以分别查询:
这些指标是cAdvisor自动采集的,只要你的集群里部署了cAdvisor(大多数K8s集群默认都有)就能用。# 用户态使用率 rate(container_cpu_user_seconds_total{pod="你的Pod名称", container="你的容器名称"}[1m]) by (cpu) * 100 # 系统态使用率 rate(container_cpu_system_seconds_total{pod="你的Pod名称", container="你的容器名称"}[1m]) by (cpu) * 100
方法3:在容器内使用perf工具(需要权限)
如果需要更底层的单核心统计,可以用perf工具,但容器默认没有这个工具,而且需要额外权限:
- 先在容器里安装perf(比如基于Debian的镜像用
apt install linux-tools-common linux-tools-generic)。 - 运行容器时需要添加性能监控权限:
或者临时用特权模式(生产环境不推荐):# 在Pod的container字段里添加 securityContext: capabilities: add: ["PERFMON"]kubectl exec -it your-pod --privileged -- bash - 然后执行perf命令查看单核心统计:
# 每秒输出一次所有允许使用的核心的CPU时钟统计 perf stat -a -e cpu-clock -I 1000 -C $(cat /sys/fs/cgroup/cpuset/cpuset.cpus)
方法4:自定义脚本解析/proc/stat数据
如果不想依赖外部工具,你可以写个简单的脚本,通过解析容器内的/proc/stat文件来计算单核心使用率,逻辑和mpstat类似:
比如下面这个简单的bash脚本(只计算总使用率):
#!/bin/bash # 获取容器允许的CPU核心 CPUS=$(cat /sys/fs/cgroup/cpuset/cpuset.cpus | tr ',' '\n') # 第一次读取CPU数据 read -r -a PREV < <(grep -E "^cpu($CPUS)" /proc/stat | awk '{print $2+$3+$4+$5+$6+$7+$8}') sleep 1 # 第二次读取CPU数据 read -r -a CURR < <(grep -E "^cpu($CPUS)" /proc/stat | awk '{print $2+$3+$4+$5+$6+$7+$8}') # 计算使用率 for i in "${!PREV[@]}"; do DIFF=$((CURR[i] - PREV[i])) USAGE=$((DIFF * 100 / 100)) # 因为sleep了1秒,总时间是100个jiffies(默认) echo "cpu${i}: ${USAGE}%" done
把脚本放到容器里执行,就能得到类似mpstat的单核心使用率结果。
备注:内容来源于stack exchange,提问作者Vishal Raghavan
相关产品推荐
相关产品推荐

