The enterprise approach to application deployment has changed dramatically over the last 20 years.
As low-cost commodity servers replaced mainframes throughout the late 90s and early 2000s, companies finally found an affordable way to isolate their applications from one another.
They were able to deploy just one main service to each physical machine. They could configure each server to suit the resource and security needs of the application it hosted. And when a server went down only one application would be affected.
This led to huge growth in the number of servers within the data center—which not only became increasingly unmanageable, but also resulted in many servers being underused.
Then came a new era of virtual machines (VMs). These made better use of computing resources by making it possible for the same hardware to host more than one server, each behaving as an individual machine in its own right.
But, in the last few years, organizations have started to adopt a different method of partitioning infrastructure and a new type of application architecture—using containers and microservices respectively.
This guide briefly explains what containers and microservices are, as well as their advantages, disadvantages and the symbiosis between them.
What Are Containers?
Containers are a lightweight alternative to VMs for providing isolated operating environments for your workloads.
They use a different method of abstracting resources where, instead of using a hypervisor, containers share the kernel of the host operating system (OS).
As a result, they avoid the infrastructure overhead of a full-blown OS and provide only the resources, such as installations, dependencies and code, your application actually needs.
This means they can stop and start more quickly in response to fluctuating scaling requirements and offer better overall performance than VMs.
What Are Microservices?
A microservice architecture is an approach to software design where an application is broken down into a distributed array of loosely coupled services.
Each microservice performs its own specific function independently of the other microservices that make up your application.
You can deploy a microservice to a dedicated VM. And, in some cases, it may make sense to do so. However, in general, microservices are better suited to containers, which offer fine-grained control over resource allocation and more efficient use of your computing capacity.
In addition to better performance and a lower infrastructure footprint, containerized microservices are typically more robust than a traditional monolithic application.
For example, if you deploy an entire application to a VM, when the machine goes down then the whole application goes down with it. But, with containers, you can replicate microservices across a cluster of smaller VMs. So, in the event of VM failure, the application will still be able to use the other microservices in the cluster and continue to function.
In addition, you can update the code and patch the operating environment of each microservice individually and independently without interruption to the overall running of your application, helping to eliminate maintenance downtime.
Containerized microservices also make life easier for developers. Each microservice is a relatively small independent component, which allows a coder to work on their own specific task without getting unnecessarily involved in the complexity of the application as a whole.
Moreover, containerized applications give them the freedom to code each service in the language that suits them best, as long as that component performs its intended role and can interface with other services.
Containers are also highly portable and easy to use in Continuous Integration (CI) and Continuous Delivery (CD) pipelines, helping to boost productivity even further.
Finally, each microservice has a smaller attack surface and is isolated from other microservices, making it harder for a security breach to spread from container to container.
Microservice architecture is rapidly becoming the application design of choice for highly scalable and cost-efficient workloads, But it’s not a silver bullet.
For example, it may be unsuitable for legacy applications, where the work involved in rearchitecting the codebase could prove a complex and costly logistical nightmare.
In addition, applications based on microservices are more complicated to test and deploy. They’re also based on dynamic infrastructure, where containers are continually booting up and closing down. This can potentially make monitoring, deployment and management more challenging.
And, because containers are disposable, ephemeral environments, you’ll need a method of writing data to persistent storage outside of your containers.
Container orchestration tools provide you with a means to provision, configure, coordinate, scale and monitor your containers across your microservice clusters.
The main open-source solutions include Kubernetes, Mesos and Docker’s native clustering engine Swarm. Kubernetes is the most widely used. But each product brings something slightly different to the table, such as flexibility, depth of features and ease of use.
Fundamentally, all orchestration engines are able to:
- Allocate compute resources between containers
- Add or remove containers in response to application workload
- Manage interaction between containers
- Monitor the health of containers
- Balance the load between microservices
As enterprises adopt container technologies, solution architects face the challenge of how best to decompose applications into smaller autonomous services.
Microservices patterns are a set of established topologies they can use to model their own application architecture.
The concept of microservices patterns is relatively new and still evolving. But the common patterns currently emerging are based on the following strategies:
- Splitting up a large legacy application designed for a range of uses into smaller containerized tasks that perform more discrete business functions.
- Gradually replacing existing functions within an application with individual containerized components until the entire system is fully refactored.
- Using different microservices to serve different browser formats (desktop, mobile and tablet).
- Creating both composite container services that only delegate tasks and single-focus microservices that perform those individual tasks.
- Designing a network of services for maximum performance and resiliency.