Sunday, April 5, 2020

Kubernetes Series - Part I - Prerequisites - Microservices

Kubernetes Series - Part I - Prerequisites

There are many prerequisites to learn Kubernetes.It's difficult to understand a container orchestration tool without understanding containers. And how to package and deploy applications using containers. When you search for containerization you will come across the term Microservices also.

Also you will see articles comparing containerization with virtualization and virtualization with non-virtualization. And if you keep searching it goes to the history of UNIX. And you search enough, you will see references to Google Borg, chroot environments and UNIX network jail.

I’ll try to touch up on these concepts before getting into the details of Kubernetes.

Microservice

Before Microservices, applications were monolithic. For example an online shopping application has sub systems like customer profile, catalog, shopping cart, customer wish list. You can break down this monolithic application into a bunch of sub systems. And model each one as a Microservice.

There are many advantages of breaking down a monolithic application into Microservices. 

You can make changes to each Microservice independently and deploy them. Typically each Microservice has a separate code base. This would reduce dependency between teams and make development /deployment more more agile. 

In a monolithic application, you need to scale the entire application. Even though some of the sub systems are less utilized. But you can scale each Microservice independently on a need basis.

Typically monolithic applications are based on a single technology stack. But in a Microservices based architecture, the Microservices talk to each other over REST APIs. So each Microservice has the flexibility to choose the most appropriate technology stack.

But there are disadvantages too. Microservices based architecture increases complexity. In a monolithic application, for example a J2EE application,  the entire application is running in a single JVM. So it's easy to make a call from one subsystem to another. But in Microservices architecture, each Microservice runs in it's own JVM. And there is no way to make direct calls. So you would need to make calls using REST API.


Since each service is built and deployed independently, there is no way to know the URL of the other Microservice up front. You may scale out a particular service based on need and there could be multiple instances of the service running on different hosts. So there are additional services required to discover a service. Then only you can invoke a REST API present in that Microservice. A Service Registry is used to register all the Microservice instances. Basically the URL and some additional metadata about each Microservice instance is published in the service registry. Whenever a microservice comes up, it will register these details with the service registry. And when a Microservice needs to  invoke another, it can first perform a lookup against the registry to get the URL of the other Microservice(IP address/Port etc).  This service discovery layer add complexity.

These additional layers(registry/lookup) increase latency. In a monolithic application(say J2EE app) everything is running in a single JVM and there is no network latency to invoke one sub system from another. But in Microservices architecture, you need to first do a service discovery(service registry lookup) to get hold of the other Microserviece instance URL and and then invoke the REST API, this would increase the network latency.

Compared to Microservices, it's easy to troubleshoot/diagnose a monolithic application. You just need to go to the application server logs to start triage. But in a Microservices based application, these services may be running on different hosts and there could be multiple instances of each service. It's a challenge to even identify the correct host and then get to the log location in production. Also you need to correlate the logs as the log messages related to a workflow might go across Microservices.


Another challenge is packaging and deploying multiple Microservices. Containers are used widely to package and deploy Microservices. In the next part I'll go through containerization concepts.





No comments: