Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
thaJeztah opened this issue Jul 25, 2022 · 0 comments · Fixed by #45347
Closed

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

thaJeztah opened this issue Jul 25, 2022 · 0 comments · Fixed by #45347
Labels
area/images containerd-integration Issues and PRs related to containerd integration kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny

Comments

@thaJeztah
Copy link
Member

thaJeztah commented Jul 25, 2022

Description

When looking at the API response for GET /images/json with containerd integration enabled, I noticed that Size and VirtualSize were not the same;

curl --unix-socket /var/run/docker.sock 'http://anyhost/images/json' | jq .
[
  {
    "Containers": -1,
    "Created": 1678271418,
    "Id": "sha256:d8dc78532e9eb3759344bf89e6e7236a34132ab79150607eb08cc746989aa047",
    "Labels": null,
    "ParentId": "",
    "RepoDigests": [
      "mysql:latest@sha256:d8dc78532e9eb3759344bf89e6e7236a34132ab79150607eb08cc746989aa047"
    ],
    "RepoTags": [
      "mysql:latest"
    ],
    "SharedSize": -1,
    "Size": 155450613,
    "VirtualSize": 584658944
  },
  {
    "Containers": -1,
    "Created": 1681236201,
    "Id": "sha256:acaddd9ed544f7baf3373064064a51250b14cfe3ec604d65765a53da5958e5f5",
    "Labels": null,
    "ParentId": "",
    "RepoDigests": [
      "busybox@sha256:acaddd9ed544f7baf3373064064a51250b14cfe3ec604d65765a53da5958e5f5@sha256:acaddd9ed544f7baf3373064064a51250b14cfe3ec604d65765a53da5958e5f5"
    ],
    "RepoTags": [
      "busybox@sha256:acaddd9ed544f7baf3373064064a51250b14cfe3ec604d65765a53da5958e5f5"
    ],
    "SharedSize": -1,
    "Size": 2594229,
    "VirtualSize": 4993024
  }
]

However, they are expected to be the same or at least, that's what the API documents it as;

Total size of the image including all layers it is composed of.

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

This field is kept for backward compatibility, but may be removed in
a future version of the API.

The new containerd integration shows different sizes for Size and VirtualSize;

VirtualSize: virtualSize,
ID: img.Target().Digest.String(),
Created: img.Metadata().CreatedAt.Unix(),
Size: size,

snapshotSizeFn := func(d digest.Digest) (int64, error) {
if s, ok := sizeCache[d]; ok {
return s, nil
}
u, err := snapshotter.Usage(ctx, d.String())
if err != nil {
return 0, err
}
sizeCache[d] = u.Size
return u.Size, nil
}
chainIDs := identity.ChainIDs(img.RootFS.DiffIDs)
virtualSize, err := computeVirtualSize(chainIDs, snapshotSizeFn)

func computeVirtualSize(chainIDs []digest.Digest, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {
var virtualSize int64
for _, chainID := range chainIDs {
size, err := sizeFn(chainID)
if err != nil {
return virtualSize, err
}
virtualSize += size
}
return virtualSize, nil
}

Whereas the old implementation considered them equal;

Size: size,
VirtualSize: size,

VirtualSize was a concept from "before" Docker 1.10, where images were not self-contained, and had "parent" images; in this situation Size was the size of the image, and VirtualSize the size of the image including the layer-size of all its parents.

However, starting with Docker 1.10, images are self-contained, which means that an image contains a list of all of its layers, so Size became an equivalent for VirtualSize.

investigate using containerd's WithSnapshotUsage()

We currently get image Size using image.Size(), which includes the size of the Manifest (and compressed layers???);
https://github.com/containerd/containerd/blob/8c27ce41930c52d2a536ff1c31d80ffdc01845e6/image.go#L162-L164

We should look into containerd's WithSnapshotUsage , which looks to include the size of the snapshots as well (which looks to be a close(r) match to what we want to present?
https://github.com/containerd/containerd/blob/8c27ce41930c52d2a536ff1c31d80ffdc01845e6/image.go#L94-L101

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/images containerd-integration Issues and PRs related to containerd integration kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant