Python获取Docker容器实时资源占用(CPU、内存、IO等)5种实现方式

Written by

in

文章目录
  • # -*- 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       PIDS7d0d088b44e6   centos7-novnc2   0.02%     144.2MiB / 7.774GiB   1.81%     2.44kB / 0B     249MB / 403MB   99 优点:简单直接 缺点:输出是人类可读的表格,不利于程序解析
  • # -*- 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、前后端交互友好
  • 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 数据
  • 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容器资源占用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: 通过Docker容器部署Python环境的全流程 python脚本监控docker容器 使用Python和PyQt5实现全方面系统资源监控 Python使用psutil实现系统监控与资源管理 python使用watchdog实现文件资源监控 基于python编写监控系统各项资源的脚本
  • 目录
    • 一、使用docker stats –no-stream最简版(适合快速查看)
    • 二、使用–format自定义输出 + 结构化解析(推荐)
    • 三、使用 subprocess 列表方式(更安全,避免 shell 注入)
    • 四、自动生成–format模板的小工具(偷懒神器)
    • 五、持续监控 + 计算平均内存使用率(适合压测报告)
    • 总结对比

    在运维监控、容器管理平台、云桌面系统等场景中,我们经常需要实时获取 Docker 容器的 CPU、内存、网络、磁盘 IO 等资源使用情况。本文总结了 5 种常用的 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

    优点:简单直接

    缺点:输出是人类可读的表格,不利于程序解析

    # -*- 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、前后端交互友好

    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 数据

    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容器资源占用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

    您可能感兴趣的文章:

    • 通过Docker容器部署Python环境的全流程
    • python脚本监控docker容器
    • 使用Python和PyQt5实现全方面系统资源监控
    • Python使用psutil实现系统监控与资源管理
    • python使用watchdog实现文件资源监控
    • 基于python编写监控系统各项资源的脚本

    站内搜索