Article

Why should you use microservices and containers?

What to expect when you're working with microservices and containers

What are microservices? A microservices architecture splits your application into multiple services that perform fine-grained functions and are part of your application as a whole. Each of your microservices will have a different logical function for your application.

Traditional applications have monolithic architectures where all your application's components and functions are in a single instance; microservices break apart monolithic applications into smaller parts. The following diagram compares monolithic and microservices architectures.

Diagram showing the architecture of a monolithic application on the left and the architecture of a microservices applicaton on the right

So, where do you put your microservices? In containers.

What are containers? Containers are packages of your software that include everything that it needs to run, including code, dependencies, libraries, binaries, and more. Docker and Kubernetes are the most popular frameworks to orchestrate multiple containers in enterprise environments. Compared to virtual machines (VMs), containers share the operating system kernel instead of having a full copy of it, such as making multiple VMs in a single host. Although it's possible to put your microservices into multiple VMs, you would typically use containers in this case since they take up less space and are faster to boot up.

Why use a microservices architecture?

The microservices architecture was created to address problems caused by monolithic applications. Microservices are already widely used, and some large-scale websites already transformed their monolithic applications to microservices.

Some benefits of using a microservices architecture are:

  • Developers will work on a smaller codebase compared to a larger one in a monolithic app. When components of the application are loosely coupled, developers will easily understand the source code and not slow down development. Not to mention, your IDE will be faster if you're working with a lesser number of lines of code. Developers will not need to deal with the complexities and dependencies of functions that can be found in a monolithic app.
  • Responsibilities of the developers will be more defined. A team can be assigned by components or microservices of the app. Code reviews will be faster. Making updates will be quicker and there would be no need to build and deploy everything compared to a monolithic app.
  • The application's technology stack can differ through microservices. The application will no longer need to depend on one language or library. Microservices can leverage different programming languages as developers see fit. It is possible to have polyglot microservices such as the ones in the diagram below.

    Diagram of polyglot microservices, where Service A in Node.js is shown to lead to either Service B in Java or Service C in Python

  • Continuous delivery will be easier. Compared to a monolithic app, you will not need to deploy everything again for a simple change with microservices. You may choose to rebuild and deploy the only microservice that needs to be updated. Frequent updates will be faster.

  • Scalability will be independent to each microservice. You can choose to scale each component of your app depending on the resource it needs. You wouldn't need to make multiple instances of everything compared to a monolithic app. Scaling the microservices will efficiently use the resources available instead of having multiple copies of the whole application in a monolithic app.

    Diagram that shows how each microservice can independently scale from the others

  • Data can be decentralized. You can choose to use different databases or storage for your microservices. You can choose a NoSQL database if your microservice suits it better than a relational database. A microservice may also only need a simple key-store database such as Redis. As in the diagram below, you can choose a combination of Cloudant, MySQL, and MongoDB databases. You can take advantage of different databases to store different data types.

    Diagram that shows how each service may choose to use a different database that other services

  • Isolate failures. An error or a bug in one microservice does not bring the entire system down. When you have loosely coupled components and a microservice in your application hangs or throws errors, there's less chance that other microservices will be affected since they are in their own containers and don't entirely depend on each other. A monolithic app can bring the entire process of your application down if the bug or error is not caught properly.

What are some drawbacks?

While using microservices solves some of the problems of a monolithic architecture, using them has its own set of problems. If you're trying to split your monolithic application into microservices, the first challenge is on how to split them. You can choose to split them into business functions, such as one microservice to handle shipments and another microservice to handle payment services. In the end, your components should only have a small set of functions or responsibilities.

Some problems in a microservice architecture that I can see are:

  • Once your number of microservices grow, it can be hard to keep track of them. Initially setting up continuous integration and continuous delivery (CI/CD) can be hard as you'll need to deal with the additional complexity of having these multiple microservices.
  • Complexity. Microservices would need more coordination especially when multiple teams are involved. Microservices would also introduce more network calls in cases where it needs to interact with other microservices, which wouldn't be present in a monolithic app. It wouldn't be as simple as deploying one instance of an app. More things you will also need to consider are: how to handle the communication between microservices, handle errors to avoid disrupting other microservices, and add more test cases in each component.
  • Finding and tracing the bugs and errors in your application. It would be easier to find if your microservice only has one route but if a microservice communicates with multiple other microservices, it can consume a lot of your time by just looking for that error.

    Diagram of two tracing requests with one of them showing an error

  • Routing your microservices will need more work. You'll need to spend time in configuring and controlling the flow of your microservices. You'll also need to keep track of the versions of your microservices and deal with its routing.

    Diagram of routing microservices

  • Microservices could consume more resources compared to a monolithic app. Although one of the pros I mentioned is that scalability and resources can be utilized better and more efficiently, each component would need its own instance and container, potentially leading to more usage in memory and CPU.

Tools that can help you with microservices

From a containers perspective, Kubernetes can help. From a microservices perspective, Istio can help.

Kubernetes

Kubernetes is a container orchestration platform that lets you deploy, scale, and manage all of your containers. It allows you to automate the deployment of your containerized microservices. This makes it easier to manage all of the components and microservices of your application. You should learn Docker for containerizing your microservices. IBM has a public offering with the IBM Cloud Kubernetes Service that manages the cluster for you.

Istio

Istio addresses some of the drawbacks in microservices. Istio is a service mesh that further helps you manage your microservices. Istio can be installed on top of Kubernetes, where it can help you trace and monitor your microservices. This can also help you quickly trace the errors and bugs in your app if there are any. Istio can also manage the traffic of your microservices such as managing and controlling the flow. Your routes can easily be configured. Istio also provides security within your microservices such as having mutual TLS or limiting its access to external services. You can also install Istio onto the IBM Cloud Kubernetes Service.

Summary

In my experience, using a container orchestration platform is a must in building your application with microservices. Kubernetes is one of the popular choices by developers as it quickly brings their application from development to production. And, even better, it's open source!

For developers who are starting to build their applications, they should decide whether it would be beneficial to them to use a microservices architecture rather than a monolithic one. They should consider the long-term usability and scalability of their application. It's okay to start with a monolithic architecture, but once the application grows in size, it would only get harder to decompose them into microservices. In that case, it would be more beneficial to start off with microservices in the early development phase. For existing monolithic applications, developers should consider how and which components they would decouple in their application.

In spite of the drawbacks, microservices continue to be popular with developers and enterprises as it greatly benefits application and user demands. With its flexibility, developers and enterprises can achieve rapid development or updates in their application once they have the right level of microservices.