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

Support for exporting nydus compression type #2581

Merged
merged 6 commits into from
Nov 8, 2022

Conversation

imeoer
Copy link
Contributor

@imeoer imeoer commented Jan 26, 2022

Related issue: #2046

Nydus image is a container accelerated image format provided by the Dragonfly image-service project, which offers the ability to pull image data on demand, without waiting for the entire image pull to complete and then start the container. It has been put in production usage and shown vast improvements over the OCI v1 image format in terms of container launching speed, image space, and network bandwidth efficiency, as well as data integrity. Nydus image can be flexibly configured as a FUSE-based user-space filesystem or in-kernel FS with nydus daemon in user-space:

  • Lightweight integration with VM-based containers runtime like KataContainers. KataContainers is supported Nydus as a native image acceleration solution.
  • Nydus closely cooperates with Linux in-kernel disk filesystem containers' rootfs can directly be set up by EROFS over Fscache with lazy pulling capability. The corresponding changes had been merged into Linux kernel since v5.19.

Nydus has provided a conversion tool Nydusify for converting OCIv1 image to Nydus image and integrated into Harbor Acceld as a conversion driver, which assumes that the OCI image is already available in the registry, but a better way would be to build the Nydus images directly from the build system instead of using the conversion tool, which would increase the speed of the image export, so we experimentally integrated the Nydus export in Buildkit.

image

A manifest example of nydus image can be found here. Unlike other compression formats (gzip, zstd, eStargz, etc.) in OCI image, nydus is divided into two types of layer, blob and bootstrap, where blob serves as the data and metadata for all files of each layer of the image, and bootstrap serves as the metadata of the whole image, the bootstrap is equivalent to the view of the whole image filesystem after all layers overlay, nydus use this layer form to reduce the number of HTTP request and FUSE overlay's overhead on preparing the container's rootfs. For example, for an OCI image with 3 layers, the corresponding nydus image is 4 layers (3 layers of blob + 1 layer of bootstrap).

The converter package in nydus-snapshotter do the actual layer compression, this PR imports the package to implement the export of nydus compression type.

@imeoer imeoer marked this pull request as draft January 26, 2022 10:54
@imeoer imeoer force-pushed the nydus-compression-type branch 4 times, most recently from 6e3e5de to 6dbd90a Compare January 27, 2022 08:07
@imeoer imeoer marked this pull request as ready for review January 27, 2022 08:08
@imeoer
Copy link
Contributor Author

imeoer commented Feb 7, 2022

@ktock @AkihiroSuda PTAL

cache/converter.go Outdated Show resolved Hide resolved
cache/nydus.go Outdated Show resolved Hide resolved
cache/blobs.go Outdated Show resolved Hide resolved
@ktock
Copy link
Collaborator

ktock commented Feb 8, 2022

BuildKit doesn't seem to be able to use the exported nydus-compressed image and cache.
e.g. the second build in the following with inline cache panics.

# mkdir -p /tmp/ctx
cat <<EOF > /tmp/ctx/Dockerfile
FROM registry2-buildkit:5000/ubuntu:20.04
RUN echo hello > /hello
EOF
# buildctl build --progress=plain --frontend=dockerfile.v0 --local context=/tmp/ctx --local dockerfile=/tmp/ctx \
                 --output type=image,name=registry2-buildkit:5000/ubuntu:20.04-hello,push=true,compression=nydus,oci-mediatypes=true \
                 --export-cache type=inline
# buildctl build --progress=plain --frontend=dockerfile.v0 --local context=/tmp/ctx --local dockerfile=/tmp/ctx \
                 --output type=image,name=registry2-buildkit:5000/ubuntu:20.04-hello-zstd,push=true,compression=zstd,oci-mediatypes=true \
                 --import-cache type=registry,ref=registry2-buildkit:5000/ubuntu:20.04-hello
...
panic: runtime error: index out of range [4] with length 4

goroutine 748 [running]:
github.com/moby/buildkit/cache/remotecache.(*contentCacheImporter).importInlineCache.func1.1()
	/go/src/github.com/moby/buildkit/cache/remotecache/import.go:188 +0xda5
golang.org/x/sync/errgroup.(*Group).Go.func1()
	/go/src/github.com/moby/buildkit/vendor/golang.org/x/sync/errgroup/errgroup.go:57 +0x67
created by golang.org/x/sync/errgroup.(*Group).Go
	/go/src/github.com/moby/buildkit/vendor/golang.org/x/sync/errgroup/errgroup.go:54 +0x92

@imeoer
Copy link
Contributor Author

imeoer commented Feb 8, 2022

BuildKit doesn't seem to be able to use the exported nydus-compressed image and cache. e.g. the second build in the following with inline cache panics.

@ktock Thanks for the testing, the panic indeed occurs.

This seems to be a tricky problem. Nydus image consists of multiple blobs and a bootstrap (one more layer than the cache records), and the blob does not correspond to the cache record one by one (probably fewer layers than the cache record).

