替代 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”中的“虚拟大小”表示 50MB 和 2Bytes 的非常小的有效负载 -> 神秘的开销 40MB
- 卷曲/下载容器内的 100MB 文件
- 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/