A minimal rootless container implementation on Linux. Copied from Inspired by Liz Rice's amazing talk on implementing containers from scratch.
- Rootless: never use
sudo
to run a container - Images: guntainer can build container images, with a
Gunfile
to define the structure.
Install using (Go 1.16+ recommended):
go install github.com/Samyak2/guntainer@latest
(ensure GOBIN
is in path)
Confirm that the installation succeeded.
guntainer help
To run a container image, use the run
subcommand.
See here for more information and examples.
guntainer run --help
To build a container image using a Gunfile
, use the build
subcommand.
See here for more information and examples.
guntainer build --help
guntainer can build new images out of existing ones, in a similar way to docker build
. Images are described using a Gunfile
, whose format is very much a work-in-progress. Following is the structure of a Gunfile (at least the things that currently work):
Using "<archive_of_root_FS>"
Exec "some command"
More examples can be found here.
To build the image from example_02, we can use:
guntainer build example_02.tar examples/02_alpine_vim/Gunfile
This will generate an example_02.tar
which is the newly built image with vim
installed. Run it using:
guntainer run example_02.tar /bin/sh
You should be able to use vim
inside the container now.
These are examples of running an existing Linux distro inside guntainer.
Get the Alpine "mini root filesystem" from here (direct link of the specific version this was tested with).
Run the container with (replace the archive path if necessary) (you can also use sh
instead of ash
):
guntainer run alpine-minirootfs-3.14.0-x86_64.tar.gz /bin/ash
Most programs will work. Running hostname
should say guntainer
.
Internet will not work out of the box as no DNS servers are configured. Use the following to access internet (replace the IP address as necessary):
echo "nameserver 8.8.8.8" > /etc/resolv.conf
Get the Ubuntu Base image from here (direct link to the specific version used).
Run using:
guntainer run ubuntu-base-21.04-base-amd64.tar.gz /bin/bash
Running hostname
should say guntainer
.
Issues:
-
apt
will not work out of the box. Refer this thread for details.Workaround (pls don't run this outside a container):
sed -i '/_apt/d' /etc/passwd
-
Internet will not work out of the box. Workaround:
echo "nameserver 8.8.8.8" > /etc/resolv.conf
- Better CLI using cobra
- Use cgroups for resource limits
- (a bit ambitious) be OCI compliant
- Fix Ubuntu issues
- Dockerfile equivalent
- Download images from URL, like go's package management
- Figure out how to store metadata along with the built image. Could do it similar to docker images (OCI) or do something more hacky.
- Optional logging -
-v
flag should enable more logs.
If you're looking to implement your own container runtime, these links are great to start with:
- Mythili Vutukuru's lecture on containers - provides a good overview of the Linux concepts behind containers (namespaces and cgroups)
- Containers From Scratch by Liz Rice - most of the code is from this talk. Liz Rice implements it live on the stage while explaining how it works.
- The corresponding code respository is a good reference and also links to another slide deck for implementing rootless containers
- The root FS archive is extracted in a temporary directory and
chroot
ed into. The directory is cleaned up once the container exits. - Rootless is implemented by mapping the current user's UID and GID to 0 (root) inside the container. This means that inside the container you are root while the same user outside the container is your user.
- The Gunfile is implemented here. It uses participle to parse the Gunfile and build an AST.
- To save the built image I had to implement a custom tar wrapper to handle in-container symlinks. I called it guntar.
MIT