Skip to content

A basic container runtime and container management system; developed for learning purposes; written in Go.

Notifications You must be signed in to change notification settings

jmuia/go-container

Repository files navigation

go-container

A basic container runtime and container management system; developed for learning purposes; written in Go*.

The time spent coding, researching, and debugging errors is much more valuable than this code will ever be.

* first time ever writing Go; be wary!

Asciicast demos

Features

Namespaces and cgroups

Executes processes in separate mount, UTS, PID, IPC, and network namespaces.

Provides option to control resource usage with the CPU shares and memory limit cgroups.

pivot_root jail and private mounts

"Jails" processes with a pivot_root, limiting their view of the file system.

Mount changes don't propagate between the host and container.

Special file systems and devices

Special file systems and devices are created per the Open Containers spec for Linux.

/proc, /dev, /sys and more are mounted. Devices like /dev/null, /dev/urandom, etc. are also created.

Copy on write containers

Manages container images and creates copy-on-write copies using the Overlay file system.

Bridge network

Creates a veth pair for each container and adds them to the goContainers0 bridge. The host system can communicate with the containers and the containers can communicate with each other (if added to the same subnet).

Environment

Sets up a clean environment with it's very own hostname and a fancy PS1.

Usage

Usage: sudo ./go-container [OPTIONS] <image name> <command>
  -bridge-addr string
    	CIDR bridge address; replaces current if present (default "10.10.10.1/24")
  -c string
    	directory to store containers (default "containers")
  -container-addr string
    	CIDR container veth address (default "10.10.10.2/24")
  -cpu int
    	cpu shares (relative weight)
  -i string
    	directory to find container images (default "images")
  -mem string
    	memory limit in bytes; suffixes can be used

Alpine Linux is included in the repository. A basic example looks like:

sudo ./go-container alpine /bin/sh

Run/Install

The easiest way to try it out is using Vagrant (ironically, I had trouble with Docker capabilities). If you want to do it yourself, use the steps in the Vagrantfile as a guide.

# this may take a while to apt-get update
vagrant up --provision

# ssh into the vm
vagrant ssh

# run as root, in root's GOPATH
sudo su
cd /root/go/src/github.com/jmuia/go-container/

# run a container
./go-container alpine /bin/sh

What's missing?

  • Containers must be run as root and privileges are not dropped when exec'ing the process.
  • User namespaces.
  • Cgroup namespaces (unavailable in Go).
  • Idiomatic Go. go-container is my first time ever using Go; it's not particularly nice code.
  • Tests!
  • More features... Docker does a lot.

Testing

I'm learning a ton of new things from this project: namespaces and cgroups; concept of layering file systems; general Linux systems things; and Go! Adding a test suite is too much "new" (at least, for now).

Instead, I've documented some of the manual testing I did in TESTING.md.

Bugs?

Open an issue or submit a PR. go-container is not bulletproof. For example, during testing I found odd cases where I couldn't do certain operations on a VirtualBox shared directory mount.

As an aside, Go had some limitations with some syscalls and programming patterns due to aspects of its runtime design.

Resources

go-container was guided by:

About

A basic container runtime and container management system; developed for learning purposes; written in Go.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published