Skip to content

Latest commit

 

History

History
130 lines (92 loc) · 4.94 KB

README.md

File metadata and controls

130 lines (92 loc) · 4.94 KB

guntainer

A minimal rootless container implementation on Linux. Copied from Inspired by Liz Rice's amazing talk on implementing containers from scratch.

Features

  • Rootless: never use sudo to run a container
  • Images: guntainer can build container images, with a Gunfile to define the structure.

Getting started

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

Building images

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.

run Examples

These are examples of running an existing Linux distro inside guntainer.

Alpine

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

Ubuntu

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

TODO

  • 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.

Resources

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

Implementation details

  • The root FS archive is extracted in a temporary directory and chrooted 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.

License

MIT