如何分析Docker容器的磁盘使用情况

356

我可以看到 Docker 占用了我的文件系统的 12GB 空间:

2.7G    /var/lib/docker/vfs/dir
2.7G    /var/lib/docker/vfs
2.8G    /var/lib/docker/devicemapper/mnt
6.3G    /var/lib/docker/devicemapper/devicemapper
9.1G    /var/lib/docker/devicemapper
12G     /var/lib/docker

但是,我如何知道这是如何分布在容器之间的?

我尝试通过运行(新的v1.3命令)连接到容器。

docker exec -it <container_name> bash

然后运行df -h来分析磁盘使用情况。看起来它是有效的,但对于使用'volumes-from'的容器则不适用。
例如,我使用一个名为'mongo-data'的数据容器来存储MongoDB数据。
当我运行docker run -it --volumes-from mongo-data busybox,然后在容器内运行df -h时,它显示挂载在/data/db(我的'mongo-data'数据容器)上的文件系统使用了11.3G,但当我运行du -h /data/db时,它只显示使用了2.1G。
那么,如何分析容器/卷的磁盘使用情况呢?或者说,在我的情况下,如何找出'mongo-data'容器的大小?

如果你想要减小多层图片的大小,我可以推荐Jason Wilder的“docker-squash”工具。在GitHub上获取它:https://github.com/jwilder/docker-squash - mhvelplund
在Mac OS X上有一个未解决的问题:“Docker无法释放磁盘空间...”:https://github.com/docker/for-mac/issues/371 - asmaier
11个回答

595

要查看您的容器文件大小,可以使用docker ps命令的--size参数:

docker ps --size

34
请注意,运行 docker ps --size 命令可能需要几分钟的时间才能完成,并且会对主机产生大量IO。该命令的详细说明请参阅以下链接:https://github.com/axibase/axibase-collector-docs/blob/master/jobs/docker/volume-size.md - Sergei Rodionov
6
我注意到运行 docker ps -s 命令时不会考虑保存在 /var/lib/docker/ 中的日志。 - demee
22
它会输出两个值,例如 27.2MB (virtual 173MB),它们的区别是什么? - Mohammed Noureldin
13
@MohammedNoureldin 这里有一个解释:https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362 - aleclarson
6
请注意,这在Docker for Windows上无法使用 - 它只会报告所有内容为0。 - Mike Christensen
显示剩余3条评论

411

Docker 1.13.0之后,新增了一个命令docker system df用于显示Docker磁盘使用情况。

$ docker system df
TYPE            TOTAL        ACTIVE     SIZE        RECLAIMABLE
Images          5            1          2.777 GB    2.647 GB (95%)
Containers      1            1          0 B         0B
Local Volumes   4            1          3.207 GB    2.261 (70%)
展示更详细的空间使用信息:

$ docker system df --verbose

如果您有很多组件,一个有用的命令是:docker system df --verbose > docker.stats-2019-07-18.log - joseluisq
容器的SIZE列是什么意思?我有一些容器关闭了,这个命令显示SIZE = 100MB。 - danilo
容器的大小为100MB - danilo

32

因为我的上面的评论被隐藏了,所以我把它作为答案发布:

列出容器的大小:

du -d 2 -h /var/lib/docker/devicemapper | grep `docker inspect -f "{{.Id}}" <container_name>`

列出容器卷的大小:

docker inspect -f "{{.Volumes}}" <container_name> | sed 's/map\[//' | sed 's/]//' | tr ' ' '\n' | sed 's/.*://' | xargs sudo du -d 1 -h

编辑: 列出所有正在运行的容器的大小和卷:

列出所有正在运行的容器的大小和卷:

for d in `docker ps -q`; do
    d_name=`docker inspect -f {{.Name}} $d`
    echo "========================================================="
    echo "$d_name ($d) container size:"
    sudo du -d 2 -h /var/lib/docker/devicemapper | grep `docker inspect -f "{{.Id}}" $d`
    echo "$d_name ($d) volumes:"
    docker inspect -f "{{.Volumes}}" $d | sed 's/map\[//' | sed 's/]//' | tr ' ' '\n' | sed 's/.*://' | xargs sudo du -d 1 -h
done

注意: 根据你的Docker文件系统更改'devicemapper' (例如 'aufs')


8
"du -d 2" 在我的Centos系统上无法使用,我不得不使用"du --max-depth 2"代替。 - dr-jan
3
在 Mac 上显示 /var/lib/docker/devicemapper: No such file or directory。你知道 devicemapper 在 Mac 上存储在哪里吗? - Markus
1
Markus:如果你正在使用boot2docker,那么你必须在boot2docker主机虚拟机内运行du命令。如果你使用的是aufs而不是device mapper,该命令也可能会失败。 - James
使用“docker ps -q”列出容器哈希值,而不是使用awk/tail命令如何? - Andrew Wolfe
我的Ubuntu 14.04/Docker 1.10.2安装中,容器大小始终为空。 - mhvelplund

