Deep-dive into exported Container Image content
Chronicles of Containers - Part 9
Hey there! 👋
In the previous article we scratched the surface of Container Image and now I want to do a deep-dive. Specifically, I will take the Windows Nanoserver Image that we exported last time and then explain every single file contained inside of it.
As we usually do - first the infographic and then the additional explanation below it!
(click on image to expand)
First thing that I need to do is export the actual image (if you want to learn the background, check previous article):
The output is a .tar ball. So let’s untar it:
What are these things that we are seeing? What I usually like to say is that Container Image contains “The WHAT” and “The HOW”.
index.json, manifest.json and oci-layout are “The HOW”. As in - they tell the Runtime (i.e. the machinery that starts your containers) HOW to spawn the container, which OSs are supported, how it should behave under each OS, etc. The list of “HOWs” is really huge because there’s really TONS of things that you can tweak.
Great thing is that all these “The HOWs” are clearly defined in OCI (Open Container Initiative) Image Specification. Specifically, there’s a “Image Layout” section that clearly discusses the content:
oci-layout is really not that interesting. All that it contains is the version of OCI that Image was built against:
index.json is an interesting one:
This file represents the Image’s entrypoint. The FIRST PLACE that Runtime will look for when starting the Container. Think of it as a bootstrap file for your container. Here’s what OCI Spec says about it:
index.json represent the Blueprint for HOW to build containers. They are THE HOW part.
Another interesting folder you might have noticed is the
blobs folder. This folder literally contains, as the name implies, bunch of Blobs. Files that could be either texts or binaries of varying sizes. Blobs. And this folder contains THE WHAT. The actual data. And that data could either be additional config files or your Windows OS binaries. But let’s start from the beginning.
If you check previous screenshot, you will see that index.json references a blob under the name of
sha256:b4248836dea118c48481b821d9fbb40daf7e207b48f5e6edc9da6837050b0f65. So what the heck is this? Well, it’s a Digest and it turns out to be a rather useful thing for addressing the content, but I’ll talk more about it in the future. Let’s check what’s inside the “blobs” folder:
It appears that
sha256:b4248836dea118c48481b821d9fbb40daf7e207b48f5e6edc9da6837050b0f65 maps to actual path :) Let’s see what’s inside of it!
Ha, so it appears to be some kind of manifest. Specifically, it’s something called OCI Image Index Specification. It tells the runtime WHICH Images for WHICH Operating Systems exist. And as we can see, we seem to only have ONE set of Images made for Windows 10.
Let’s look up yet another blob that this manifest is pointing to:
Well well, this one seems to be OCI Image Manifest (not to be confused with previous one which is OCI Image INDEX Manifest). This one specifies the actual images for our Operating System and which Layers do they contain. If you’re not familiar with concept of Layers - worry not! They are really powerful technique and I am going to spent the whole next article on them! For now, just think of the Container’s File System as being created by stacking layers on top of each other - Windows OS + Some additional Binaries + Your App’s Binaries = Filesystem for Container.
Apparently we seem to have a single layer only. And that’s because I exported Windows’ Nanoserver Image. I didn’t add any additional layers on top of it.
Can you guess what’s inside this blog? What’s inside
sha256:25550ca2a1c5d341a996152b565fbecf6742f2e123642a941212c6100c3dfb7d? I’ll wait!
The media type for it (i.e. couple of lines above the “digest”) claims it’s a gzipped tarball. So instead of reading it as a text file, let’s try gunzipping it!
# Create new folder "layer0" and extract blob there mkdir layer0 tar -xvf blobs\sha256\25550ca2a1c5d341a996152b565fbecf6742f2e123642a941212c6100c3dfb7d -C layer0\
And this is what I end up with:
Upon closer inspection, “Files” is actually a very slim version of Windows OS, whereas UtilityVM is what I believe to be a lighweight VM used when you use “Hyper-V Isolation mode” (if you’re not familiar with Isolation modes - worry not! There’ll be a separate article about it as well).
And there you have it! :) We just disassembled and described the full content of Container Image.
If you want to check the full OCI Image Specification - it’s available here. But do be warned that it takes some time to actually understand it.
In the next article I’m going to discuss the Image Layers and everything that goes with them. Until then, if you haven’t subscribed already, now’s a good time do so:
Thanks for reading Bitesized Engineering! Subscribe for free to receive new posts and support my work.
If you missed the previous articles, here are the latest three: