如何使用 docker stats 实时监控容器 CPU 内存与网络占用

来源:站长查询作者:比特币程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何使用 docker stats 实时监控容器 CPU 内存与网络占用》,敬请观看详情。当线上服务突然变慢,却找不到是哪一个容器吃光了资源时,快速定位问题就成了当务之急。docker stats 是 Docker 自带的轻量命令,无需安装额外组件,就能在终端实时输出所有运行中容器的 CPU、内存、网络 IO 与磁盘读写数据。它直接读取 cgroups 与 Linux 内核接口,开销极低。理解各列指标含义、掌握格式化输出与过滤特定容器的方法,可以帮助运维人员在故障发生时几秒内看清资源瓶颈,也能在压测阶段持续观察容器表现,避免盲目重启或扩容。

在容器化部署成为主流的今天,单个宿主机上往往运行着几十甚至上百个容器。一旦某个业务模块出现内存泄漏或死循环,就会迅速拖垮整台机器。Docker 引擎提供了原生的统计接口,通过 docker stats 命令即可实时拉取每个容器的资源消耗情况,不需要借助 Prometheus 或第三方 Agent 就能完成基础巡检。

如何使用 docker stats 实时监控容器 CPU 内存与网络占用

docker stats 的基础用法与输出字段解析

最直接的使用方式是在终端输入 docker stats,此时命令会持续刷新,列出当前所有处于运行状态的容器。默认展示的字段包括容器 ID、名称、CPU 占用百分比、内存用量与限制、内存百分比、网络接收与发送速率、以及块设备读写。这些数据每秒更新一次,方便用户动态观察趋势。

很多人第一次看输出时会困惑为什么 CPU 百分比能超过 100%。这是因为 Docker 默认按单核基准计算,如果宿主机是四核,某个容器跑满了两个核心,就会显示约为 200%。内存那一列则同时给出了绝对用量和上限值,当限制列显示为 0 或具体数值时,可以直观判断容器是否设置了硬性约束。网络与磁盘 IO 以人类可读单位呈现,例如 MB 或 GB,便于快速评估流量异常。

如果只想看某几个容器,可以在命令后追加容器名或 ID,例如 docker stats web_app redis_db。这样输出就只会包含指定对象,避免信息过载。配合 --no-stream 参数还能只打印一次当前快照,适合写进脚本做定时采集。下面是一段典型的单次采样代码:

# 获取一次 web 容器资源快照
docker stats --no-stream web_app

# 输出示例
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O
a1b2c3d4e5f6   web_app   12.34%    180MiB / 512MiB     35.15%    1.2MB / 800kB     0B / 0B

底层原理与 cgroups 数据来源

docker stats 并不是凭空估算数字,而是读取 Linux 的 cgroups(控制组)虚拟文件系统。每个容器在创建时,Docker 都会为其建立独立的 cgroup 目录,例如 /sys/fs/cgroup/cpu/docker/<容器ID>//sys/fs/cgroup/memory/docker/<容器ID>/。命令通过 Docker daemon 调用 libcontainer 或 runc 接口,周期性地打开这些文件并解析其中的累计计数器。

以 CPU 为例,内核记录的是容器在所有 CPU 上的累计占用纳秒数。Docker 在计算百分比时,取相邻两次采样的差值除以采样间隔,再除以逻辑 CPU 总数,从而得到相对占用率。内存部分则直接读取 memory.usage_in_bytesmemory.limit_in_bytes,两者相除即内存使用率。网络数据来源于 /sys/class/net/<veth>/statistics/ 中的收发字节数,块设备则来自 cgroups 的 blkio 控制器。

了解原理后就能明白,为什么在容器停止后 docker stats 看不到它,以及为什么某些老版本内核下网络速率可能为零。如果宿主机使用了非 systemd 的 cgroup 驱动,路径会稍有差异,但 daemon 已经封装了这些细节。下面的 Go 风格伪代码展示了 daemon 侧的大致逻辑:

// 伪代码:读取某容器 CPU 使用纳秒
func readCpuUsage(cgroupPath string) (uint64, error) {
    data, err := ioutil.ReadFile(cgroupPath + "/cpuacct.usage")
    if err != nil {
        return 0, err
    }
    return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
}

// 两次采样求差得到使用量
delta := currentUsage - lastUsage
percent := float64(delta) / float64(intervalNs) / float64(cpuNum) * 100

实战中的过滤技巧与自动化监控方案

在生产环境中,我们通常不会一直盯着终端,而是把 docker stats 接入定时任务或监控管道。例如通过 --format 参数自定义输出模板,只提取关心的列,再使用 awkjq 做阈值判断。自定义格式依赖 Go 的模板语法,可以引用 .Name.CPUPerc 等字段,避免冗余信息干扰。

假设需要每五秒记录一次内存超过 80% 的容器,可以写一个简单的 shell 循环,将 --no-stream 的结果重定向到日志,并由外部程序告警。对于多节点集群,单机 docker stats 显然不够,此时可将其作为边车脚本,把数据推送到中央收集器。但它依然是排查单机异常时最快捷的手段,比登录网页控制台更实时。

另一个常见需求是排除系统容器只盯业务容器。可以结合 docker ps --filter 先拿到列表,再传给 docker stats。下面示例展示如何用格式化输出生成 CSV,方便 Excel 打开分析:

# 生成 CSV 格式统计并追加到文件
docker stats --no-stream 
  --format "{{.Name}},{{.CPUPerc}},{{.MemPerc}},{{.NetIO}}" 
  >> stats_$(date +%F).csv

# 配合过滤只统计带 app 标签的容器
docker stats --no-stream 
  $(docker ps -q --filter label=type=app) 
  --format "table {{.Name}}t{{.MemUsage}}"

通过上述方式,团队可以在不引入重量级监控栈的前提下,建立起基础的资源可视能力。当业务规模扩大后,再平滑迁移到更完整的观测系统,而日常排障时 docker stats 始终是工程师手边那把最快的扳手。

docker_stats容器监控资源占用修改时间:2026-08-15 09:15:46

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。