Is it possible to consider not supporting the inline cache export for nydus image? Will submit a new commit to do this.

@imeoer imeoer changed the title Support for exporting nydus compression type [WIP] Support for exporting nydus compression type Feb 15, 2022
@imeoer imeoer force-pushed the nydus-compression-type branch 5 times, most recently from 798a223 to a9362be Compare February 17, 2022 04:03
@imeoer imeoer changed the title [WIP] Support for exporting nydus compression type Support for exporting nydus compression type Feb 17, 2022
@imeoer
Copy link
Contributor Author

imeoer commented Feb 17, 2022

@ktock rebased code to resolve the conflicts with the PR and add workaround for inline export on the commit. PTAL.

@imeoer imeoer force-pushed the nydus-compression-type branch 4 times, most recently from 3b53729 to 8c2ce98 Compare February 21, 2022 02:49
Copy link
Collaborator

@ktock ktock left a comment

Choose a reason for hiding this comment

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

Now we seem to have 2 implementation of computeBlobChain(computeBlobChain and computeNydusBlobChain).
Some concerns about maintainability:

  • How can guarantee/keep the compatibility of these implementations?
  • Will we need 2 duplicated patches on these implementations for 1 futural change?

cache/refs.go Outdated Show resolved Hide resolved
exporter/containerimage/writer.go Outdated Show resolved Hide resolved
cache/manager_test.go Outdated Show resolved Hide resolved
docs/nydus.md Outdated Show resolved Hide resolved
@imeoer imeoer changed the title Support for exporting nydus compression type [WIP] Support for exporting nydus compression type Mar 3, 2022
@imeoer imeoer force-pushed the nydus-compression-type branch 6 times, most recently from 56a951b to f26808c Compare October 26, 2022 09:35
@imeoer imeoer changed the title [WIP] Support for exporting nydus compression type Support for exporting nydus compression type Oct 26, 2022
@bergwolf
Copy link

@AkihiroSuda @ktock @tonistiigi With #3136 merged, this PR is pretty clean in terms of code invasion in the general code path. Could you give it another spin and see if it is suitable for merging? As discussed earlier, we'll continue improving the nydus functionality in buildkit and we look forward to putting it into large-scale production use.

Nydus image is a container accelerated image format provided by the
Dragonfly image-service project, which offers the ability to pull
image data on demand, without waiting for the entire image pull to
complete and then start the container. It has been put in production
usage and shown vast improvements over the old OCI image format in
terms of container launching speed, image space, and network bandwidth
efficiency, as well as data integrity. Nydus image can be flexibly
configured as a FUSE-based user-space filesystem or in-kernel
EROFS (from Linux kernel v5.16) with Nydus daemon in user-space,
integrating with VM-based container runtime like KataContainers
is much easier.

Nydus has provided a conversion tool Nydusify for converting OCIv1
image to Nydus image and integrated into Harbor Acceld as a conversion
driver, which assumes that the OCI image is already available in the
registry, but a better way would be to build the Nydus images directly
from the build system instead of using the conversion tool, which would
increase the speed of the image export, so we experimentally integrated
the Nydus export in Buildkit.

Unlike other compression formats (gzip, estargz, etc.) in OCI image,
nydus is divided into two types of layer, blob, and bootstrap, where
blob serves as the data part of each layer of the image, and bootstrap
serves as the metadata of the whole image, the bootstrap is equivalent
to the view of the whole image filesystem after all layers overlay. For
example, for an OCI image with 3 layers, the corresponding nydus image
is 4 layers (3 layers of blob + 1 layer of bootstrap).

The nydus-snapshotter project provides a package to do the actual layer
compression, this commit imports the package to implement the export of
nydus compression type.

Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
For nydus image, appending an extra nydus bootstrap layer
to the manifest, this layer represents the whole metadata
of filesystem view for the entire image.

Nydus uses this extra boostrap layer to reduce the number
of HTTP request and FUSE overlay's overhead on preparing
the container's rootfs.

For now we just support this in image type exporter.

Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
cache/not_nydus.go Outdated Show resolved Hide resolved
docs/nydus.md Outdated Show resolved Hide resolved
util/compression/not_nydus.go Outdated Show resolved Hide resolved
cache/not_nydus.go Outdated Show resolved Hide resolved
cache/nydus.go Outdated Show resolved Hide resolved
exporter/containerimage/writer.go Outdated Show resolved Hide resolved
Introduce nydus image and show that how to export nydus image, and
add known limitations.

Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
@imeoer
Copy link
Contributor Author

imeoer commented Nov 3, 2022

@ktock @AkihiroSuda Updated, please help to take a glance again, thanks!

@imeoer
Copy link
Contributor Author

imeoer commented Nov 7, 2022

Thanks for all! cc @tonistiigi Please help to take a final look, thanks!

@tonistiigi tonistiigi merged commit 5b7315c into moby:master Nov 8, 2022
@hsiangkao
Copy link

Thanks all for considering Nydus!

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

Successfully merging this pull request may close these issues.

None yet

9 participants