21

音量部分不再起作用,如果有人感兴趣,我只是稍微修改了上面的脚本:

for d in `docker ps | awk '{print $1}' | tail -n +2`; do
    d_name=`docker inspect -f {{.Name}} $d`
    echo "========================================================="
    echo "$d_name ($d) container size:"
    sudo du -d 2 -h /var/lib/docker/aufs | grep `docker inspect -f "{{.Id}}" $d`
    echo "$d_name ($d) volumes:"
    for mount in `docker inspect -f "{{range .Mounts}} {{.Source}}:{{.Destination}}                                                                                                                                                      
    {{end}}" $d`; do
        size=`echo $mount | cut -d':' -f1 | sudo xargs du -d 0 -h`
        mnt=`echo $mount | cut -d':' -f2`
        echo "$size mounted on $mnt"
    done
done

挂载点不等于卷。 - derFunk
1
Mac Docker 1.12.1将镜像文件放置在~/Library/Containers/com.docker.docker/而不是/var/lib/docker/aufs中。这些文件名不包含.Id或.Name :-( - paul_h

18

改进Maxime的回答:

docker ps --size

你会看到类似这样的东西:

+---------------+---------------+--------------------+
| CONTAINER ID  | IMAGE         | SIZE               |
+===============+===============+====================+
| 6ca0cef8db8d  | nginx         | 2B (virtual 183MB) |
| 3ab1a4d8dc5a  | nginx         | 5B (virtual 183MB) |
+---------------+---------------+--------------------+
当启动一个容器时,会将容器启动所需的镜像以只读方式(虚拟)挂载。此外,还会挂载一个可写层,容器中对于任何更改都会写入到该可写层中。
因此,无论从相同的镜像启动多少个容器,虚拟大小(例如183MB)仅使用一次,不会使用额外的磁盘空间。然而,“大小”(例如2B)对于每个容器都是唯一的,因此磁盘上使用的总空间为:
183MB + 5B + 2B
请注意,显示的大小不包括用于容器的所有磁盘空间。目前未包括以下内容: - 卷 - 交换 - 检查点 - 容器生成的日志文件所使用的磁盘空间 https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362

那么如果它说大小为0,那么这意味着可写层不包含任何更改? - A X
我不能确定,可能对一个文本文件进行最小的更改就会导致结果为零。 - danilo
有一些工具可以分析图像,你可以导出为tar.gz文件,然后进行提取,最后使用比较器。 - danilo

17

我使用 docker stats $(docker ps --format={{.Names}}) --no-stream 命令获取以下信息:

  1. CPU 使用率,
  2. 内存使用量/容器分配的总内存大小 (可以通过 docker run 命令进行分配)
  3. 内存使用百分比
  4. 块 I/O
  5. 网络 I/O

11

执行 docker images 命令将显示“虚拟大小”,即包括所有较低层的总大小。如果您有共享相同基础镜像的容器,则会存在一些重复计算。

文档


3
我不是在谈论镜像,而是容器(通过运行'docker ps'显示的列表)。 - AlonL
1
容器就像进程一样,它们没有磁盘空间。 - Bryan
2
docker run命令首先在指定的镜像上创建一个可写的容器层,这就是我所说的那个层,或者通过“volumes-from”等方式挂载到容器中的任何其他卷。 - AlonL
1
也许这个工具会有所帮助?https://github.com/cpuguy83/docker-volumes 引用自http://container42.com/2014/11/03/docker-indepth-volumes/ - Bryan
1
谢谢,它并不能满足我的需求,但是这是一个不错的工具。 - AlonL
显示剩余3条评论

10

您可以使用

docker history IMAGE_ID

查看图像大小在其各个子组件之间的分布情况。


6
请注意,docker ps --size可能是一个昂贵的命令,需要花费几分钟以上的时间才能完成。对于带有size=1的容器列表API请求也同样适用。最好不要频繁运行它。
请查看我们编制的备选方案,包括使用du -hs选项来监控Docker持久卷目录。

不适用于我的服务器-在几毫秒内运行。上述 YMMV 警告(测试,正如 Sergei 所说的“...可能...”) - Todd Curry
我也在测试,使用docker ps --size仍然可以接受。 - caknia

4

docker system df命令显示有关Docker守护程序使用的磁盘空间量的信息。

docker system df -v

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接