VMs vs. Containers for Microservices
What makes more sense for an enterprise?
Join the DZone community and get the full member experience.Join For Free
In my previous post, I talked about how enterprises can achieve continuous delivery of applications using microservices and containers. Here, I delve deeper to compare containers and VMs from a microservices architecture viewpoint.
In this era of constant evolution, we hear a lot of talk about using containers for microservices and the need to modernize monolithic applications. But, there is always an impending question for an enterprise that arises next and is rarely addressed — why not use VMs instead of containers?
Virtual machines offer virtualization of hardware as well as the OS and create an efficient, isolated duplicate of a real machine. In the case of containers, only the OS is virtualized and not the hardware, creating a lightweight environment that houses the application and the dependent assets. Containers have continued to gain popularity since 2014 and virtual machines have existed for a very long time, the difference between the two is known to all. As the world keeps comparing the two, it is imperative to remember both are here to serve different purposes.
I like to think virtual machines are to containers what trains are to aeroplanes. While aeroplanes offer much faster mobility, we are always going to have trains around for some journeys that aeroplanes are not equipped to handle. Likewise, in certain business situations, containerization may be the prefered choice and in some, virtualization.
But when microservices come into the picture, the question to “containerize or virtualize” seems to be frequent.
Benefits of Using Containers Over VMs for Microservices
VMs make it easy to partition execution environments among microservices by virtualizing hardware as well as operating systems. When you are executing every microservice through a separate VM, that requires replication of the OS as well. This will increase licensing costs. It is possible to execute multiple microservices in a single VM, but that would negate the single biggest advantage of breaking down a monolithic application into small, easily executable microservices. The issue of conflicting libraries and application components will remain unsolved.
Containers offer isolation at the OS level. Thus, a single operating system can support multiple containers, each running within its own, separate execution environment. By running multiple components on a single operating system you reduce overhead licensing costs.
It is common knowledge that VMs often impose a large performance penalty by using up server processing cycles which can be used to run applications instead. Every virtual machine runs its own execution environment on a separate copy of the operating system exhausting server processing cycles that you otherwise could have used to run the applications.
On the other hand, containers perform environment isolation at the operating system level. This way, a single operating system can support multiple containers, each running within its own separate, isolated environment. By running multiple components on a single operating system, containers reduce the overhead server processing cycles thereby freeing up processing power for other application components.
VMs have multiple options for storage. They can either have a local or a network-based storage type. Whichever option you choose, there will always be a physical disk space allocated to every VM which is isolated from the VM itself. So, at all times, the operating system, program files, and data of a VM occupy storage space on the dedicated storage disk — stateful storage.
In contrast, containers, offer the choice of being stateful or stateless. Storage space is created or occupied when the container is created and discarded when it's deleted. A sandbox layer is created when a container image is edited and that stores all the data. This layer is active only as part of the container. Thus, each service of your microservices app can have its own storage, that can be managed differently from the storage of other services providing more flexibility and control.
As mentioned above, containers offer independent execution environments to microservices while enabling cohabitation on a single operating system. The databases, as well as the environments of microservices, are completely independent, despite being deployed on a single OS. If one tries to run multiple microservices on a single VM, there can be overlapping environments which may end up clogging up the server.
With containers, one can make the most out of a given piece of hardware by smart application processing. For example, some microservices require a lot of processing power, while others may generate a lot of network traffic. With smart workload allocation within containers, app developers can efficiently utilize server resources, ensuring network capacity is not left unused.
VMs, as we know, take up a lot more storage space than containers. A container is typically as small as 10MB whereas a VM occupies at least a few GBs of storage space. While segregating a complex application using a microservices architecture, where each functionality is a separate microservice, the isolation will require a large number of VMs or containers. VMs are bound to require a lot of space while containers will not. The same physical server can hold many more containers than VMs. So, given the need to ensure the enterprise app does not become too bulky, containerization is often the preferred choice.
VMs are created by a hypervisor that needs a lot of configurational decisions at the start — the guest OS for running the application, amount of storage space needed, network preferences, and many such settings. Though VMWare offers preset defaults in its creation wizard of VMs, the process still remains pretty complex and takes a couple of minutes to be executed on a platform. On the other hand, containers are created faster than VMs due to the absence of a hypervisor. Container images are stored in a repository from where they can be accessed as required through a few quick commands. Thus, the startup time for Docker containers ranges from a few milliseconds to a couple of seconds which makes it much faster than a VM.
Executing containerized microservices at scale can be further simplified by using container orchestrators like Kubernetes and Docker Swarm. Docker containers can be quickly launched, retired, and replaced at scale with such orchestrators. To further enhance working with microservices and containers, one can use app delivery platforms designed exclusively to overcome modern delivery challenges for an enterprise. An app delivery platform can help accelerate, standardize, and sustain the complete process of containerization and subsequent delivery to orchestrators.
In reality, every enterprise comes with its own needs, requirements, and legacy systems. In the choice between VMs and containers, the latter is better suited for packaging microservices. So, if one is looking at a scalable and flexible modern architecture for their teams, containers are their best bet to ensure continuous delivery.
Published at DZone with permission of Spruha Pandya. See the original article here.
Opinions expressed by DZone contributors are their own.