Container Deep Diving: Part 3
After looking at the nitty gritty functionality of containers in Part 2 lets make life a bit easier now. First by making this post a short one and secondly by using tools for abstracting away the manual labour that had to be done in order to switch namespaces and set them up. For this lets take a look at container runtimes.
While you have probably heard of and used Docker lets talk about the common layer that underlies modern Docker and other runtimes.
Open Container Initiative Specification
The OCI specs were written to gain control over the container landscape. After all it would not help anyone if every company would create and run containers in their own fashion.
To make it clearer simply think about containers in the real world. It does not matter who stores their stuff inside a container. Every container ship can transport it. If on the other hand you start building your very own spherical containers you are probably going to run into problems at the harbor.
Same situation for the cloud. Whatever system you run at your desk, the container you pack should run everywhere you need it to run (CI/Staging/Production/Colleagues machine etc.).
So the OCI runtime specs set a few rules that programs that want to be compliant must follow, and if followed the programs are then compatible with all those OCI containers out there.
Whats under the hood?
In case you do not want to read the whole spec yourself let me give you some of the most important points:
- every container is run via a config.json
- Container runtimes are programs that read the
config.json
and start the namespaced processes from them - The container initialization process has lifecycle hooks defined inside the Spec
And that is pretty much it. Most of the spec describes the fields of the config.json
-> Root directory on the Host, Capabilites, Networking and many other things you could need.
But what about all the dependencies that the process inside the container needs? Since this is all about packaging and not running the container another spec comes into the picture. The OCI image spec.
The gist of the spec is as follows:
- the filesystem is stored in
.tar
packaged layers - each layer represents a change to the file-system and the layers have to be applied in order
- an
index.json
file contains all the information on the order of layers and all the necessary information to create theconfig.json
for the runtime from it
How do both fit together?
Simple. You download/build an image bundle as specified in the image spec, you convert into a usable root-directory and a config.json
, the runtime can then run the container as specified in the runtime spec.
And thats it for the the OCI specs. While there is a third spec as well I will leave it out here since it is all about distribution of the image bundles.
Now what?
I will not go ahead and write a runtime from scratch for this post, sorry. To be honest it sounds like fun, but I am going back to university next week to get me one of those master degrees and it is just too much work right now.
Since I still have to pay the bills feel free to contact me if you think I could be of help on your project! I should be able to squeeze in 20hrs per week starting August when I am comfortable in the new environment.
Now let me leave you with the teasered podman vs. docker. And to your surprise this one is going to be short.
Both achieve the goal of making your work with containerized processes easier just fine, but the design behind them is quite different.
Docker
Docker is a program that runs an always-on daemon in the background on your system. It is consistently waiting to do work and you will find that most people that know containers can probably use it to some degree. Everything you want to do with your containers is included in this big boy (building, running, releasing).
Podman
Podman on the other hand really just starts your container into the desired state and then stops running. It is a program that is the interface into a whole suite of container tools. Not monolithic, but split over different projects that have different responsibilities.
Which to chose?
It really just boils down to preference, as both support the spec. Just use what speaks more to your philosophy on how to run your systems.
Whats my philosohy?
Use podman.
The main reasons for this are the top-notch integration into Linux’s systemd and the lack of a daemon (less things to worry about.)
Recap
So, that was it for my container tech deep dive.
Lets finish it off with a quick recap:
- chroot is the container granddaddy (part 1)
- Namespaces, bind-mounts and c-groups are the actual things behind the container name (part 2)
- the OCI specs makes sure that containers run on any machine you encounter if it has a compliant runtime installed
Hopefully you found this helpful, I surely learned new things when writing this little 3 part series.
If there is any info you are missing, or I misrepresented anything please just let me know in the comments.
Stay tuned via RSS and happy hacking.