[nydus] Add empty layer in OCI image when merging platforms#352
Merged
imeoer merged 2 commits intogoharbor:mainfrom Sep 22, 2025
Merged
[nydus] Add empty layer in OCI image when merging platforms#352imeoer merged 2 commits intogoharbor:mainfrom
imeoer merged 2 commits intogoharbor:mainfrom
Conversation
bf33c10 to
9ad6d04
Compare
10 tasks
Add an empty tar.gz layer at the beginning of the OCI image that's referrenced in the nydus merged-manifest compared to the original OCI one. This empty layer, being the first layer, will force the OCI image to have a completely different chainID from its original counterpart. This is done so that containerd and other runtimes don't try to reuse the OCI layers for other images that share layers with the original OCI variant. The drawback being that nydus-merged images can't share layers with pure OCI images when they are pulled on non-nydus clients. The choice to use an empty tar.gz layer as the new first layer is because: - this is a format understood by every runtime (on the other hand, docker doesn't understand layers that use `application/vnd.oci.empty.v1+json`) - an empty layer won't change the unpacked digest of the final image - it shouldn't be possible for a regular image (not built using nydus merge-manifest) to start wtih an empty tar.gzip. That's because they would need to be based on `scratch` and any layer they would add will necessary change something on the filesystem so it won't be an empty change Signed-off-by: Baptiste Girard-Carrabin <baptiste.girardcarrabin@datadoghq.com>
9ad6d04 to
7413411
Compare
Contributor
Author
|
Maybe I should hide this behind an additional flag? |
imeoer
reviewed
Sep 19, 2025
pkg/driver/nydus/nydus.go
Outdated
| emptyDescriptor := ocispec.Descriptor{ | ||
| MediaType: emptyLayerMediaType, | ||
| Digest: digest.FromBytes(emptyDescriptorBytes), | ||
| Size: int64(len(emptyDescriptorBytes)), |
Collaborator
There was a problem hiding this comment.
Maybe we should add an annotation to indicate that the layer is a special empty layer? (not block this PR :))
Contributor
Author
Collaborator
It's okay if we only apply this on |
Set the annotation`containerd.io/snapshot/nydus-empty-layer: "true"` on the empty layer that's added in the OCI image. Just to be able to find it easily. Signed-off-by: Baptiste Girard-Carrabin <baptiste.girardcarrabin@datadoghq.com>
287a45b to
7e7bbfd
Compare
imeoer
approved these changes
Sep 22, 2025
Collaborator
|
@Fricounet Thanks! Tagged |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add an empty tar.gz layer at the beginning of the OCI image that's referrenced in the nydus merged-manifest compared to the original OCI one. This empty layer, being the first layer, will force the OCI image to have a completely different chainID from its original counterpart. This is done so that containerd and other runtimes don't try to reuse the OCI layers for other images that share layers with the original OCI variant. The drawback being that nydus-merged images can't share layers with pure OCI images when they are pulled on non-nydus clients.
The choice to use an empty tar.gz layer as the new first layer is because:
application/vnd.oci.empty.v1+json)scratchand any layer they would add will necessary change something on the filesystem so it won't be an empty changeTesting
Testing this change should show that the final nydus image doesn't cause layer reuse issues:
image-a:
image-b:
Converting image-b to nydus with the current release of nydusify
Then pulling both images with containerd:
The final result is that both images share layers
On the other hand, if we use a nydusify built with these changes:
When we pull both images
The first tree corresponds to image-a (sha match with above)
The second tree is the nydus image which now has different digests and 1 additional layer whose chainID
5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6efmatch the value we expect from the empty tar.gz