Docker and its Containers
Senuri Wijenayake, PhD
Lecturer | School of Computing Technologies | RMIT University
Docker is a trending form of server virtualization. Out of the many popular use cases, docker is well known as a technology that enables developers to wrap their development environment (source code, run time environment etc.) along with the dependencies, all embedded in its own file system. Docker uses the concept of containers (well known as Dockers) to spin up the same environment as in you server computer, on your local machines, as many times as required using a Docker image (user defined or from a public/private image registry).
Docker is written in Google’s Go language and has the following main components.
- Linux kernel to convert instructions to machine understandable format
- Cgroups and namespaces to facilitate isolation, security and optimum use of CPU and memory resources
- Union file system
- libcontainer execution driver
All in all, to understand Docker, a thorough understanding of containers is essential. And thus, in this blog post i would be covering the basics of containers, how they came into practice and why.
It’s all about the applications
Earlier, each application required a separate server, and that meant a separate physical machine, with its own operating system, licensing, network and storage resources. This was no doubt extremely expensive and consumed a significant time to set up thus, leading to increased time to market our applications.
And even then, each application server consumed not more than 10% of the total server resources! This was clearly an eye raiser, and people started looking for more resource efficient solutions.
Enters the Virtual Machine
Virtualization is basically creating a virtual (not real) version of something.
In this case, since one physical machine for each application server was too much of a cost and less efficient in terms of resource utilization and time to market, it was identified that multiple applications can run on fictitious hardware or virtual hardware facilitated using a single machine’s resources.
Further explaining the concept, a single physical machine was carved up to be multiple virtual machines, each pretending to have its own hardware. This is accomplished with the help of a Hypervisor.
Thus, VMs were capable of shifting the server technologies from multiple applications on multiple machines to multiple applications on a single machine. That seemed like a significant achievement at that time. But it was not before long the ugly side of the VMs became visible.
Remember, It’s all about the applications!
As i mentioned before, the primary idea is to find an efficient way to run our applications. That said, even though Virtual Machines were a significant improvement than having a separate physical machine for each server, a bit too much importance was given to the operating systems.
Each VM can run one application and would also require its own operating system. And each OS consumes CPU, RAM and expensive licences! This was not the ideal solution.
This brings us to the question, what exactly is required to run an application?
In very basic terms, in order to run an application we would require a secure and isolated environment with bare minimum operating system services.
Keeping that in mind, let’s now look into containers.
Introducing Containers (An Application Run time Environment)
A container in day today life is simply a large box where items could be put in and packed together. The large metallic containers that we see on dockyards are commonly used for transportation of goods, and have evidently increased the portability of goods.
Docker uses the same concept in “Docker Containers” and is defined as a standardized and well defined container which can be used to include your entire application and then hosted on any environment running Docker regardless the underlying platform. It wraps up your piece of software, along with everything it needs to run, onto a single container. Thus your software can now be shipped and immediately hosted on multiple environments without having to worry about the dependency issues.
Further, whenever we hear about containers, the words “light-weight” and “resource efficient” always come into use. This is ideally, when containers are compared to VMs. Why exactly is this?
Comparing the two concepts, an application needs a full blown VM to run in the old approach, while it can now run in an individual container. Container are lightweight because, unlike in a VM it does NOT include a full operating system inside and runs on top of the host OS. Containers are ideally, isolated user spaces that include only the bare minimum OS services required to run an application. It is also capable of facilitating comforting levels of security to our application servers with the help of certain kernel services such as namespaces and capabilities (will be looked into later in this article).
Digging Deep into Containers
Before looking into containers in detail, let me rephrase our objective here.
Why are containers lightweight and yet isolated, secure and resource efficient just as a VM? What makes it all possible?
Namespaces for Isolation
Isolation is a super important requirement in application servers. We can’t ideally put multiple applications on a single user space because of the lack of isolation. Applications usually need different versions of the same libraries and this can’t be accommodated without isolated spaces for each application.
A container is ideally an isolated instance of the user space. Each container has its own root file system, process tree etc. Therefore the process running in one container can’t communicate with a process in another container and nor can it access any files placed in another container.
This user space isolation is acquired via kernel namespaces. The system namespaces such as the pid, net, mnt etc. are sub-divided into partitions and then assigned to each container. Thus each container has access only to its own processes, root access and network resources.
cGroups for Efficient use of Resources
cGroups in short for Control groups, is a kernel feature that enables the user to control the resources allocated to each container in terms of CPU time, memory, network bandwidth etc. Each container can have its own cgroup allocation, determining how much CPU time, system memory and bandwidth should be used by the application running within the container.
This is important when having multiple containers, to manage the resources among the different applications in an optimum manner. This can be determined when using Docker’s run command in the context of Docker containers.
Capabilities for Security
Traditionally, there are root users with all privileges and non root users with almost no privileges. Capabilities are used to break the privileges of a root user into separate privileges that can be assigned independent of one another. So that each container can be assigned the privileges that it only require for its processes.
Capabilities is a concept that is important for security (give them only what they need), and Docker facilitates that.
In summary, containers are super lightweight, isolated, secure userspaces that can facilitate a runtime environment for your application. In this blog post, we discussed about how containers came into being and why they are so popular right now. In the next post we will look into Docker containers directly and the main components of Docker.
Hope this helped :)
Data Engineer
8 年Good work :) keep it up!
I love automation
8 年Containers may not be super light weight. For it to be super light weight it must be based on a busybox or alpine base container. If CentOS container is used it adds about 380mb on top of OS. So usually we need to use stipped down version of OS such as CoreOS or Atomic host. Though I agree containers will have a great future I still love to see someone like Red Hat providing minimal base image which we can build our applications.
Research Technician at SOKA University -Faculty of Engineering
8 年worth to read