ChatGPT解决这个技术问题 Extra ChatGPT

How to analyze disk usage of a Docker container

I can see that Docker takes 12GB of my filesystem:

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

But, how do I know how this is distributed over the containers?

I tried to attach to the containers by running (the new v1.3 command)

docker exec -it <container_name> bash

and then running 'df -h' to analyze the disk usage. It seems to be working, but not with containers that use 'volumes-from'.

For example, I use a data-only container for MongoDB, called 'mongo-data'.

When I run docker run -it --volumes-from mongo-data busybox, and then df -h inside the container, It says that the filesystem mounted on /data/db (my 'mongo-data' data-only container) uses 11.3G, but when I do du -h /data/db, it says that it uses only 2.1G.

So, how do I analyze a container/volume disk usage? Or, in my case, how do I find out the 'mongo-data' container size?

If you want to reduce the size of many-layered images, I can recommend Jason Wilder's docker-squash utility. Get it from GitHub here: github.com/jwilder/docker-squash
On Mac OS X there is a open issue "Docker doesn't release disk space...": github.com/docker/for-mac/issues/371

t
tshepang

To see the file size of your containers, you can use the --size argument of docker ps:

docker ps --size

Note that docker ps --size can take several minutes to complete and will produce heavy IO on the host: github.com/axibase/axibase-collector-docs/blob/master/jobs/…
I noticed also that running docker ps -s does not take logs kept inside /var/lib/docker/ into account.
It outputs two values, like this 27.2MB (virtual 173MB) what is the difference between them?
@MohammedNoureldin Here's an explanation: github.com/docker/docker.github.io/issues/…
Note this doesn't work on Docker for Windows - it just reports 0 for everything.
t
tshepang

After 1.13.0, Docker includes a new command docker system df to show docker disk usage.

$ 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%)

To show more detailed information on space usage:

$ docker system df --verbose

One useful command if you have a lot of components: docker system df --verbose > docker.stats-2019-07-18.log
what does the container's SIZE column mean? I have some containers off, and this command shows SIZE = 100MB for example.
SIZE=100MB for the container off
A
AlonL

Posting this as an answer because my comments above got hidden:

List the size of a container:

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

List the sizes of a container's volumes:

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

Edit: List all running containers' sizes and volumes:

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

NOTE: Change 'devicemapper' according to your Docker filesystem (e.g 'aufs')


"du -d 2" does not work on my Centos system, I had to use "du --max-depth 2" instead.
On Mac it shows /var/lib/docker/devicemapper: No such file or directory. Any idea where the devicemapper is stored on mac?
Markus: if you are using boot2docker, you have to run the du command inside your boot2docker host VM. The command can also fail if you are using aufs instead of device mapper.
how about 'docker ps -q' to list the hashes of the containers instead of the awk/tail?
Container size is always blank on my Ubuntu 14.04/Docker 1.10.2 installation.
G
Gilsha

The volume part did not work anymore so if anyone is insterested I just change the above script a little bit:

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

Mount Points != Volumes
Mac Docker 1.12.1 puts image files in ~/Library/Containers/com.docker.docker/ not /var/lib/docker/aufs. The filenames for which do not contain the .Id or the .Name :-(
O
Opal

I use docker stats $(docker ps --format={{.Names}}) --no-stream to get :

CPU usage, Mem usage/Total mem allocated to container (can be allocate with docker run command) Mem % Block I/O Net I/O


B
Bryan

(this answer is not useful, but leaving it here since some of the comments may be)

docker images will show the 'virtual size', i.e. how much in total including all the lower layers. So some double-counting if you have containers that share the same base image.

documentation


I'm not talking about the images, but about the containers (The list shown by running 'docker ps').
Containers are like processes; they don't have disk space.
"The docker run command first creates a writeable container layer over the specified image..." (docs.docker.com/v1.1/reference/commandline/cli) That layer is what I mean, or any other volumes that are mounted to the container via 'volumes-from', etc.
Thanks, it doesn't satisfy my needs but it's a nice tool.
C
Channing Walton

Improving Maxime's anwser:

docker ps --size

You'll see something like this:

+---------------+---------------+--------------------+
| CONTAINER ID  | IMAGE         | SIZE               |
+===============+===============+====================+
| 6ca0cef8db8d  | nginx         | 2B (virtual 183MB) |
| 3ab1a4d8dc5a  | nginx         | 5B (virtual 183MB) |
+---------------+---------------+--------------------+

When starting a container, the image that the container is started from is mounted read-only (virtual). On top of that, a writable layer is mounted, in which any changes made to the container are written.

So the Virtual size (183MB in the example) is used only once, regardless of how many containers are started from the same image - I can start 1 container or a thousand; no extra disk space is used. The "Size" (2B in the example) is unique per container though, so the total space used on disk is:

183MB + 5B + 2B

Be aware that the size shown does not include all disk space used for a container. Things that are not included currently are; - volumes - swapping - checkpoints - disk space used for log-files generated by container

https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362


So if it says the size is 0, then that means the writable layer contains no changes?
I can't be sure, maybe a minimal change to a text file will result in 0
there are tools to analyze the image, and you can export to tar.gz, extract, and then use a comparator
e
eiTan LaVi

You can use

docker history IMAGE_ID

to see how the image size is ditributed between its various sub-components.


N
Nathan

Keep in mind that docker ps --size may be an expensive command, taking more than a few minutes to complete. The same applies to container list API requests with size=1. It's better not to run it too often.

Take a look at alternatives we compiled, including the du -hs option for the docker persistent volume directory.


Not the case on my server - runs in milliseconds. YMMV caveat to the above (test, as Sergei says "...may...")
I'm also testing, it's still acceptable using docker ps --size
u
user6070547

Alternative to docker ps --size

As "docker ps --size" produces heavy IO load on host, it is not feasable running such command every minute in a production environment. Therefore we have to do a workaround in order to get desired container size or to be more precise, the size of the RW-Layer with a low impact to systems perfomance.

This approach gathers the "device name" of every container and then checks size of it using "df" command. Those "device names" are thin provisioned volumes that a mounted to / on each container. One problem still persists as this observed size also implies all the readonly-layers of underlying image. In order to address this we can simple check size of used container image and substract it from size of a device/thin_volume.

One should note that every image layer is realized as a kind of a lvm snapshot when using device mapper. Unfortunately I wasn't able to get my rhel system to print out those snapshots/layers. Otherwise we could simply collect sizes of "latest" snapshots. Would be great if someone could make things clear. However...

After some tests, it seems that creation of a container always adds an overhead of approx. 40MiB (tested with containers based on Image "httpd:2.4.46-alpine"):

docker run -d --name apache httpd:2.4.46-alpine // now get device name from docker inspect and look it up using df df -T -> 90MB whereas "Virtual Size" from "docker ps --size" states 50MB and a very small payload of 2Bytes -> mysterious overhead 40MB curl/download of a 100MB file within container df -T -> 190MB whereas "Virtual Size" from "docker ps --size" states 150MB and payload of 100MB -> overhead 40MB

Following shell prints results (in bytes) that match results from "docker ps --size" (but keep in mind mentioned overhead of 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

Further reading about device mapper: https://test-dockerrr.readthedocs.io/en/latest/userguide/storagedriver/device-mapper-driver/


This only works with the non-default devicemapper snapshotter, right?
K
Kai - Kazuya Ito

This is the simplest way:

docker ps -s

l
logbasex

The docker system df command displays information regarding the amount of disk space used by the docker daemon.

docker system df -v