Skip to content

c8d: align "Size" and "VirtualSize" for images#45347

Merged
thaJeztah merged 1 commit intomoby:masterfrom
thaJeztah:align_size_virtualsize
Apr 17, 2023
Merged

c8d: align "Size" and "VirtualSize" for images#45347
thaJeztah merged 1 commit intomoby:masterfrom
thaJeztah:align_size_virtualsize

Conversation

@thaJeztah
Copy link
Member

In versions of Docker before v1.10, this field was calculated from the image itself and all of its parent images. Images are now stored self-contained, and no longer use a parent-chain, making this field an equivalent of the Size field.

For the containerd integration, the Size should be the sum of the image's compressed / packaged and unpacked (snapshots) layers.

- What I did

- How I did it

- How to verify it

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

@thaJeztah thaJeztah added status/2-code-review area/images Image Distribution containerd-integration Issues and PRs related to containerd integration labels Apr 17, 2023
Comment on lines +203 to +204
// TODO(thaJeztah): include content-store size for the image (similar to "GET /images/json")
return usage.Size, usage.Size + snapShotSize, nil
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wasn't 100% sure here, but given that a container is "image size" + "writable layer size", I think we're missing a size here in the total (if I'm wrong, I'll remove this TODO 😂)

Copy link
Contributor

@vvoland vvoland Apr 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to NOT include the content-store size. Once created, snapshot exists independently from the content. We could even delete the content and the snapshot will not be affected.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. right, yeah. Thinking how the parallel is with pre-snapshottee; I guess in that case we have mounts for the container, and I think we also allow the image to be deleted if there's still a container using it (in which case those layers basically get "re-parented" and now are only used by the container, so will be garbage-collected once the container is gone.

/cc @rumpl @tianon @tonistiigi any thoughts what makes most sense to include?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I noted in the meeting today, I'd personally be surprised to find that the docker image ls listed size doesn't include the layers still in the content store as well as the extracted content in the snapshotter. Just because we can remove the image from the content store when it's extracted doesn't mean we would or even should, and IMO the default top-level size field should absolutely reflect all parts of "this image taking up space" including any content and all snapshotters (ideally).

It'd be great if we could dial into that somehow (maybe a separate struct in the API response that includes the individual details of the content store and each snapshotter/snapshot size?), but I don't think that's critical (especially given we can mostly query that from containerd itself outside of Docker if absolutely necessary).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This affects docker container ls (size of the container), not docker image ls :).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhh, the "xxxB (virtual yyyB)" value, hmm - so that should probably be "xxx" is the size of the RW layer and "yyy" is that plus whatever value docker image ls shows, right? (it'd be weird if docker image ls tells me 20MiB, then a container tells me only 10MiB or something)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! That's the one 🙈

@thaJeztah thaJeztah requested review from rumpl and vvoland April 17, 2023 12:00
@thaJeztah thaJeztah added this to the 24.0.0 milestone Apr 17, 2023
Copy link
Member

@tianon tianon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not ideal, but the difference between VirtualSize and Size has long since been lost, I think (they've been the same in every case I've looked closely at for years now), so I think this is good. 😄

In versions of Docker before v1.10, this field was calculated from
the image itself and all of its parent images. Images are now stored
self-contained, and no longer use a parent-chain, making this field
an equivalent of the Size field.

For the containerd integration, the Size should be the sum of the
image's compressed / packaged and unpacked (snapshots) layers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah
Copy link
Member Author

thaJeztah commented Apr 17, 2023

@thaJeztah thaJeztah merged commit 7103efa into moby:master Apr 17, 2023
@thaJeztah thaJeztah deleted the align_size_virtualsize branch April 17, 2023 21:45
@tianon
Copy link
Member

tianon commented Apr 17, 2023

Here's an example to illustrate why I think including the snapshotter size is really important: (the short version of this is that the compressed content of bash:latest is ~6.1MiB but the unpacked content takes the total all the way up to ~20.4MiB, and that's what I get back if I delete bash:latest)

/ # docker version
Client:
 Version:           
 API version:       1.43
 Go version:        go1.19.8
 Git commit:        67c4570f280ca3c4d40ca69d8686370784bebc04
 Built:             Fri Apr 14 20:32:07 2023
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          dev
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.19.8
  Git commit:       ad2ab4927cb1f95b3767c00f95c9696a5975dd0a
  Built:            Mon Apr 17 20:33:14 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.0
  GitCommit:        1fbd70374134b891f97ce19c70b6e50c7b9f4e0d
 runc:
  Version:          1.1.5
  GitCommit:        v1.1.5-0-gf19387a6
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

/ # du -hsx /var/lib/docker/containerd/
272.0K	/var/lib/docker/containerd/
/ # ctr content fetch docker.io/library/bash:latest
docker.io/library/bash:latest:                                                    resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:e0acf0b8fb59c01b6a2b66de360c86bcad5c3cd114db325155970e6bab9663a0:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:565db8a061f00b6ae93dcfea37faab27b880f644c31e2c0b57e65b94fe84668f: done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:f56be85fc22e46face30e2c3de3f7fe7c15f8fd7c4e5add29d7f64b87abdaa09:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:1eb2595706a1249a9fd53b5e09ca99a98e70bd497edc6f2e34683ba47886b702:    done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:f5c1538e3a18fe20ee8e917e749202f36016df07092278163876a5bf885654d6:   done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:4abd0b518e7b49a663bbe01b70ae16047d3fc7c0f6baa7841c94b6920e005aa1:    done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 2.3 s                                                                    total:  4.6 Mi (2.0 MiB/s)                                       
/ # du -hsx /var/lib/docker/containerd/
6.1M	/var/lib/docker/containerd/
/ # docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
bash         latest    e0acf0b8fb59   8 seconds ago   6.13MB
/ # ctr i pull docker.io/library/bash:latest
docker.io/library/bash:latest:                                                    resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:e0acf0b8fb59c01b6a2b66de360c86bcad5c3cd114db325155970e6bab9663a0:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:565db8a061f00b6ae93dcfea37faab27b880f644c31e2c0b57e65b94fe84668f: done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:1eb2595706a1249a9fd53b5e09ca99a98e70bd497edc6f2e34683ba47886b702:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:f56be85fc22e46face30e2c3de3f7fe7c15f8fd7c4e5add29d7f64b87abdaa09:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:4abd0b518e7b49a663bbe01b70ae16047d3fc7c0f6baa7841c94b6920e005aa1:    done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:f5c1538e3a18fe20ee8e917e749202f36016df07092278163876a5bf885654d6:   done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 0.7 s                                                                    total:   0.0 B (0.0 B/s)                                         
unpacking linux/amd64 sha256:e0acf0b8fb59c01b6a2b66de360c86bcad5c3cd114db325155970e6bab9663a0...
done: 147.279164ms	
/ # docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
bash         latest    e0acf0b8fb59   20 seconds ago   6.13MB
/ # du -hsx /var/lib/docker/containerd/
20.4M	/var/lib/docker/containerd/

(graphdriver-based Docker lists ~13.7MiB in docker images bash:latest, for comparison)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/images Image Distribution containerd-integration Issues and PRs related to containerd integration status/4-merge

Projects

Development

Successfully merging this pull request may close these issues.

containerd integration: verify "Size" vs "VirtualSize" in images

3 participants