如何分析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个回答

2

替代docker ps --size的方法

"docker ps --size"会在主机上产生大量IO负载,因此在生产环境中每分钟运行这样的命令是不可行的。因此,我们需要一个解决方案来获取所需容器大小或更准确地说是RW层的大小,并对系统性能影响较小。

这种方法收集每个容器的“设备名称”,然后使用“df”命令检查其大小。这些“设备名称”是挂载到每个容器的“/”目录下的薄配置卷。但是,还存在一个问题,即观察到的大小也包括底层镜像的所有只读层。为了解决这个问题,我们可以简单地检查已使用的容器镜像的大小,并从设备/薄卷的大小中减去它。

应该注意,当使用设备映射器时,每个镜像层都被实现为一种lvm快照。不幸的是,我无法让我的rhel系统打印出这些快照/层。否则,我们可以简单地收集“最新”快照的大小。如果有人能澄清这些事情,那就太好了。但是...

经过一些测试,似乎创建容器总是增加了约40MiB的开销(使用基于Image“httpd:2.4.46-alpine”的容器进行测试):

  1. docker run -d --name apache httpd:2.4.46-alpine // 现在从docker inspect中获取设备名称,并使用df查找
  2. df -T -> 90MB,而“docker ps --size”中的“虚拟大小”为50MB,非常小的有效负载为2字节->神秘的开销为40MB
  3. 在容器内下载/ curl一个100MB文件
  4. df -T -> 190MB,而“docker ps --size”中的“虚拟大小”为150MB,有效负载为100MB->开销为40MB

以下shell打印与“docker ps --size”相匹配的结果(但请记住上述40MB的开销)

for c in  $(docker ps -q); do \
container_name=$(docker inspect -f "{{.Name}}" ${c} | sed 's/^\///g' ); \
device_n=$(docker inspect -f "{{.GraphDriver.Data.DeviceName}}" ${c} | sed 's/.*-//g'); \
device_size_kib=$(df -T | grep ${device_n} | awk '{print $4}'); \
device_size_byte=$((1024 * ${device_size_kib})); \
image_sha=$(docker inspect -f "{{.Image}}" ${c} | sed 's/.*://g' ); \
image_size_byte=$(docker image inspect -f "{{.Size}}" ${image_sha}); \
container_size_byte=$((${device_size_byte} - ${image_size_byte})); \
\
echo my_node_dm_device_size_bytes\{cname=\"${container_name}\"\} ${device_size_byte}; \
echo my_node_dm_container_size_bytes\{cname=\"${container_name}\"\} ${container_size_byte}; \
echo my_node_dm_image_size_bytes\{cname=\"${container_name}\"\} ${image_size_byte}; \
done

关于设备映射器的更多阅读资料:https://test-dockerrr.readthedocs.io/en/latest/userguide/storagedriver/device-mapper-driver/


这只适用于非默认的devicemapper快照程序,对吗? - Daniel Föhr
在我的Mac OS Ventura上无法工作。出现了一个错误:“df: 选项需要一个参数 -- T”。 - user674669

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