Kubernetes is a container orchestration system which is used to manage containers grouped in pods which are hosted on nodes. To do that Kubernetes uses an agent called kubelet which uses a Docker (or another container runtime or container engine) which uses a container runtime (once again?) to manage the container lifecycle.
🛑 HOLD ON!
So much layers, terms, and dependencies here. It is not easy to understand how all these components work together. Especially, when some of terms are used interchangeably.
😉 Don't worry.
I will clarify those uncertainties in this series. I will take you on a journey to understand the concept of containers and containerization, and their terms one by one. From bottom to top. From the smallest units, which are system resources and process. At the end of the day, they compute and store your data, not Kubernetes.
In this post I will explain the terms related to containers and images, and a bit of the operating system.
🧭 Let's start the journey!
- Table of contents
- Terminology on the schema
- Operating system specific terms
- Containers and images specific terms
I prepared a map 🗺️ for you to not get lost in the terminology journey.
The following schema shows the relationship between the terms.
* Docker is only one of container runtimes and can do much more than presented in the map. I will explain it with details in the next post from this series.
A process of an operating system is an instance of a computer program that is being executed by one or many threads. It is a basic unit of work.
A resource is a hardware of software component managed by an operating system. Resources are allocated to processes to perform some work.
Sample Linux resources:
- net - network interfaces
- mnt - file system mount points
- pid - process ID space
- uts - hostname and NIS domain name
- user - user and group IDs
- ipc - inter-process communication mechanisms.
A Linux namespace is functionality of the Linux kernel that isolates and virtualizes system resource. Processes can only interact with resources or processes that are part of the same namespace. Namespaces exist for each type of resource.
Namespaces provide isolation of system resources, and cgroups allow for fine‑grained control and enforcement of limits for those resources.
A control group (cgroup) is a Linux kernel feature that limits, accounts for, and isolates the usage of resources by a collection of processes. Docker relies on cgroups to control and isolate resource limits.
In the context of containers, cgroups limits the resources that each container can consume. cgroups ensures the container has the resources it needs to function properly.
SELinux (Security-Enhanced Linux) defines access controls for the applications, processes, and files on a system. It uses security policies, which are a set of rules that tell SELinux what can or can’t be accessed. When an application or process makes a request to access an object, like a file, SELinux checks with an access vector cache (AVC), where permissions are cached for subjects and objects. If SELinux is unable to make a decision about access based on the cached permissions, it sends the request to the security server. SELinux supports mandatory access control (MAC).
SELinux is used by containers to control accesses withing them.
AppArmor (Application Armor) is security module that you can use to restrict the capabilities of processes running on the host operating system. Each process can have its own security profile. The security profile allows or disallows specific capabilities, such as network access or file read/write/execute permissions. It proactively protects the operating system and applications from external or internal threats. AppArmor supplements the traditional Unix discretionary access control (DAC) model by providing mandatory access control (MAC).
For any given container, you can apply either the default AppArmor security profile, or a custom security profile that you provide.
Most popular Linux distributions contain pre-installed one or both of those security modules.
You could have gotten hold of an impression that SELinux and AppArmor were remarkably similar to each other. It is true. Here you can dive into the comparison between them: https://www.maketecheasier.com/selinux-vs-apparmor/.
In computer operating systems, union mount is a technique to mount multiple directories into one that appears to contain their combined contents.
It is a technique used to optimize the performance of file systems by copying of a resource only when it is modified. Non-modified resources are shared between the original and the copy of an operation.
OverlayFS is the union mount implementation included in the Linux kernel since the version 3.18. It implements the copy-on-write technique by overlaying file system layers on top of another one and interacting with the merged result.
A container is a running instance of an image. It is a standardized package containing software along with dependencies, configuration, data, and everything that is needed to run.
From the operating system point of view, a container represents an isolated process (or group of processes) that exists in its own namespace. Processes inside the container do not see processes outside it and vice versa. The container cannot access resources belonging to another container or process resources outside the container.
A volume is a directory on a host machine that is mounted into one or more containers. It is used to store persistent data outside of the container. It is independent of the container lifecycle. There are three types of Docker volumes:
- host volume - lives on the Docker host file system and can be accessed from within the container
- named volume - is managed by Docker, where it is created on disk, but is given a name
- anonymous volume - is similar to the named volume, but it can be difficult to reference the same volume over time; the volume is managed by Docker, where the files are stored.
An image is a read-only template that is used to create a container. It contains an ordered collection of changes to the root file system and the corresponding execution parameters for use at container runtime. The change of the file system is called a layer. They are stacked on top of each other starting from a base image or from scratch.
The base image is usually the latest version of an operating system. It is usually a minimal image, which contains only the operating system and few basic tools.
A layer is a modification of an image, represented by a Dockerfile instruction. To create the final image, layers are sequentially applied to the parent image or to the root. When the image is updated or rebuilt, only changed layers need to be updated. Unchanged layers are cached locally to be reused.
When a container is created, a writable layer is created on top of the image. It is a layer that can be modified by the container to store changes made to the container. The writable layer is discarded when the container is deleted.
Sample tools that implement the build process:
Build’s context is a set of files located in the specified
URL. The build process of an image can refer to any files in the context. For example, your build can use the Dockerfile
COPY instruction to reference the file in the context.
A Dockerfile instruction is a command that is executed during the build process. The instructions are executed in the order they are written in the Dockerfile. An instruction can be:
CMDis a statement that is run by default when the container is started, but can be easily overridden if the container is started with a command.
ENTRYPOINTis set to a single command. Even if you don't specify
ENTRYPOINT, it can be inherited from a parent image. It is not overridden even if the container is started with a command. To override
ENTRYPOINTyou can use the
--entrypointoption of the
The instructions are reduced to run the command according to the pattern:
<ENTRYPOINT> <CMD>. Therefore,
CMD can be used to pass default arguments for the command in
Pretty much terms you just learned, aren't they? I gathered them from different sources for you to have a quick reference.
The list is not complete, but it should be enough for you to jump into the world of Docker right now. You've just learned terminology of container components.
Next time I will show you what kind of tools manage them. You will get know what is and what isn't a Docker.
What is the difference between a container engine, a container runtime, and Docker Engine? How does Kubernetes interact with Docker? Does it even use Docker?
I hope you enjoyed this article. If you found it helpful or just liked it, share it with your friends.