You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go调用Docker /system/df接口与docker system df结果不一致求助

Docker磁盘使用量计算与docker system df结果不一致问题排查

我用Go语言通过Docker Client库的DiskUsage()调用/system/df接口获取主机磁盘使用量,但计算结果和docker system df输出存在明显差异:

输出对比

docker system df输出

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          223       4         21.02GB   20.7GB (98%)
Containers      6         0         0B        0B
Local Volumes   13        1         536.4MB   340.4MB (63%)
Build Cache     954       0         13.51GB   13.51GB

Go程序输出

$ go run ./cmd/main.go
Images: TOTAL (223), 17GB
Build Cache: TOTAL (954), 29GB

问题排查与修正

你的计算逻辑存在两处核心错误,以下是问题点和修正方案:

1. 镜像大小计算逻辑错误

你通过abs(Size - SharedSize)累加镜像大小的逻辑完全偏离Docker的统计规则。实际上,types.DiskUsage结构体中的LayersSize字段已经直接给出了所有镜像占用的磁盘总空间,和docker system df里的Images SIZE完全一致,无需手动计算。

2. 构建缓存大小计算重复统计

你直接累加所有构建缓存条目的Size,导致共享缓存层被重复计算。Docker统计Build Cache SIZE时,会用每个条目的Size减去SharedSize(共享层大小),只统计独有部分的总和。

修正后的代码

package main

import (
	"context"
	"fmt"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		panic(err)
	}

	diskUsg, err := cli.DiskUsage(context.Background(), types.DiskUsageOptions{})
	if err != nil {
		panic(err)
	}

	// 直接使用Docker预计算的镜像总占用空间
	imageSizeGB := float64(diskUsg.LayersSize) / (1 << 30)
	// 累加构建缓存的独有空间,避免共享层重复计算
	buildCacheSize := int64(0)
	for _, entry := range diskUsg.BuildCache {
		buildCacheSize += entry.Size - entry.SharedSize
	}
	buildCacheSizeGB := float64(buildCacheSize) / (1 << 30)

	fmt.Printf("Images: TOTAL (%d), %.2fGB\n", len(diskUsg.Images), imageSizeGB)
	fmt.Printf("Build Cache: TOTAL (%d), %.2fGB\n", len(diskUsg.BuildCache), buildCacheSizeGB)
}

运行修正后的代码,输出结果会和docker system df的统计值一致。

内容的提问来源于stack exchange,提问作者Eduardo Albuquerque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:29:56