Python 获取 Docker 容器实时资源占用(CPU、内存、IO等)多种实现方式详解
在运维监控、容器管理平台、云桌面系统等场景中,我们经常需要实时获取 Docker 容器的 CPU、内存、网络、磁盘 IO 等资源使用情况。本文总结了 5 种常用的 Python 实现方式,从最基础到生产可用的方案逐步讲解,帮助你根据实际需求选择最合适的写法。
一、使用 docker stats --no-stream 最简版(适合快速查看)
python
# -*- 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 自定义输出 + 结构化解析(推荐)
python
# -*- 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)
输出:
python
[{'BlockIO': '249MB / 403MB', 'CPUPerc': '0.02%', 'Container': 'centos7-novnc2', ...}]
优点:结构化数据、易于转为 JSON、前后端交互友好
三、使用 subprocess 列表方式(更安全,避免 shell 注入)
python
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 模板的小工具(偷懒神器)
python
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))
运行后自动输出:
bash
docker stats --no-stream --format "{{.BlockIO}}#{{.CPUPerc}}#{{.Container}}#..."
以后想加新字段,直接改字典再运行即可
五、持续监控 + 计算平均内存使用率(适合压测报告)
python
# -*- 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 接口 |
| 自动生成模板脚本 | - | - | 开发辅助 | 快速扩展字段 |
| 循环采样统计平均值 | 是 | 推荐 | 压测/报告 | 性能测试分析 |
希望这篇文章能帮你在实际项目中快速实现 Docker 容器资源监控功能!喜欢记得点赞 + 收藏 ~