在容器宿主机上获取容器 CPU 及内存使用率。
方案一:使用 docker 命令行
示例代码:
docker stats --no-stream $(docker ps --format={{.Names}} | grep ${CONTAINER_NAME}) \
--format "{{.CPUPerc}}:{{.MemPerc}}:{{.MemUsage}}" | head -n 1 | \
while IFS=: read cpu_percent mem_percent mem_usage;
do
echo $mem_usage | while IFS=' / ' read mem_used mem_total
do
# mem_used / mem_total 可能有这几种单位:
# https://github.com/docker/go-units/blob/1364ead0d8e38649c7d8d8920d1eafeaf5064071/size.go#L22
# 但是他们会带一个 B 表示字节,如 7.527MiB 。${mem_used::-1} 去掉最后的 B,使其可以被 numfmt 理解。
mem_used_kb=$(echo ${mem_used::-1} | numfmt --from iec-i --to-unit Ki)
mem_total_kb=$(echo ${mem_total::-1} | numfmt --from iec-i --to-unit Ki)
done
done
方案优点:
- 利用
docker stats
来获取计算好的 CPU / Mem 内存占用,相对方便
方案缺点:
docker stats
输出的数据不够可编程(比如MemUsage
字段输出7.42 MiB / 512 MiB
,仍然需要自己去做解析)- Bash 脚本操纵数据能力差,不得不引入
numfmt
,jo
等工具用来解析单位、生成 JSON 等 - Bash 脚本难写,一个 split string 就写得很别扭,编码、调试时间增加
方案二:使用 Docker Engine API
这个方案使用 Docker Engine API 来获取 docker stats
所展现的数据。
CONTAINER_ID=$(curl -s --unix-socket ${DOCKER_SOCK_PATH} -H "Content-Type: application/json" "http:/v1.24/containers/json?filters=\{\"name\":\[\"${CONTAINER_NAME}\"\]\}" | jq -r ".[0].Names[0][1:]")
STATS_JSON_DATA=$(curl --unix-socket ${DOCKER_SOCK_PATH} -H "Content-Type: application/json" http:/v1.24/containers/${CONTAINER_ID}/stats?stream=false)
STATS_JSON_DATA
便存储了 Docker API 返回的资源占用 JSON 数据(参考)。然后你需要模仿 Docker 命令行的做法(参考),把这些数据计算成我们实际需要的资源占用数据。
方案优点:
- 比直接用 Docker 命令行轻量及快速
方案缺点:
- 难以仅用 Bash 完成所有任务,需要额外写一个 Go 程序来做 JSON 处理和计算
- 未来
docker stats
的计算方法如果改变,可能需要随之变化 - 需要考虑 API 兼容性(参考),比如 Docker 1.12.6 版本对应 Docker API 1.24 版本。你需要收集 TSF 的所有容器运行环境的 Docker 版本,来判断用哪个 API 版本