go-csv-samples
is an open-source implementation of a basic container build from scratch in Go solely for learning
purpose. It uses namespaces and cgroups, mount a tmpfs that's isolated from host filesystem.
Note: Before starting, you will have to extract the content of
ubuntu-fs.tar.gz
file into./os-root-fs/ubuntu
which will be mounted as the container's root directory.
Note: You will have to be inside a Linux box (Ubuntu in my case) to try this.
The example 5-isolate-cgroup-sample
is the full implementation, and it needs root privilege for creating cgroup
:
sudo su
go run main.go run /bin/bash
It will:
- Fork itself with
CLONE_NEWUTS
,CLONE_NEWPID
,CLONE_NEWNS
flags with isolated hostname, processes and mounts - The forked process will create
cgroup
to limit memory usage of itself and any child process it creates - Mount
./ubuntu
directory as root filesystem usingchroot
to limit access to host machine's filesystem - Mount
/newtemp
directory as tmpfs. Any change made to this directory will not be visible from host. - Mount proc (where
CLONE_NEWPID
namespace was already set) so that container can runps
and see only the processes running inside it. - Execute the supplied argument
/bin/bash
inside the isolated environment
- Building Containers from Scratch with Go by Liz Rice If you don't have access to Building Containers from Scratch, Liz Rice gave several talks on the same topic in other conferences. One of them is "GOTO 2018 โข Containers From Scratch".
- Building a container from scratch in Go
- Containers from scratch: The sequel
- Build Your Own Container Using Less than 100 Lines of Go
- Understand Container by Bin Chen
I have used Windows to develop the container from scratch and have run it inside Ubuntu in a virtualbox by sharing the
development directory. While this setup is fine for running the code inside Linux, the development experience is not
great because a lot of pieces of this application is Linux specific. For example, calls like syscall.Sethostname
or
the Cloneflags
field in the syscall.SysProcAttr{}
struct is not available in intellisense in VSCode when the dev
environment is not Linux. VSCode will mark those lines as errors, because they are platform specific and declared in
the standard library in Go for Linux only.
Fortunately, there is a workaround, and it is very simple. Search for "go.toolsEnvVars"
in VSCode settings, copy it to User Settings and change it to:
"go.toolsEnvVars": {
"GOOS": "linux"
}
Now restart VSCode and after that it will recognize all Linux specific declarations and will not see them as errors.
Go-to-definition
will work properly too.
PS: the contents of
ubuntu_fs.tar.gz
file has been extracted from Ubuntu docker image by usingdocker export...
command.