Skip to content

Comments

compression: add zstd:chunked compression type#6528

Open
JakeCooper wants to merge 1 commit intomoby:masterfrom
JakeCooper:zstd-chunked-compression
Open

compression: add zstd:chunked compression type#6528
JakeCooper wants to merge 1 commit intomoby:masterfrom
JakeCooper:zstd-chunked-compression

Conversation

@JakeCooper
Copy link

Summary

Add support for zstd:chunked as a compression option for image layer export. This enables partial/lazy pulling by consumers that understand the format (e.g. podman, containers/storage).

When specified via --output "compression=zstd:chunked", each file in the tar stream is compressed as an independent zstd frame with a table of contents (TOC) appended as a zstd skippable frame.

Format

The output blob structure follows the containers/storage zstd:chunked spec:

[FILE_1][FILE_2]..[FILE_N][SKIPPABLE FRAME: TOC][SKIPPABLE FRAME: FOOTER]

Where each [FILE_N] is an independently compressed zstd frame containing the tar header + payload for that file, and the TOC contains file metadata (name, size, offset, digest) enabling consumers to fetch individual files without downloading the entire layer.

Key design decisions

  • Same OCI media type as zstd (application/vnd.oci.image.layer.v1.tar+zstd) — fully backwards-compatible. Registries and runtimes that don't understand zstd:chunked simply decompress it as a regular zstd blob.
  • Decompression reuses existing zstd decompressor — no changes needed on the pull side for non-chunked-aware consumers.
  • Wraps the containers/storage compressor — the implementation in containers/storage/pkg/chunked/compressor is explicitly designed for standalone use by external callers and is well-tested in production by podman and buildah.

Usage

docker buildx build \
  --output "type=image,compression=zstd:chunked,push=true,name=registry.example.com/myapp:latest" \
  .

Impact

  • Fedora has adopted zstd:chunked as the default for container images, reporting up to 90% faster pulls for incremental updates.
  • This bridges the gap between BuildKit (which produces images) and the containers/storage ecosystem (which consumes them with partial pulling).

Changes

  • util/compression/zstdchunked.go (new) — implements the Type interface
  • util/compression/compression.go — registers the new type and adds it to the parser

New dependency

github.com/containers/storage/pkg/chunked/compressor — lightweight, standalone package. Most of its transitive deps (klauspost/compress/zstd, opencontainers/go-digest) are already vendored in BuildKit.

Related: #2345

Add support for zstd:chunked as a compression option for image layer
export. When specified via `compression=zstd:chunked`, each file in
the tar stream is compressed as an independent zstd frame with a
table of contents (TOC) appended as a zstd skippable frame. This
enables partial/lazy pulling by consumers that understand the format
(e.g. podman, containers/storage) while remaining fully backwards-
compatible with standard zstd decompression.

The implementation wraps the well-tested compressor from
containers/storage/pkg/chunked/compressor, which is explicitly
designed for standalone use by external callers.

Key design decisions:
- Uses the same OCI media type as zstd (backwards-compatible)
- Decompression reuses existing zstd decompressor
- Skips conversion if layer is already zstd-compressed

Related: moby#2345

Signed-off-by: Jake Cooper <jake@railway.com>

"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/core/images"
chunkedcompressor "github.com/containers/storage/pkg/chunked/compressor"
Copy link
Member

Choose a reason for hiding this comment

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

I don't really like we consume an unrelated package just for zstd compression for a module not directly aimed at compression. If anything I think it should be either vendored here with tests or use a proper module. Also github.com/containers/storage is deprecated and has moved to https://github.com/containers/container-libs/tree/main/storage.

Copy link
Member

Choose a reason for hiding this comment

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

Also vendor is not updated in your PR (go mod vendor).

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.

2 participants