Gontainer is a container made for fun and curiosity.
The scope of this project was to better understand Linux namespacing, and apply it to create a rudimental container.
If you have a Go environment ready to go, it's as easy as:
go get github.com/alegrey91/Gontainer
Once you retrieved you are ready to build:
go build github.com/alegrey91/Gontainer
Typing Gontainer -h
the following output will be shown:
Usage: ./Gontainer -run -uid [-mnt=/path/rootfs] [-uts [-hostname=new_hostname]] [-ipc] [-net] [-pid]
-mnt='/path/rootfs' Enable Mount namespace
-uts Enable UTS namespace
-hostname='new_hostname' Set a custom hostname into the container
-ipc Enable IPC namespace
-net Enable Network namespace
-pid Enable PID namespace
-uid Enable User namespace
-v Check Gontainer version
Below there is a full explanation of provided arguments:
- mnt: Mount namespaces control mount points. Upon creation the mounts from the current mount namespace are copied to the new namespace. The clone flag used to create a new namespace of this type is CLONE_NEWNS. [6]
- uts: UTS namespaces allow a single system to appear to have different host and domain names to different processes. The clone flag used to create a new namespace of this type is CLONE_NEWUTS. [6]
- ipc: IPC namespaces isolate processes from SysV style inter-process communication. This prevents processes in different IPC namespaces from using, for example, the SHM family of functions to establish a range of shared memory between the two processes. The clone flag used to create a new namespace of this type is CLONE_NEWIPC. [6]
- net: Network namespaces virtualize the network stack. On creation a network namespace contains only a loopback interface. The clone flag used to create a new namespace of this type is CLONE_NEWNET. [6]
- pid: The PID namespace provides processes with an independent set of process IDs (PIDs) from other namespaces. The first process created in a PID namespace is assigned the process id number 1 and receives most of the same special treatment as the normal init process. The clone flag used to create a new namespace of this type is CLONE_NEWPID. [6]
- uid: User namespaces are a feature to provide both privilege isolation and user identification segregation across multiple sets of processes available since kernel 3.8. With administrative assistance it is possible to build a container with seeming administrative rights without actually giving elevated privileges to user processes. The clone flag used to create a new namespace of this type is CLONE_NEWUSER. [6]
If you are interested in understanding how a containerized process is isolated from the rest of the system, follow the next step.
From your terminal run:
Gontainer -run -uid
The result will be:
[user@real-hostname ~]$ ./Gontainer -run -uid
[Gontainer config]
• mnt: ""
• uts: disabled
• ipc: disabled
• net: disabled
• uid: enabled
📦 [root@real-hostname] ~/home/user ‣
What's happened?
We are trying to running Gontainer
from the home directory of a non privileged user (user
).
Using the flag option -uid
we are mapping our local UID with the container's root
UID.
For this reason, we are root
inside the container. First magic of Linux namespaces!
Commonly called as chroot
this represents the true essence of the system isolation.
First of all, we need a basic root filesystem. If you have docker installed, you can retrieve a rootfs from it:
docker container inspect alpine | grep UpperDir
Just cp -r
the resultant path to /tmp/rootfs
and then:
Gontainer -run -uid -mnt /tmp/rootfs
As you can see, your OS file system has disappeared, leaving space for a new file system (the alpine fs).
- https://medium.com/@teddyking/linux-namespaces-850489d3ccf
- https://medium.com/@ssttehrani/containers-from-scratch-with-golang-5276576f9909
- http://ifeanyi.co/posts/linux-namespaces-part-1/
- https://klotzandrew.com/blog/container-from-scratch
- https://www.infoq.com/articles/build-a-container-golang/
- https://en.wikipedia.org/wiki/Linux_namespaces