In this exercise, I am going to play with some building blocks for Linux application container. And the goal is to be able to manually create simplified application containers.
Motivation
After using Docker for about 2 years, I finally try to understand how a Linux application container runtime works. Jérôme Petazzoni’s presentation (slides) explains both concept and implementation details of application container runtime. To me, the most interesting part of the presentation is the live demo of lunching a container without using any container manager/runtime such as Docker or rkt.
One missing part of the demo is that the network setup portion doesn’t full work. So it’s also a good chance for me to review Linux networking to get that work.
Requirement
From a developer point of view, Docker provides more value for deployment. Features like resource limiting by cgroups and copy-on-write storage by btrfs are great in production environments, but might not be that useful if we want to bring container concept into development cycle.
In the other hands, isolation by namespaces are quite useful for development, especially for file system and networking.
There are tools for creating isolated compilation or runtime environments for specific programming languages, such as Virtualenv for Python, RVM for ruby, Go’s native GOROOT
and GOPATH
, but file system isolation would be a simple and one-size-fits-all solution for all kinds of programming languages and tools.
And network isolation would also be pretty useful. Think about that if you want to implement a software load balancer, and want to test with multiple instances of upstream service locally. It’s possible to archive this by
- Tweak upstream services to listen on different ports
- Create virtual network interfaces and tweak upstream service to listen on specific interface
But using network namespace would be a generic solution and require no special tweaking for applications.
So in this exercise, I’ll figure out how to do file system isolation by well-known chroot to change current process root (/
) directory, and use ip
to manage network interfaces and namespace.
Let’s Do It!
Prepare Host Network
|
|
Prepare Container Network
|
|
Prepare Container File System
|
|
Switch to Container Context
|
|
References
- Cgroups, namespaces, and beyond: what are containers made from? YouTube video, slides
- Which of proc, sys etc. should be bind-mounted (or not) when chrooting into a “replacement” distribution?. StackExchange.
- App Container Executor. appc project.
- Accessing graphical applications inside the chroot. help.ubuntu.com.
Also posted on https://www.linkedin.com/pulse/poor-mans-container-steven-chin by Steven Chin.