CLI开发工具【免费下载链接】cliThe Docker CLI项目地址https://gitcode.com/gh_mirrors/cli5/cli点击查看免费下载导读docker stats是 Docker CLI 中用于实时查看容器资源使用情况的命令它能够以流式默认或快照--no-stream的方式持续输出每个容器的 CPU 占用率、内存使用量与限额、网络 I/O、块设备 I/O 以及进程/线程数PIDS等关键指标。本文以 container_stats.md 官方参考文档为主体结合 Docker CLI 仓库中 stats.go、formatter_stats.go 与 stats_helpers.go 的源码实现讲解命令的全部参数、输出格式、Go 模板定制方法以及底层数据采集与计算原理。读完本文你将能够在生产环境中熟练使用docker stats定位资源热点并通过--format与 JSON 输出将其接入监控与告警脚本。命令概览用法与别名docker stats返回运行中容器的实时数据流。其命令形式为docker stats [OPTIONS] [CONTAINER...]其中CONTAINER...是可选参数用于将数据限制在一个或多个特定容器可以传入多个容器名称或 ID用空格分隔。未指定任何容器时命令会对所有容器进行统计。也可以指定一个已停止的容器但已停止的容器不会返回任何数据输出0B / 0B等占位值详见下文示例。该命令同时注册了两个别名在 cmd.go 与 stats.go 中有对应声明docker container statsdocker stats两者完全等价。在 cmd.go 中newStatsCommand同时被注册为docker container子命令和顶层别名命令因此无论使用哪种拼写底层执行的都是同一个RunStats实现。命令选项完整说明名称类型默认值说明-a,--allbool显示所有容器默认只显示运行中的容器--formatstring使用自定义模板格式化输出table以带列头的表格格式输出默认table TEMPLATE使用给定的 Go 模板以表格格式输出json以 JSON 格式输出TEMPLATE使用给定的 Go 模板输出。更多格式化信息可参考 Docker 官方格式化文档--no-streambool禁用流式统计只拉取一次结果--no-truncbool不截断输出例如容器 ID这些选项在源码 stats.go 中通过Flags()注册并映射到StatsOptions结构体stats.go中的对应字段All对应--all决定是否将已停止容器也纳入统计NoStream对应--no-stream决定是流式输出还是单次快照NoTrunc对应--no-trunc控制容器 ID 是否被截断为 12 位短 IDFormat对应--format自定义输出模板Containers由位置参数[CONTAINER...]填充。值得注意的一个细节StatsOptions中还存在一个尚未在命令行暴露的Filters字段当前源码只接受label过滤器见 stats.go 的acceptedStatsFilters且当显式指定容器列表时不允许使用过滤器stats.go 会返回filtering is not supported when specifying a list of containers错误。这一约束在最新版本中仍以 TODO 形式存在从源码结构看未来可能将容器列表也实现为过滤器以统一代码路径。输出列含义如果不使用--format指定格式字符串命令会显示以下列各列的头部常量定义见 formatter_stats.go列名说明CONTAINER ID和Name容器的 ID 和名称CPU %和MEM %容器正在使用的主机 CPU 和内存百分比MEM USAGE / LIMIT容器正在使用的总内存以及它被允许使用的总内存量NET I/O容器通过网络接口接收和发送的数据量BLOCK I/O容器在主机块设备上写入和读取的数据量PIDs容器已创建的进程或线程数关于内存统计的重要说明cgroup 语义差异[!NOTE] 在 Linux 上Docker CLI 通过从总内存使用量中减去缓存使用量来报告内存使用量。API 并不执行这种计算而是提供总内存使用量和来自缓存的数量以便客户端按需使用数据。在 cgroup v1 主机上缓存使用量被定义为memory.stat文件中total_inactive_file字段的值。在 Docker 19.03 及更早版本中缓存使用量被定义为cache字段的值。在 cgroup v2 主机上缓存使用量被定义为inactive_file字段的值。这一行为在源码 stats_helpers.go 的calculateMemUsageUnixNoCache函数中有精确体现// cgroup v1 if v, isCgroup1 : mem.Stats[total_inactive_file]; isCgroup1 v mem.Usage { return float64(mem.Usage - v) } // cgroup v2 if v : mem.Stats[inactive_file]; v mem.Usage { return float64(mem.Usage - v) } return float64(mem.Usage)即在 cgroup v1 主机上结果为Usage - total_inactive_file在 cgroup v2 主机上结果为Usage - inactive_file若字段缺失或值不小于 Usage 则直接返回 Usage。该定义与 cadvisor 和 containerd/CRI 保持一致。对应的单元测试 stats_helpers_test.go 验证了 v1 场景Usage: 500、total_inactive_file: 400时计算结果为100。同时MEM %内存百分比的计算在 stats_helpers.go 中usedNoCache / limit * 100当MemoryStats.Limit为 0容器未运行、cgroup 尚无数据时返回 0。关于 PIDS 列的重要说明[!NOTE]PIDS列包含该容器创建的进程数和内核线程数。Threads线程是 Linux 内核使用的术语其他等价术语包括 lightweight process轻量级进程或 kernel task内核任务等。如果PIDS列出现很大的数值而ps或top报告的进程数很小这可能表明容器内的某个程序正在创建大量线程。从源码看该值直接取自v.PidsStats.Currentstats_helpers.go是 cgroup 的 pids 控制器当前计数。典型使用示例查看所有运行中容器Linux 守护进程$ docker stats CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2 e5c383697914 test-1951.1.kay7x1lh1twk9c0oig50sd5tr 0.00% 196KiB / 1.952GiB 0.01% 71.2kB / 0B 770kB / 0B 1 4bda148efbc0 random.1.vnc8on831idyr42slu578u3cr 0.00% 1.672MiB / 1.952GiB 0.08% 110kB / 0B 578kB / 0B 2按名称和 ID 查看多个指定容器Linux 守护进程$ docker stats awesome_brattain 67b2525d8ad1 CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS b95a83497c91 awesome_brattain 0.28% 5.629MiB / 1.952GiB 0.28% 916B / 0B 147kB / 0B 9 67b2525d8ad1 foobar 0.00% 1.727MiB / 1.952GiB 0.09% 2.48kB / 0B 4.11MB / 0B 2以 JSON 格式输出单次快照对名为nginx的容器执行单次统计并输出 JSON$ docker stats nginx --no-stream --format {{ json . }} {BlockIO:0B / 13.3kB,CPUPerc:0.03%,Container:nginx,ID:ed37317fbf42,MemPerc:0.24%,MemUsage:2.352MiB / 982.5MiB,Name:nginx,NetIO:539kB / 606kB,PIDs:2}{{ json . }}是 Go 模板内置函数会将当前上下文字段序列化为 JSON非常便于脚本解析。对应的statsContext.MarshalJSON实现位于 formatter_stats.go。自定义格式查看所有含已停止容器$ docker stats --all --format table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}} fervent_panini 5acfcb1b4fd1 humble_visvesvaraya big_heisenberg CONTAINER CPU % MEM USAGE / LIMIT fervent_panini 0.00% 56KiB / 15.57GiB 5acfcb1b4fd1 0.07% 32.86MiB / 15.57GiB humble_visvesvaraya 0.00% 0B / 0B big_heisenberg 0.00% 0B / 0B上例中humble_visvesvaraya和big_heisenberg是已停止的容器。可见即使指定了--all已停止容器也无法提供统计样本因此内存显示为0B / 0B。这是底层 API 决定的已停止容器没有 cgroup 数据可采集。查看所有运行中容器Windows 守护进程PS E:\ docker stats CONTAINER ID CPU % PRIV WORKING SET NET I/O BLOCK I/O 09d3bb5b1604 6.61% 38.21 MiB 17.1 kB / 7.73 kB 10.7 MB / 3.57 MB 9db7aa4d986d 9.19% 38.26 MiB 15.2 kB / 7.65 kB 10.6 MB / 3.3 MB 3f214c61ad1d 0.00% 28.64 MiB 64 kB / 6.84 kB 4.42 MB / 6.93 MB注意 Windows 平台的列集与 Linux 不同没有MEM %和PIDS列内存列名为PRIV WORKING SET私有工作集。这是因为 Windows 容器没有 cgroup 语义内存指标采用私有工作集大小源码 stats_helpers.go 中v.MemoryStats.PrivateWorkingSetCPU 百分比也使用了完全不同的计算公式stats_helpers.go 的calculateCPUPercentWindows。按名称和 ID 查看多个容器Windows 守护进程PS E:\ docker ps -a CONTAINER ID NAME IMAGE COMMAND CREATED STATUS PORTS NAMES 3f214c61ad1d awesome_brattain nanoserver cmd 2 minutes ago Up 2 minutes big_minsky 9db7aa4d986d mad_wilson windowsservercore cmd 2 minutes ago Up 2 minutes mad_wilson 09d3bb5b1604 fervent_panini windowsservercore cmd 2 minutes ago Up 2 minutes affectionate_easley PS E:\ docker stats 3f214c61ad1d mad_wilson CONTAINER ID NAME CPU % PRIV WORKING SET NET I/O BLOCK I/O 3f214c61ad1d awesome_brattain 0.00% 46.25 MiB 76.3 kB / 7.92 kB 10.3 MB / 14.7 MB 9db7aa4d986d mad_wilson 9.59% 40.09 MiB 27.6 kB / 8.81 kB 17 MB / 20.1 MB自定义输出格式--format--format选项使用 Go 模板来美化容器输出。以下占位符是 Go 模板中的有效字段实现于 formatter_stats.go 的statsContext各访问器方法占位符说明.Container容器名称或 ID用户输入.Name容器名称.ID容器 ID.CPUPercCPU 百分比.MemUsage内存使用量.NetIO网络 I/O.BlockIO块设备 I/O.MemPerc内存百分比Windows 上不可用.PIDsPIDs 数量Windows 上不可用使用--format时stats命令要么严格按照模板声明输出数据要么在使用table指令时同时包含列头。下面的示例使用无表头的模板对所有容器输出以冒号:分隔的Container和CPUPerc$ docker stats --format {{.Container}}: {{.CPUPerc}} 09d3bb5b1604: 6.61% 9db7aa4d986d: 9.19% 3f214c61ad1d: 0.00%要以表格格式列出所有容器的名称、CPU 百分比和内存使用量$ docker stats --format table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}} CONTAINER CPU % PRIV WORKING SET 1285939c1fd3 0.07% 796 KiB / 64 MiB 9c76f7834ae2 0.07% 2.746 MiB / 64 MiB d1ea048f04e4 0.03% 4.583 MiB / 64 MiB默认格式Linux 平台默认格式为table {{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}Windows 平台默认格式为table {{.ID}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}这两个默认模板正是 formatter_stats.go 中定义的defaultStatsTableFormat与winDefaultStatsTableFormat常量。NewStatsFormat函数formatter_stats.go会在未指定格式时根据守护进程的OSType选择对应模板——这正是示例中 Windows 输出没有MEM %/PIDS列的原因。另外docker stats的默认格式还可以通过 Docker CLI 配置文件~/.docker/config.json中的statsFormat字段全局定制见 file.go。在 stats.go 中格式优先级为命令行--format 配置文件statsFormat 平台默认模板。源码级原理docker stats的实时采集与渲染流程理解命令行为的最佳途径是阅读其核心实现RunStatsstats.go整个流程可概括为三个环节1. 目标容器列表的动态维护未指定容器时showAll为 trueCLI 会先订阅守护进程的容器事件流apiClient.Events再拉取初始容器列表以避免错过新建容器。事件处理器按动作分发start以及--all下的create事件触发新增容器统计destroy以及非--all下的die事件触发移除容器统计stats.go。这正是docker stats无需重启就能自动纳入/剔除容器的机制。指定容器时直接为每个名称/ID 创建Stats实体并启动采集 goroutine不做事件监听stats.go。2. 数据采集collect 函数每个容器对应一个独立的collectgoroutinestats_helpers.go调用/containers/(id)/statsAPI客户端ContainerStats通过IncludePreviousSample: !streamStats控制是否附带上一采样点的 CPU 数据用于首次 CPU 百分比计算流式模式下持续解码 JSON 流--no-stream模式下取得第一条数据后即返回若 2 秒内未收到更新会调用SetErrorAndReset将统计值清零并标记IsInvalid truestats_helpers.go此时各列显示--或-- / --占位值。原始指标在采集 goroutine 中会被换算为人类可读的展示值CPU 百分比Linux基于两次采样间的容器 CPU 增量与系统 CPU 增量之比乘以在线 CPU 数见calculateCPUPercentUnixstats_helpers.go网络 I/O对所有网络接口的RxBytes/TxBytes求和见calculateNetworkstats_helpers.go块 I/O对IoServiceBytesRecursive中读/写操作求和见calculateBlockIOstats_helpers.go其单元测试 stats_helpers_test.go 验证了blkRead 5815、blkWrite 593的聚合结果。3. 渲染与刷新渲染由 formatter_stats.go 的statsFormatWrite完成它会根据守护进程类型选择列头Linux 显示MEM USAGE / LIMIT、MEM %、PIDSWindows 显示PRIV WORKING SET并按--no-trunc决定 ID 是否截断为短 ID。流式模式下主循环以500ms 间隔stats.go 的ticker : time.NewTicker(500 * time.Millisecond)重绘整个终端帧通过 ANSI 转义序列将光标移至左上角\033[H、逐行清屏\033[K并清除残余内容\033[J在单次写入中完成刷新以避免闪烁。若所有容器都消失且不是showAll模式命令会清屏退出。非流式模式下则一次性输出快照stats.go。关于渲染层的格式化行为formatter_stats_test.go 中TestContainerStatsContext覆盖了各字段的取值与列头映射包括无效数据时输出--的降级行为如IsInvalid: true时CPUPerc输出--、MemUsage输出-- / --。小结从命令到 API 的完整链路当你在终端敲下docker stats时实际发生的是Cobra 解析参数并填充StatsOptionsstats.goRunStats确定目标容器集合必要时订阅容器事件流保持动态stats.go每个容器由独立 goroutine 调用守护进程的/containers/(id)/statsAPI 持续拉取原始数据stats_helpers.go原始数据经 CPU、内存去缓存、网络、块 I/O 计算后按--format模板或平台默认模板渲染formatter_stats.go流式模式以 500ms 周期刷新终端--no-stream输出单次快照后退出stats.go。掌握这套机制后你可以把docker stats --no-stream --format {{ json . }}的输出接入 cron 定时任务或监控系统用--all排查异常容器或通过~/.docker/config.json的statsFormat统一团队输出风格。如需更细粒度的单容器资源明细例如逐核 CPU、内存页统计文档建议直接使用/containers/(id)/statsAPI 端点获取未做任何换算的原始数据。赞分享CLI开发工具【免费下载链接】cliThe Docker CLI项目地址https://gitcode.com/gh_mirrors/cli5/cli点击查看免费下载相关推荐Docker CLI 容器资源监控指南深入理解 docker stats 命令Docker CLI 容器资源监控指南深入理解 docker stats 命令 概述 在容器化应用的管理和维护过程中实时监控容器资源使用情况是至关重要的运维CLI开发工具Docker CLI 的 docker stats 命令详解实时监控容器资源使用统计Docker CLI 的 docker stats 命令详解实时监控容器资源使用统计 导读 docker stats 是 Docker CLI 中用于 实时查CLI开发工具telepresence compose stats 命令详解在 Kubernetes 本地开发中实时监控 Docker 容器资源占用telepresence compose stats 命令详解在 Kubernetes 本地开发中实时监控 Docker 容器资源占用 telepresenc云原生开发工具微服务网络上一篇pageres版本历史v1到v3的重大更新回顾下一篇termtosvg快捷键冲突与终端模拟器的兼容性处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考