Migrate Spring Cloud to Kubernetes

Soumya Ranjan Sahoo
7 min readJan 6, 2023

--

Spring Cloud To Kubernetes

Hi Reader, this article is about migration of your Java Spring Boot application from on-premise to Kubernetes eco system.

If you are a Java developer you might have spent a good amount of time to learn spring boot and spring cloud but in this article I am going to replace Spring Cloud with the Kubernetes components. So you may not like this considering all your effort will not be useful, but trust me its worth it. I will help you to understand K8 components using the reference of Spring cloud, so your knowledge will be useful anyway.

But first lets talk about …

Why Kubernetes?

I mean life is good with Java and Spring Cloud right, so why we need to add another element to our application which will remove many existing components?

Because … it is what required in this fast pace market where we need to bring up new features over the night to production with zero downtime. Complex architecture like microservices and features like performance, scalability, reliability, availability kind of cloud feature are unspoken expectation form your app. To achieve this, only writing code in modular manner is not enough, the platform you hosts your app plays a major role because when user hits your website it will hit the server not your O(n) optimized FOR Loop. Hence we need to accept the fact that infrastructure is as important as your code.

As of now, the two popular architectures are “Server-less” and “Containerization”. In this article we will focus on Containerization. Some popular applications like YouTube, Google Maps or most of the google products run in Containerization (Kubernetes) manner.

Some of the key features that Kubernetes provides are:

  1. Container Orchestration
  2. Auto scaling and Auto healing
  3. Health checks
  4. Routing, Service discovery and Load balancing
  5. Centralized application configurations mechanism

But why you should migrate?

  1. Spring cloud features like service discovery, load balancing, Spring Gateway etc. will be implemented using Kubernetes components which makes the application code loosely coupled with the infrastructure settings
  2. In future your application will not be Java eco system dependent and you can expand by adding more microservices developed by Python/ Node Js etc.
  3. Cloud aspects like Scalability and Auto scaling, Load balancing, will be done automatically.
  4. You can run your application in any Kubernetes platform like OpenShift, EKS, AKS, GKE etc. Hence you can lift and shift you app.
  5. And best part is you don’t need to make any application code changes.

Some basics concepts of containerization before we start …

  1. Cluster → Cluster is the set of Nodes. Multiple Nodes of different categories like compute optimized, memory optimized, GPU optimized etc. can be combined under a single cluster.
  2. Node → Node is nothing but a Virtual Machine like Ec2 or Compute Engines in GCP, where we install the Kubernetes software and Kubernetes uses the CPU and Memory of Node to orchestrate the Pods.
  3. Pod → Your container get executed in one of the port inside the Pod. Its like a mini VM where you can run multiple containers in different ports. But it is recommended to run one container inside one Pod. Hence Pods are like mini VMs running inside a Node which is the the actual VM.
  4. Container → When you build your .jar/.war file of your application you wrap the fat jar with the JRE and declare the RUN command so that the application can be executed inside the wrap. Here the Wrapper is called container.

So you build your application fat jar, put it in a Container, and run it in a Pod. Many Pods can be created inside a Node and many nodes can be combined and called it as a Cluster.

Kubernetes basic component

Ok.. so lets start making changes one by one.

Spring Eureka → K8 Services

Like every spring boot microservice starts it registers it self with Eureka, when we migrate to Kubernetes we need to create Service for every micro service and this K8 “Service” name will be used in other microservice for discovery and with ingress for traffic routing. Service acts as load balancer as well for distributing the load among multiple pods.

Spring Gateway → Ingress

If you have Spring Gateway in our application which is the only microservice exposed to the outside world then you can remove it and use ingress along with path based routing for routing your traffic to the respective service. But let’s say you have used some extra features like custom authentication or filters then better to keep using Spring gateway and use the service names from K8 “service” because you can’t do the same using Ingress.

Spring Config → Config Maps & Secrets

In Spring eco system we put all the configurations like DB connection details, API Key, active profile name or any other constants in application.yaml or properties file and when Spring boot starts Spring Config will take all the values from there and make them environment variables. Well this is good but in Kubernetes we need to make use of ConfigMaps and Secrets for this feature.

Why?

Because if you use Spring Config, scope of your environment variables will be limited to only one micro service. But when you push it to Kubernetes it will be centralized and any of your micro service can import which ever value they want. Apart from that, micro services from other languages like Python or Node can also make use of the configurations.

In ConfigMaps you can save general data like Country names, error messages etc. But in Secret you can save the sensitive data like DB details, API key because Kubernetes stores in encrypted format. Hence you data will be secured.

Recommendation is not to restrict your app to one eco system, our application should be as loosely coupled as possible.

So these are the major shifts from Spring cloud to Kubernetes. But apart from these replacements we get some cloud features which changes the ball game.

Auto Scaling : HPA

HPA stands for Horizontal Auto Scaling. As it name says this component will scale up and down your application based on parameters you set. For example if the memory consumption will reach to 70% then you can spin up another pod to manage the load. These kind of conditions you can set using HPA.

Health Check : Probes

Here you can make use of Spring Actuator or create a custom made endpoint where you can define your condition to check application status. Basically probes will keeps on checking/pinging the API endpoint in some interval and validate if the Pod is alive or not, ready or not. If it found the Pod to be not Ready it will remove from the active list of Pods so that K8 Service will not send any request. And if probes found one Pod to be unhealthy then it will restart the Pod.

Service Mesh

This is an add-on in the Service Discovery. By using only Services, the inter-communications between the pods can’t be controlled, nor secure and we will not be able to trace the flow of request from one service to another. Monitoring and tracing are also challenges.

Hence, we will be using Service Mesh. This will deploy a side car container in every pod which will act as a proxy gateway for your application container. Now service to service calls will go through the proxy side car containers rather than hitting the application container directly.

Logging, Monitoring & distributed tracing

Well this is a very big topic and you can get many articles on this. So no point of writing anything for this. In short, you can use ELK or ELG stack for this component and Kubernetes & Service Mesh integrates with this stack of technology very easily.

Outbound Traffic Management : Egress IP

Let’s say you want to integrate your system with some other third party but the problem is they will only allow some IP address but when multiple Pods will send request to the external third party they will be using the IP of the Node where they are running. So the third party will get request from our application but from multiple IPs.

So whitelisting is difficult in this case. Hence Egress IP comes to rescue. K8 Egress IP will assign one IP for your namespace so that all the requests from the Pods from that namespace will be originating from single IP address.

Now as we have one IP address, we can ask our third party to whitelist that one IP only.

Ok … So that's all from my end for migration. Lets see a quick summary …

Summary

  1. Disable Spring Eureka and use K8 Services for service discovery
  2. Remove Spring Gateway and use Ingress for traffic routing.
  3. Use ConfigMaps and Secrets for application configuration instead of Spring Config
  4. Use Service Mesh like istio for better inter communications.
  5. ELK or ELG stack will provide you logging, monitoring and distributed tracing
  6. HPA for auto scaling and Probes for health check will be great to use
  7. Egress IP will provide you an single IP so that you can whitelist your system with other secured systems

I hope this article is helpful and you will get some direction to start. If not let me know in the comment and will be happy to help.

Happy Kubernetezing …

--

--

Soumya Ranjan Sahoo
Soumya Ranjan Sahoo

Written by Soumya Ranjan Sahoo

Solution architect and full stack developer, like to write tech stuff …

No responses yet