In the short span since containers burst to the infrastructure scene, various different types of containers have been introduced, and new ones — or at least new marketing terms for the existing ones — get introduced every six months. Continuing on the theme of providing basic container ecosystem information on top of which either my co-founder/CTO John Kinsella or I can build more complex explanations, I am going to cover the various types of containers in this post and the next one. While explaining the types of containers, I will also cover the pros and cons associated with each one of them.
This Container or That Container??? Which Container?
When you start digging into containers, you will come across the terms: ‘OS Container,’ ‘Application Container,’ ‘Hyper Container,’ ‘Privileged Container,’ ‘Unprivileged Container,’ ‘Microkernel Container,’ ‘Unikernel Container’ – the types of some of which may be obvious but not the purpose.
So, let’s begin with the most commonly used container type.
This type of container contains an application and all of its dependencies — environment, configurations, libraries etc in it. When a container of this type is run, it could be run either with user space privileges in which case it’s also referred to by just the term ‘Container’ or with root privileges in which case it’s referred to as a ‘Privileged Container.’ An application container running without any root privileges is also referred to as an ‘Unprivileged Container’ in certain container ecosystems (such as LXD).
An application container doesn’t include any execution environment separate from its host. Meaning, no typical Operating System (OS) functionality of process, memory, task or storage management etc is included in an Application Container. Additionally, this container type doesn’t include any device drivers, network protocol stacks or file systems that are typically included in a monolithic regular OS.
Currently, the most common approach is to run one application per container, or even just one module of an application per container, leading to typically just one process running in the container. That’s not to mean that multiple processes can’t be run in a container — web servers, such as Apache, typically spawn off multiple child processes to handle the client requests. It’s also getting increasingly common, among those who have used containers for a while, to first run some type of a management or a monitoring process in the container before launching the actual application.
An OS of a particular type, especially an open source one such as Linux, could have various distributions. All distributions of an OS include the same base kernel, of a particular version, but have their own distribution-specific device drivers, file system, network protocol stacks etc. Ubuntu, CentOS, Debian, RedHat are some of the examples of Linux distributions.
When distribution specific bundles — device drivers, file system etc — are brought into an application container, the container becomes an OS Container. OS Containers run on the same underlying kernel but the distribution-specific ancillary functionality (that are typically in the Ring 1 and 2 of an OS) are brought in. The primary purpose of such containers is to test how an application will behave in those different OS distribution environments.
It’s important to remember that OS Containers still don’t have an execution environment in them hence are still significantly different from Virtual Machines (VMs).
As I mentioned briefly above, Privileged Containers are regular application containers, or even OS containers, that are launched with root privileges. From a security point of view, privileged containers are very dangerous and, if you ask me, should never be used in production, as with such containers you add root privileges to a user space entity. Additionally, if the application running in a privileged container is accessible over the internet, a compromise situation would result in malicious party having access to the host system.
Of late, a few monitoring and “security” solutions for containers use a Privileged Container based approach. Though that approach is the easiest way to get information about other containers running alongside a Privileged Container, such solutions are usually the result of force-fitting something that was built for the VMs and is being applied to the containers. If that container running with root privileges is compromised, it could easily be used to access, alter and modify the applications running in other containers and their data, and could also be used to change the underlying kernel itself.
Privileged Container based solutions also require ownership of the underlying Container-As-A-Service (CaaS) infrastructure which means that such solutions would not work for applications running on a public CaaS (one of the first native CaaS, Carina from Rackspace — doesn’t allow Privileged Containers). Owning the CaaS infrastructure also means that the solution is not easily portable across even the public Infrastructure-As-A-Service (IaaS) providers, while having to pay for both the CaaS as well as the IaaS services.
In part two I’ll discuss Unikernels, Microkernels, Hyper containers and others. Check back soon!
(P.S.: I would love to hear from you, in the comments section, on which container type you are currently using, or thinking of using, and why.)