stargz-snapshotter

repository·main·Indexed 23 days ago

https://github.com/containerd/stargz-snapshotter

A containerd plugin that enables 'lazy pulling' of container images using the eStargz format. It reduces container startup times by fetching image data on-demand. The project includes the containerd-stargz-grpc service and the ctr-remote tool for image conversion and workload-based optimization. It is compatible with OCI/Docker specifications and supports integration with Kubernetes, BuildKit, Kaniko, and nerdctl.

Tokens
23K
Snippets
39
Records
126
Agent score
76%

What's inside stargz-snapshotter

  1. What is Stargz Snapshotter and eStargz?

    main

    Stargz Snapshotter is a containerd snapshotter implementation designed for lazy pulling. Instead of waiting for a full image download to complete before starting a container, it allows containers to run by fetching necessary image chunks on-demand.

    eStargz is the lazily-pullable image format used by this project. Key characteristics include:

    • OCI/Docker Compatibility: eStargz images are compatible with standard OCI/Docker specifications and can be pushed to standard registries (e.g., ghcr.io).
    • Runtime Compatibility: They remain runnable on eStargz-agnostic runtimes like standard Docker.
    • Optimization: Unlike basic lazy pulling (which can slow down file access), optimized eStargz images allow the snapshotter to prefetch and cache likely accessed files during container execution to mitigate performance drawbacks.
  2. What is eStargz and how does it enable lazy pulling?

    main

    eStargz is a backward-compatible extension to OCI and Docker gzip image layers designed for lazy pulling.

    In standard container images, the entire layer must be extracted before files can be accessed. eStargz solves this by allowing runtimes to fetch and extract only the necessary files (or specific chunks of large files) on-demand during container execution. This significantly reduces cold start times.

    Key features include:

    • On-demand fetching: Runtimes use the Table of Contents (TOC) to find file offsets and fetch them via HTTP Range Requests.
    • Prefetching: Supports pre-loading files to mitigate runtime performance latency.
    • Backward compatibility: eStargz-formatted images can be pushed to standard registries and run on eStargz-agnostic runtimes (which will simply treat them as standard gzip layers).
  3. Directory cache behavior in passthrough mode

    main
    When FUSE passthrough mode is enabled, the [directory_cache] setting direct = true is applied by default. This setting is enforced even if it is explicitly set to false in your configuration file, because read operations after opening a file are handled directly by the kernel in this mode.
  4. What are Stargz Snapshotter and Stargz Store?

    main

    The project provides two distinct plugins to enable lazy pulling of eStargz images depending on your container runtime:

    1. Stargz Snapshotter: A plugin for containerd (v1.4.2+) that implements the remote snapshotter interface. It communicates with containerd via gRPC over a Unix socket to provide remotely-mounted eStargz layers.

    2. Stargz Store: A plugin for CRI-O or Podman that implements the additional layer store interface. It provides remotely-mounted eStargz layers through a specific filesystem structure.

    Stargz Store Filesystem Structure

    CRI-O/Podman access eStargz layers via a mounted filesystem at <mountpoint>/base64(imageref)/<layerdigest>/ containing:

    • diff: The extracted eStargz layer.
    • info: JSON-formatted metadata for the layer.
    • use: Files used to notify the system of layer usage (for Garbage Collection).
  5. Monitor image layer fetching via the State Directory

    main

    Stargz snapshotter uses FUSE to mount eStargz layers. At the root of the container filesystem, a hidden state directory /.stargz-snapshotter is created for status monitoring. This directory is hidden from getdents(2) (so ls -a won't show it), but you can access it directly by path.

    Each JSON file in this directory corresponds to a layer and contains:

    • digest: The layer digest (matches the image manifest).
    • size: Total size of the layer in bytes.
    • fetchedSize: Number of bytes currently fetched.
    • fetchedPercent: Percentage of the layer downloaded. When this reaches 100, the layer is fully local and no further network access is required.

    Note: The directory layout and JSON structure are subject to change.

  6. Understand eStargz landmark files

    main

    eStargz uses specific landmark files to manage the boundary between prioritized and non-prioritized files within the archive:

    • .prefetch.landmark: A mandatory regular file entry placed at the boundary between the prioritized files group and the non-prioritized files group. It must have 4 bits of content 0xf.
    • .no.prefetch.landmark: A mandatory regular file entry that MUST be contained in the archive if no prioritized files are present.

    Both landmarks must be recorded in the TOC as a TOCEntry.

  7. Verify eStargz content integrity

    main

    eStargz ensures the integrity of metadata (TOC) and file contents (chunks) using digests. Verification relies on the following metadata being present in the verified manifest:

    1. TOC Verification: The layer descriptor referencing the eStargz layer must include the annotation containerd.io/snapshot/stargz/toc.digest. This value is the digest of the TOC. The snapshotter recalculates the TOC digest and compares it to this annotation.
    2. Content Verification: Each TOCEntry for a regular file (reg) or a chunk must contain a chunkDigest property. This property holds the digest of the content of that specific entry. The snapshotter recalculates the digest of fetched chunks and verifies them against the chunkDigest recorded in the verified TOC.
  8. The structure of an eStargz blob

    main

    An eStargz-formatted blob is a gzip-compressed tar archive containing a metadata component called the TOC (Table of Contents).

    To enable seekable access, the structure follows these rules:

    • Each non-empty regular file and each metadata component (TOC, Footer) MUST be separately compressed as gzip.
    • Gzip headers MUST be located at the top of the blob, the top of the TOC tar header, the top of the footer, and the top of the payload of each non-empty regular file entry (except the TOC).
    • Chunking: Large regular files may be split into multiple smaller gzip members called chunks. In this case, gzip headers may be located at arbitrary locations within the payload of the regular file entry.
    • An eStargz blob is a concatenation of these gzip members, remaining a valid gzip blob.
  9. How FUSE manager affects Stargz Snapshotter restarts

    main

    The behavior of the snapshotter during a restart depends on whether the Fuse Manager is enabled:

    FUSE manager is DISABLED

    • Killing containerd-stargz-grpc unmounts all snapshots.
    • On restart, snapshots are remounted via lazy pulling.
    • If a snapshot fails to mount during restart, behavior is controlled by allow_invalid_mounts_on_restart:
      • true: Failed snapshots remain as empty directories. You must manually remove them using ctr snapshot rm.
      • false: containerd-stargz-grpc fails to start. Manual recovery (e.g., wiping state) is required.

    FUSE manager is ENABLED

    • Killing containerd-stargz-grpc with a non-SIGINT signal (like SIGTERM) does not affect snapshot mounts. The Fuse Manager keeps the mounts active, so running containers remain available.
    • This allows for reloading configuration without interrupting workloads.
    • To perform a graceful upgrade/restart of the Fuse Manager itself, follow these steps:
      1. Stop containers using Stargz Snapshotter.
      2. Stop containerd-stargz-grpc using SIGINT (triggers unmounting and cleanup).
      3. Kill the stargz-fuse-manager process.
      4. Restart containerd-stargz-grpc.
      5. Restart the containers.
  10. How IPFS-enabled OCI images work with lazy pulling

    main

    An IPFS-enabled OCI image contains descriptors where the urls field includes an IPFS URL in the format ipfs://<CID>. The <CID> must be the Base32 case-insensitive CIDv1 of the blob.

    Lazy Pulling Behavior:

    • With eStargz: If the image is formatted as eStargz and you are using the Stargz Snapshotter, the snapshotter mounts the blobs from IPFS to the container's rootfs using FUSE. This allows the container to start immediately, fetching only the necessary file chunks from IPFS on-demand.
    • Without eStargz (or using overlayfs): If the image is not eStargz or you are using a different snapshotter (like overlayfs), containerd will fetch the entire image from IPFS and unpack it locally before starting the container, resulting in a slower cold-start.
    # Example OCI descriptor pointing to an image index of an IPFS-enabled image
    {
      "mediaType": "application/vnd.oci.image.index.v1+json",
      "digest": "sha256:80d6aec48c0a74635a5f3dc106328c1673afaa21ed6e1270a9a44de66e8ffa55",
      "size": 314,
      "urls": [
        "ipfs://bafkreiea22xmjdakorrvuxz5yeddfdawoox2uipnnyjhbknejxtg5d72ku"
      ]
    }
  11. Run Stargz Store for Podman using podman unshare

    main

    After configuring storage.conf, you must start the stargz-store process within the namespace managed by Podman using the podman unshare command.

    Run the following command to start the store in the background, ensuring you provide the correct paths for the data and store directories:

    podman unshare stargz-store --root $HOME/.local/share/stargz-store/data $HOME/.local/share/stargz-store/store &
  12. Use eStargz with an external TOC

    main

    An optional feature allows separating the TOC into a separate TOC image to create smaller eStargz layer blobs.

    Requirements for External TOC:

    • The eStargz layer blob must contain a special footer (an empty gzip stream with an Extra header containing STARGZEXTERNALTOC).
    • The TOC image is an OCI image containing the stargz.index.json file in its root directory.
    • Layer descriptors in the TOC image must include the annotation containerd.io/snapshot/stargz/layer.digest, which points to the corresponding eStargz layer blob digest.

    How Stargz Snapshotter finds the TOC image: Stargz Snapshotter assumes the TOC image follows the naming convention of the original image plus the -esgztoc suffix.

    Example: If the eStargz image is ghcr.io/stargz-containers/ubuntu:22.04-esgz, the snapshotter will look for the TOC image at ghcr.io/stargz-containers/ubuntu:22.04-esgz-esgztoc.

    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:64dedefd539280a5578c8b94bae6f7b4ebdbd12cb7a7df0770c4887a53d9af70",
      "annotations": {
        "containerd.io/snapshot/stargz/layer.digest": "sha256:5da5601c1f2024c07f580c11b2eccf490cd499473883a113c376d64b9b10558f"
      }
    }