我可以看到 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”的容器。
例如,我为 MongoDB 使用了一个纯数据容器,称为“mongo-data”。
当我运行 docker run -it --volumes-from mongo-data busybox
,然后在容器内运行 df -h
时,它说安装在 /data/db
上的文件系统(我的 'mongo-data' 纯数据容器)使用 11.3G,但是当我执行 du -h /data/db
时,它说它只使用2.1G。
那么,如何分析容器/卷的磁盘使用情况?或者,就我而言,如何找出“mongo-data”容器的大小?
docker-squash
实用程序。从 GitHub 获取它:github.com/jwilder/docker-squash
要查看容器的文件大小,您可以使用 docker ps
的 --size
参数:
docker ps --size
在 1.13.0 之后,Docker 包含一个新命令 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
将其发布为答案,因为我上面的评论被隐藏了:
列出容器的大小:
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”)
/var/lib/docker/devicemapper: No such file or directory
。知道 devicemapper 存储在 mac 上的什么位置吗?
du
命令。如果您使用 aufs
而不是设备映射器,该命令也可能会失败。
卷部分不再起作用,所以如果有人感兴趣,我只需稍微更改一下上面的脚本:
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
我使用 docker stats $(docker ps --format={{.Names}}) --no-stream
来获得:
CPU 使用率,Mem 使用率/分配给容器的总内存(可以使用 docker run 命令分配) Mem % Block I/O Net I/O
(这个答案没有用,但因为有些评论可能有,所以把它留在这里)
docker images
将显示“虚拟大小”,即包括所有较低层在内的总大小。因此,如果您的容器共享相同的基本映像,则需要进行重复计算。
改进Maxime的答案:
docker ps --size
你会看到这样的东西:
+---------------+---------------+--------------------+
| CONTAINER ID | IMAGE | SIZE |
+===============+===============+====================+
| 6ca0cef8db8d | nginx | 2B (virtual 183MB) |
| 3ab1a4d8dc5a | nginx | 5B (virtual 183MB) |
+---------------+---------------+--------------------+
启动容器时,启动容器的映像以只读(虚拟)方式挂载。最重要的是,安装了一个可写层,对容器所做的任何更改都会写入其中。
所以虚拟大小(示例中为 183MB)只使用一次,无论从同一个镜像启动了多少容器——我可以启动 1 个容器或 1000 个容器;没有使用额外的磁盘空间。但是,每个容器的“大小”(示例中为 2B)是唯一的,因此磁盘上使用的总空间为:
183MB + 5B + 2B
请注意,显示的大小不包括用于容器的所有磁盘空间。目前不包括的东西是; - 卷 - 交换 - 检查点 - 用于容器生成的日志文件的磁盘空间
https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362
您可以使用
docker history IMAGE_ID
查看图像大小如何在其各个子组件之间分布。
请记住,docker ps --size
可能是一个昂贵的命令,需要几分钟才能完成。这同样适用于使用 size=1
的容器列表 API 请求。最好不要太频繁地运行它。
看看我们编译的 alternatives,包括 docker 持久卷目录的 du -hs
选项。
替代 docker ps --size
由于“docker ps --size”会在主机上产生沉重的 IO 负载,因此在生产环境中每分钟运行这样的命令是不可行的。因此,我们必须采取一种变通方法来获得所需的容器大小,或者更准确地说,RW 层的大小对系统性能的影响较小。
这种方法收集每个容器的“设备名称”,然后使用“df”命令检查它的大小。这些“设备名称”是安装在每个容器上的精简配置卷。一个问题仍然存在,因为这个观察到的大小也意味着底层图像的所有只读层。为了解决这个问题,我们可以简单地检查使用的容器镜像的大小,然后从设备/瘦卷的大小中减去它。
应该注意的是,在使用设备映射器时,每个图像层都被实现为一种 lvm 快照。不幸的是,我无法让我的 rhel 系统打印出这些快照/图层。否则,我们可以简单地收集“最新”快照的大小。如果有人能把事情说清楚,那就太好了。然而...
经过一些测试,似乎创建一个容器总是会增加大约 100 的开销。 40MiB(使用基于镜像“httpd:2.4.46-alpine”的容器测试):
docker run -d --name apache httpd:2.4.46-alpine // 现在从 docker inspect 获取设备名称并使用 df df -T -> 90MB 查找它,而“docker ps --size”中的“Virtual Size”状态50MB 和 2Bytes 的非常小的有效负载 -> 神秘的开销 40MB curl/download 在容器 df -T -> 190MB 中的 100MB 文件,而“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/
这是最简单的方法:
docker ps -s
docker ps -s
不会考虑保存在 /var/lib/docker/ 中的日志。27.2MB (virtual 173MB)
它们之间有什么区别?