CRFS is a Google project that aims at running a container without pre-pulling the image first.
The idea is quite smart: an OCI layer (that is basically a compressed tarball), is modified in a way that it is possible to seek content inside of it and access a single file. It is designed around the stargz (Seekable tar.gz) format. Instead of having a single compressed tar stream, the stargz modifies it to concatenate the gzipped stream of each file. Old clients are still able to handle the stargz’ipped stream as a regular .tar.gz file.
In an attempt to support CRFS with fuse-overlayfs, I’ve worked on adding a plugin system to fuse-overlayfs (https://github.com/containers/fuse-overlayfs/pull/119). It will make possible to extend it and support different ways to retrieve data from the lower layers.
The second step is a plugin that can handle CRFS, it is still a PoC but seems to work quite nicely: https://github.com/giuseppe/crfs-plugin
To create a stargz image, you’d need to use stargzify
# go get -u github.com/google/crfs/stargz/stargzify
Once stargzify is installed, an image can be converted as:
# stargzify docker.io/fedora docker.io/gscrivano/test:stargz
2019/10/24 20:33:33 pushed blob: sha256:c7155ae298b145d79e75c396ab5cb917023c4fd8b9cf8c7ff2f0332b41ef8651
2019/10/24 20:33:34 pushed blob: sha256:5a419d36bce538fa32fc21cbe11134ccbd70597379d9320f3a32eb6be78e4ad5
2019/10/24 20:33:35 docker.io/gscrivano/test:stargz: digest: sha256:ca6723c15c5b3b0947deef12048ee64126ed237e112cfbde300ce0f4066a4b4d size: 428
The image was pushed to the registry. Let’s create a container:
# mkdir lower upper workdir merged
# export DATA=$(echo -n docker://docker.io/gscrivano/test:stargz | base64 -w0)
# OPTS=fast_ino=1,plugins=/path/to/crfs-plugin.so,lowerdir=//crfs/$DATA/lower,upperdir=upper,workdir=work
# fuse-overlayfs -o $OPTS merged
The image, passed to fuse-overlayfs encoded in base 64, is mounted at the merged directory.
# ls merged/
bin dev home lib lost+found mnt proc run srv sys usr
boot etc hosts lib64 media opt root sbin tmp var
To run the container, we can take advantage of the Podman –rootfs feature. It tells Podman to not manage the storage for the container, but to use the specified path as its rootfs.
# podman run --rm -ti --rootfs merged /bin/sh
sh-5.0#
Now we are in a container where files from the lower layers will be loaded on demand when requested.