Before trying to understand Docker Containers, it’s good to have a basic grasp of how the operating system on your local machine normally works.
Most operating systems have what’s called “a kernel”. A kernel is the core of an operating system. It manages and maintains the operations of the programmes that are running on the computer and the physical hardware — memory, CPU time and Hard Disk. When I say “programmes”, I mean the likes of Chrome, Spotify or the text editor you use to build your code. When you run each programme individually or combined, the OS’ kernel is apportioning sections of the hardware to allow these programmes to run smoothly.
For example, whenever I code, other than my text editor (VS Code), I’d also have Chrome and Spotify running. If I’m coding in Node.js, once I finish and save my file to the hard drive, Node.js communicates to the kernel that it has a file that it wants written and saved to the hard drive. The kernel takes that communication and persists it to the hard disk. So, the kernel serves as the middleperson that links programmes to the hard drive.
The other programmes that I also run will interact with the kernel via what’s called a “system call”. The system call invokes an activity from a programme. The kernel exposes different end points for programmes which enable programmes to interact with the hard drive via the kernel.
For example, imagine a scenario where you’re running two programmes that have are built on the same programming language but individually require a different version of the same language. The hard disk on your local machine has one version of the language installed. How will you be able to run both languages at the same time? Name spacing! Name spacing is an operating feature that looks at all hardware resources connected to the computer and segments out portions of those resources. So it can segment a portion of the hard disk specifically dedicated to housing one version of the programming language and a second segment that houses the other version of the language.
So, when either programme issues a system call, the kernel will look to connect the programme with the segment of the hard drive that has stored the version of the language. With name spacing we can isolate resources per process or via a group of processes. Name spacing is also used to restrict the area of the hard drive available, the network devices available, the ability to communicate with and view other processes or to limit or redirect the request of resources from a particular process. Name spacing says “this area of the hard drive is restricted for this process”… a bit like security at the VIP section of a nightclub.
Control Groups are used to limit the amount of resources that a particular process can use. They can limit the amount of memory, CPU, HD Input/Output and Network Bandwidth that a process can use. These two features combined can isolate a single process and limit the amount of resources it can talk to and the amount of bandwidth that it can make use of.
So, with a basic understanding of how the OS works, what is a container?
A container is a running process along with a subset of physical resources — hard drive, network, RAM & CPU that are allocated to that process specifically. These processes or programmes could be Chrome, Spotify etc.
An image is a snapshot of the file system with a startup command.
Name Spacing and control groups features are specific to the LINUX operating system.
When Docker was installed, a LINUX Virtual Machine was installed. So whenever Docker is running, a LINUX VM is also running. Inside this VM is where all these Containers will be created. Inside the VM is a LINUX kernel which will host running processes inside of Containers. The LINUX kernel will be responsible for sectioning, distributing or limiting access on the local machine.