在运维监控、容器管理平台、云桌面系统等场景中,我们经常需要实时获取 docker 容器的 cpu、内存、网络、磁盘 io 等资源使用情况。本文总结了 5 种常用的 python 实现方式,从最基础到生产可用的方案逐步讲解,帮助你根据实际需求选择最合适的写法。
一、使用docker stats --no-stream最简版(适合快速查看)
# -*- encoding: utf-8 -*-
from subprocess import popen, pipe, stdout
def run_cmd(cmd):
p = popen(cmd, shell=true, stdin=pipe, stdout=pipe, stderr=stdout)
stdout, _ = p.communicate()
return p.returncode, stdout.strip().decode()
if __name__ == "__main__":
cmd = 'docker stats --no-stream' # 获取所有容器
# cmd = 'docker stats 92d1f89c5bb4 --no-stream' # 指定容器
code, out = run_cmd(cmd)
print(out)
输出示例:
container id name cpu % mem usage / limit mem % net i/o block i/o pids
7d0d088b44e6 centos7-novnc2 0.02% 144.2mib / 7.774gib 1.81% 2.44kb / 0b 249mb / 403mb 99
优点:简单直接
缺点:输出是人类可读的表格,不利于程序解析
二、使用--format自定义输出 + 结构化解析(推荐)
# -*- encoding: utf-8 -*-
from subprocess import popen, pipe, stdout
def run_cmd(cmd):
p = popen(cmd, shell=true, stdin=pipe, stdout=pipe, stderr=stdout)
stdout, _ = p.communicate()
return stdout.strip()
if __name__ == "__main__":
cmd = ('docker stats --no-stream --format '
'"{{.blockio}}#{{.cpuperc}}#{{.container}}#{{.id}}#'
'{{.memperc}}#{{.memusage}}#{{.name}}#{{.netio}}#{{.pids}}##"')
result = run_cmd(cmd).decode("utf-8")
container_list = []
for line in result.split("##"):
if not line:
continue
fields = line.split("#")
info = {
'blockio': fields[0],
'cpuperc': fields[1],
'container': fields[2],
'id': fields[3],
'memperc': fields[4],
'memusage': fields[5],
'name': fields[6],
'netio': fields[7],
'pids': fields[8]
}
container_list.append(info)
print(container_list)
输出:
[{'blockio': '249mb / 403mb', 'cpuperc': '0.02%', 'container': 'centos7-novnc2', ...}]
优点:结构化数据、易于转为 json、前后端交互友好
三、使用 subprocess 列表方式(更安全,避免 shell 注入)
from subprocess import popen, pipe
import json
try:
shell = [
'docker', 'stats', 'centos7-novnc2', '--no-stream', '--format',
'{{.blockio}}#{{.cpuperc}}#{{.container}}#{{.id}}#'
'{{.memperc}}#{{.memusage}}#{{.name}}#{{.netio}}#{{.pids}}'
]
p = popen(shell, stdout=pipe, stderr=pipe)
response = {"code": 200, "msg": "success", "data": []}
for line in p.stdout.readlines():
line = line.decode("utf-8").strip()
if not line:
continue
ls = line.split("#")
info = {
'blockio': ls[0], 'cpuperc': ls[1], 'container': ls[2],
'id': ls[3], 'memperc': ls[4], 'memusage': ls[5],
'name': ls[6], 'netio': ls[7], 'pids': ls[8].strip()
}
response["data"].append(info)
except filenotfounderror:
response = {"code": 500, "msg": "docker 未安装"}
print(json.dumps(response, ensure_ascii=false, indent=2))
推荐用于 web 接口返回 json 数据
四、自动生成--format模板的小工具(偷懒神器)
p = {"blockio":"249mb / 403mb","cpuperc":"0.02%","container":"centos7-novnc2",
"id":"7d0d088b44e6","memperc":"1.81%","memusage":"144.2mib / 7.774gib",
"name":"centos7-novnc2","netio":"2.44kb / 0b","pids":"99"}
pd = []
for i, k in enumerate(p.keys()):
pd.append(f"{{{{.{k}}}}}#")
print(f"p.update({{'{k}': ls[{i}]}})")
print("\n生成的 format 字符串:")
print("".join(pd))
运行后自动输出:
docker stats --no-stream --format "{{.blockio}}#{{.cpuperc}}#{{.container}}#..."
以后想加新字段,直接改字典再运行即可
五、持续监控 + 计算平均内存使用率(适合压测报告)
# -*- encoding: utf-8 -*-
from subprocess import popen, pipe, stdout
import time
def get_mem_usage(container_name):
cmd = f'docker stats {container_name} --no-stream'
p = popen(cmd, shell=true, stdout=pipe, stderr=stdout)
output = p.stdout.read().decode("utf-8")
lines = output.strip().split("\n")
if len(lines) < 2:
return 0.0
# 第2行是数据,memperc 在第5列(索引4)
mem_perc = lines[1].split()[4] # 例如: 1.81%
return float(mem_perc.rstrip("%"))
if __name__ == "__main__":
container = "centos7-novnc2"
total = 0.0
count = 120
print("开始监控容器内存使用率(每3秒采样一次,共120次)\n")
for i in range(1, count + 1):
mem = get_mem_usage(container)
total += mem
avg = total / i
print(f"第{i:3d}次 | 当前: {mem:5.2f}% | 累计平均: {avg:.2f}%")
time.sleep(3)
print(f"\n120次采样平均内存使用率:{total/count:.2f}%")
适用于:
- 压测前后资源占用对比
- 自动化报告生成
- 容器资源预警
总结对比
| 方式 | 是否结构化 | 是否安全 | 是否适合生产 | 推荐场景 |
|---|---|---|---|---|
| 直接 shell=true 输出表格 | 否 | 一般 | 调试用 | 快速查看 |
| --format + split("#") | 是 | 推荐 | 强烈推荐 | 前后端、监控系统 |
| subprocess 列表传参 | 是 | 高 | 生产首选 | web api 接口 |
| 自动生成模板脚本 | - | - | 开发辅助 | 快速扩展字段 |
| 循环采样统计平均值 | 是 | 推荐 | 压测/报告 | 性能测试分析 |
到此这篇关于python获取docker容器实时资源占用(cpu、内存、io等)5种实现方式的文章就介绍到这了,更多相关python获取docker容器资源占用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论