When talking about containers, in a technical context, the first thing that might come to mind could be Docker or even Kubernetes. However, Docker is a platform where you can create containers and perform other operations with them. There are other open-source container runtimes such as CRI-O and LXC, but Docker is one of the most popular.
In this article, we will be explaining what containers are, how they work, and some of their benefits. We will also compare them to virtual machines, and we will explore the concept of container orchestration.
Containers are composed of container images as a method to package software and its dependencies, namespaces for resource isolation, and Linux kernel cgroups for resource limits, such as CPUs, RAM, etc.
The Linux kernel cgroups, or control groups, limit resource utilization by processes or, in our case, containers. The resources that cgroups can control include CPU, memory, and network, among others.
For example, you can assign a certain amount of memory to a process with cgroups. Cgroups also allow you to have different shares of CPU from the host system. And lastly, you can use cgroups to measure resource usage.
Namespaces, on the other hand, limit what the processes within a namespace can see. Namespaces allow isolation for containers and prevent them from seeing the file systems of others. In short, namespaces make it possible for containers to have their own file system, network, and user namespace - among other namespaces.
Container images are a set of files and directories needed to create containers and run software in them. These images are composed of layers. The concept of layers is that they allow you to combine files and directories to create a unified view.
Layers provide a Copy-on-Write (CoW) view of the files in the image, which means that whenever you add a file, it will not be duplicated until it is written to it; so if you have a file that only needs to be read, the file won’t be duplicated.
To implement layers, you need to use a Union file system (FS), such as OverlayFS or AUFS, which can provide merged views of files. The two file systems, OverlayFS and AUFS, are used by Docker to manage images and layers.
UnionFS can help you start new containers very efficiently. This is because there is no need to duplicate the whole image; you can create a new container just by adding a new empty layer at the top for each one. Adding an empty layer allows a container to have its own writable space without interfering with others.
This entire process of packaging software with all dependencies, application code, and files needed to run applications in containers is known as containerization.
Containers, in a way, containerize the host operating system (OS) by running the application directly on the host CPU and talking to the host system kernel. This gives you the ability to run several of them in a single OS.
With containers, you can easily share the server's storage, memory, network, and CPU resources among different applications. Additionally, even when sharing the server's resources, they are independent of each other, which provides isolation for your applications.
Another great benefit about containers is their Portability. Because containerized applications come with all dependencies, libraries, and configuration files already packaged, you can deploy your applications anywhere. You do not need to worry about needing a specific OS or server or whether you want to deploy your application on-prem or in the cloud; this makes containerized applications easy to deploy.
A Virtual Machine (VM), as the name suggests, is a computer system on top of a physical computer or a physical server. VMs, as well as containers, can be used to deploy applications. However, VMs need an additional OS on top of the host OS. This is already a problem because needing a different OS means you need to allocate resources specifically for that OS.
Additionally, the VMs not only need an extra OS, but similarly to containerized applications, they also need the libraries, binaries, and any necessary files to run the application.
Suppose you want to deploy three applications, so you create three VMs on your personal computer because you can only run one application in each VM. Besides the OS in your computer, you will need three extra OSs, one for each VM. Adding three extra OSs takes up a lot of space from the system.
In addition, you need all the files required by your applications. And, if one of your VMs takes up all the resources in your system, you won’t be able to run the other two applications. Although VMs allow you to package applications and run them in complete isolation, VMs are not as efficient as containers.
As we mentioned before, containers talk to the host kernel, so they do not require a different OS as VMs do. VMs are usually much larger than containers and also require a lot more memory than containers. VMs also take longer to boot compared to containers, which can start very quickly. In summary, with containers, your resources are not wasted by virtualization of hardware, additional OSs, and simulation of block storage. These are just a few of the reasons why containers have proven to be more efficient than VMs.
In summary, with containers, your resources are not wasted by virtualization of hardware, additional OSs, and simulation of block storage.
Although containers are great to run applications anywhere, you could encounter several issues if you try to manage several of them manually. If you use them just for testing or have very few in your environment, you could probably manually manage them. However, if you are planning on creating a large containerized infrastructure or data center, then this is where things get more complicated.
Managing an extensive containerized infrastructure includes having a scheduler to know where to run your containers. You need to be able to seamlessly move them and know where to place them so that your applications keep running smoothly. You also need a load balancer to redirect traffic to the proper server; otherwise, you might overload some of them with too much traffic while others don't get any.
Additionally, you need to monitor the container's health, as some of them might completely fail, and you will need to replace them right away. Some of them might malfunction, and they can start using more resources than needed; in such a case, you will need to identify the faulty container and then replace it. You also need to control how your containers access resources such as storage or network.
You need to consider several other things when you have a large infrastructure, and as you could imagine, manually managing this type of infrastructure is impossible. Even if it were possible, it would be very inefficient. That's why you'd need a container orchestrator, which can do all the things we mentioned above and much more.
With such an orchestrator, you can automate the tasks required to run containerized applications. In other words, to have a reliable containerized infrastructure, you’d need a suitable container orchestrator. And a great example of that is Kubernetes.
Kubernetes allows you to automate the tasks that are needed to successfully deploy containerized applications. Kubernetes offers great features to orchestrate containers and to make sure that they properly run your applications.
If you want to learn more about Kubernetes and how it works, check out our next article: What is Kubernetes and How It Works. In this article, you will learn what Kubernetes is and how it works. And we will also explore some of the major Kubernetes components.