How do COWs (Containers on Windows) work?
Chronicles of Containers - Part 5
Hey there! 👋
What a better to spend your Sunday than reading a bit on containers, eh? :) I actually planned on sharing this article on Tuesday but it opened so many things to think about that I just couldn’t wait. As usual, here’s an infographic, and the expanded description can be found below it:
(click on image to enlarge
Few words (and graphics) on how containers talk to underlying Kernel. Even though Linux and Windows are rather different, when it comes to containers, there are some commonalities:
➡ "Container Daemon" (containerd) works on both systems and is used as a main vehicle for starting, stopping and managing the lifecycle of containers. Think of it as a stagehand whose main job is to prepare the environment (i.e. set permissions, create groups, etc.) for container to execute, ensures that they are running smoothly and, when needed, cleans up after them.
➡ Once the Container is started, it somehow has to communicate to underlying OS (remember the previous article on "Container is not a VM"?). And this is where the "runtime engine" comes into a play. A layer between the actual container and Host Operating System's Kernel. Container sends lower-level commands to runtime engine, which in turn forwards them to Host's Kernel.
➡ And this is the main point where Linux and Windows diverge (and also where future articles will start diverging, as I will be focusing on Windows exclusively). Linux uses "runc" (feel free to look it up) as it's runtime engine, whereas Windows uses "hcsshim". But WTF is hcsshim, right? Good luck pronouncing a word with a single syllable. It's shorthand for "Host Compute Service Shim", or "HCS Shim" if you will.
➡ The story behind this seems to require a bit more explanations, which I will be doing over time, but short version is -- when it comes to executing processes, Windows and Linux are fundamentally different. And Docker (which borrowed stuff for OCI initative) used to rely on the way Linux does things, which is not really available in Windows. In order to leverage that, Windows team created a layer above Kernel, called "Host Compute Service", which provides some low-level access to Kernel. And in order to expose this to Docker, a "shim" was created in Go language which is nothing more but a bridge between HCS and Containers on Windows. These shims are publicly available on Github and currently have Go and C# versions available.
➡ Long story made short - Containers use hcsshim to communicate to Kernel and, as such, get a same effect as it is on Linux.
📕 And there you have it. Building blocks from which you can further explore if you want. If not - well, at least you should be equipped with a mental picture on how this works one level deeper :)
🚢 In future articles I will start digging deeper into HCS and Container Networking. and as I said, I will focus exclusively on Windows Containers on Windows (i.e. WCOWS).
Other articles in the Container series:
Containers are like The Truman Show (Part 4 of the series) - some words on the fact how Containers see themselves (and what really happens on the outside).
Intro to Container Networking (Part 6 of the series) - provides introduction to how networking works inside containers.
What is Container Network Interface (CNI)? (Part 7 of the series) - deeper-look into how networking is configured at runtime.