Containers: Thinking outside the (virtual) box
As a follow-up to my previous article “DevOps: It may not mean what you think it means”, I thought I would take a stab at demystifying another closely linked topic, that of application containers. Whilst containers are not new (they have been evolving since as far back as the 80’s in the Unix world), the emergence of the open source Docker Engine in 2013 greatly accelerated adoption of the technology.
There is often confusion about what containers are and how they differ from virtual machines. Though related, they are in fact fundamentally different concepts.
Simply put, a virtual machine (VM) is a software defined server that runs on top of a physical server or cluster of servers, via a software “hypervisor” (VMWare for example). They are considered an abstraction of the hardware layer. Each VM includes a full copy of an operating system, binaries, libraries and applications and is assigned memory, CPU and disk resources.
Containers on the other hand are an abstraction at the application layer. A container has no operating system, dedicated memory, disk or CPU. Containers sit directly on top of the host server via a “container engine” (such as Docker) and shares the host operating system, binaries and libraries. Containers are standardised, portable packages that hold only the files and data necessary to run an application.
The concept is probably easier to grasp and best illustrated via the below diagram.
So why use containers?
Containers speed up and simplify code deployment, reduce the need to account for dependencies and are generally more efficient in terms of server resources. You can typically run many more containers on the same hardware than you can VMs, which can be a huge cost-saver for smaller applications.
Essentially containers are a way to separate an application from its environment, allowing developers to package an application along with its configurations and dependencies into a single portable piece of code that can run on any operating system and on any infrastructure.
Recommended by LinkedIn
Surely then containers should be replacing VMs as the platform of choice?
To answer this, you need to understand the drawbacks of containerisation as well of course. There are a number scenarios where VMs are still more suitable than containers. Performance critical applications like databases for example are harder to manage successfully in containers, as are multi-user environments, where VMs trump containers in terms of options for security, performance tuning, troubleshooting and system isolation
Migrating to containers also presents a number of challenges for existing applications and legacy environments. There are the inevitable issues of the time, skill and effort required in re-coding applications to enable the “microservice” architecture provided by containerisation.
In simple terms, in order to benefit from containerisation, the fundamental components of an application need to be split into smaller inter-operable parts. Many existing applications are simply too complex, too large or contain proprietary code that cannot be abstracted in this way easily.
Finally large applications can quickly grow to include a massive number of containers, making the management of these disparate parts a serious challenge to DevOps teams. Understanding what is running and where, monitoring performance and ensuring issues of security, compliance and data integrity are addressed requires a different set of tools and skills from the traditional VM deployment model. This is where solutions such as Kubernetes comes into play, but that’s certainly a whole different topic for another day!
At the end of the day, the decision about whether to use containers or VMs is really a case of “it depends”. Both containers and VMs have benefits and drawbacks, and the ultimate decision will depend on your specific needs. As always though, if in doubt, consult an expert!