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

时间:2014-11-05 09:01:17

标签: linux docker lxc volumes device-mapper

我一直在搜索,但找不到分析Docker容器/卷的磁盘使用情况的方法。

我可以看到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'来分析磁盘使用情况。它似乎有效,但不适用于使用'volume-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'容器大小?

非常感谢,

11 个答案:

答案 0 :(得分:357)

要查看容器的文件大小,可以使用-s的{​​{1}}参数:

docker ps

答案 1 :(得分:219)

1.13.0之后,Docker 包含一个新命令docker system df以显示泊坞磁盘使用情况。

$ 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 -v

答案 2 :(得分:30)

将此作为答案发布,因为我上面的评论被隐藏了:

列出容器的大小:

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')

答案 3 :(得分:22)

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

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

答案 4 :(得分:10)

(这个答案没用,但是因为有些评论可能会留在这里)

docker images将显示“虚拟大小”,即包括所有较低层的总数。如果你有共享相同基本图像的容器,那么有些重复计算。

documentation

答案 5 :(得分:10)

改善马克西姆的怒吼:

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

答案 6 :(得分:6)

我使用docker stats $(docker ps --format={{.Names}}) --no-stream来获取:

  1. CPU使用率,
  2. 内存使用量/分配给容器的内存总量(可以通过docker run命令分配)
  3. 回忆%
  4. 块I / O
  5. 网络I / O

答案 7 :(得分:4)

如果你想减少多层图像的大小,我可以推荐Jason Wilder的docker-squash实用程序。从GitHub获取它:https://github.com/jwilder/docker-squash

答案 8 :(得分:3)

请记住,docker ps --size可能是一个昂贵的命令,需要花费几分钟才能完成。这同样适用于size=1的容器列表API请求。最好不要经常运行它。

查看我们编译的alternatives,包括docker持久卷目录的du -hs选项。

答案 9 :(得分:1)

这是最简单的:

docker ps -s

答案 10 :(得分:0)

替代docker ps --size

由于“ docker ps --size”会在主机上产生沉重的IO负载,因此在生产环境中每分钟运行一次这样的命令是不可行的。因此,为了获得所需的容器尺寸或更准确地说,RW层的尺寸对系统性能的影响很小,我们必须采取一种解决方法。

此方法收集每个容器的“设备名称”,然后使用“ df”命令检查其大小。这些“设备名称”是在每个容器上安装的精简配置卷。由于观察到的大小还暗示了基础图像的所有只读层,因此仍然存在一个问题。为了解决这个问题,我们可以简单地检查已用容器图像的大小,并从设备/ thin_volume的大小中减去它。

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

经过一些测试,容器的创建似乎总是会增加大约30%的开销。 40MiB(使用基于图片“ 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,很小的有效载荷为2Bytes->神秘开销为40MB
  3. 卷曲/下载容器中的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/