Python獲取Docker容器實(shí)時(shí)資源占用(CPU、內(nèi)存、IO等)5種實(shí)現(xiàn)方式
在運(yùn)維監(jiān)控、容器管理平臺、云桌面系統(tǒng)等場景中,我們經(jīng)常需要實(shí)時(shí)獲取 Docker 容器的 CPU、內(nèi)存、網(wǎng)絡(luò)、磁盤 IO 等資源使用情況。本文總結(jié)了 5 種常用的 Python 實(shí)現(xiàn)方式,從最基礎(chǔ)到生產(chǎn)可用的方案逐步講解,幫助你根據(jù)實(shí)際需求選擇最合適的寫法。
一、使用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
優(yōu)點(diǎn):簡單直接
缺點(diǎn):輸出是人類可讀的表格,不利于程序解析
二、使用--format自定義輸出 + 結(jié)構(gòu)化解析(推薦)
# -*- 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', ...}]
優(yōu)點(diǎn):結(jié)構(gòu)化數(shù)據(jù)、易于轉(zhuǎn)為 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 數(shù)據(jù)
四、自動(dòng)生成--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))
運(yùn)行后自動(dòng)輸出:
docker stats --no-stream --format "{{.BlockIO}}#{{.CPUPerc}}#{{.Container}}#..."
以后想加新字段,直接改字典再運(yùn)行即可
五、持續(xù)監(jiān)控 + 計(jì)算平均內(nèi)存使用率(適合壓測報(bào)告)
# -*- 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行是數(shù)據(jù),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("開始監(jiān)控容器內(nèi)存使用率(每3秒采樣一次,共120次)\n")
for i in range(1, count + 1):
mem = get_mem_usage(container)
total += mem
avg = total / i
print(f"第{i:3d}次 | 當(dāng)前: {mem:5.2f}% | 累計(jì)平均: {avg:.2f}%")
time.sleep(3)
print(f"\n120次采樣平均內(nèi)存使用率:{total/count:.2f}%")
適用于:
- 壓測前后資源占用對比
- 自動(dòng)化報(bào)告生成
- 容器資源預(yù)警
總結(jié)對比
| 方式 | 是否結(jié)構(gòu)化 | 是否安全 | 是否適合生產(chǎn) | 推薦場景 |
|---|---|---|---|---|
| 直接 shell=True 輸出表格 | 否 | 一般 | 調(diào)試用 | 快速查看 |
| --format + split("#") | 是 | 推薦 | 強(qiáng)烈推薦 | 前后端、監(jiān)控系統(tǒng) |
| subprocess 列表傳參 | 是 | 高 | 生產(chǎn)首選 | Web API 接口 |
| 自動(dòng)生成模板腳本 | - | - | 開發(fā)輔助 | 快速擴(kuò)展字段 |
| 循環(huán)采樣統(tǒng)計(jì)平均值 | 是 | 推薦 | 壓測/報(bào)告 | 性能測試分析 |
到此這篇關(guān)于Python獲取Docker容器實(shí)時(shí)資源占用(CPU、內(nèi)存、IO等)5種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Python獲取Docker容器資源占用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
opencv實(shí)現(xiàn)靜態(tài)手勢識別 opencv實(shí)現(xiàn)剪刀石頭布游戲
這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)靜態(tài)手勢識別,opencv實(shí)現(xiàn)剪刀石頭布游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
解決tensorboard多個(gè)events文件顯示紊亂的問題
今天小編就為大家分享一篇解決tensorboard多個(gè)events文件顯示紊亂的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
python根據(jù)給定文件返回文件名和擴(kuò)展名的方法
這篇文章主要介紹了python根據(jù)給定文件返回文件名和擴(kuò)展名的方法,實(shí)例分析了Python操作文件及字符串的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
python3發(fā)送request請求及查看返回結(jié)果實(shí)例
這篇文章主要介紹了python3發(fā)送request請求及查看返回結(jié)果實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
python條件變量之生產(chǎn)者與消費(fèi)者操作實(shí)例分析
這篇文章主要介紹了python條件變量之生產(chǎn)者與消費(fèi)者操作,結(jié)合具體實(shí)例形式分析了Python條件變量的概念、原理、及線程操作的相關(guān)技巧,需要的朋友可以參考下2017-03-03
Django和websocket實(shí)現(xiàn)簡單的多人聊天的示例代碼
本文主要介紹了使用Django和WebSocket實(shí)現(xiàn)一個(gè)簡單的多人聊天應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01

