Kubernetes (GKE) + Spring Boot + Flask = Awesomeness

Deploying Spring Boot and Flask application on Kubernetes with auto scaling enabled

Amit Singh
7 min readJul 23, 2021

Ever thought of leveraging that cool auto-scaling feature of Kubernetes for your app, and also practice deploying a Spring Boot application on Kubernetes, and throw in a flask app in the mix too just for fun?

Because that’s what we did. Mostly to test deploying spring boot app on Kubernetes, but also to just see the deployment scale up as the load increases and scale back down when the traffic reduces, which, again, is really cool.

To begin with, you’d need a GKE cluster, here’s the quickstart guide: https://cloud.google.com/kubernetes-engine/docs/quickstart

For our case we created two nodepools

  1. api-pool
    -
    1 node, set to autoscale to 3 nodes max
    -
    e2-small
  2. flask-pool
    -
    1 node, no autoscaling
    - custom e2 instance with 6vcpu and 16GB memory

Why this specific configuration? We’ll get to that in a bit ;)

Now we get to the core of our app, the backend.

lyrics-scraper-google

So I tried looking up some free APIs that could provide me lyrics for a song, but couldn’t really find anything. I had a script that used selenium to scrap lyrics using Genius API. But it seems like they made some changes to their page structure and that no longer works now. I tried making some changes but nah, nothing worked.

And there I was, almost defeated even before I had started. Listening to some songs that you listened to when you feel defeated. When I had to look lyrics of a song I couldn’t understand.
And guess what, I didn’t use Genius, I used Google. I just typed in the song’s name, followed by “lyrics”, as the query and there it was.

So I modified the scraper and now we are getting lyrics directly from google results. Check it out here.
You need to provide the track name as the track query parameter and the artist’s name as the artist query parameter. The listener is set on the path /lyrics-scraper
Of course this also puts a limitation that if google doesn’t return the lyrics as a search result, the scraper would fail.

you can see the chrome window here but we would be setting the webdriver to headless

Create an image

Next we are gonna deploy this flask app on GKE. Remember that flask-pool nodepool we created earlier? Yep that’s where this app is going. But first…

We need to create an image, and we need to take care of dependencies too since we are using selenium with chromedriver.
Here’s the Dockerfile I made, after doing some “google research”.

And this is the requirements.txt file

I’m not gonna put all the source code here, mostly because I don’t want this post to be of the length of a scientific paper.

Now we can just build this image and push it to GCR using the following command

gcloud builds — project <your gcp project name> submit — tag gcr.io/<your gcp project name>/<your image name>:<your image tag>

Deploy the application on GKE

Once we have the image, we just need to create a yaml file to deploy our pods on the node, here’s what I made.

Apply this yaml file to create the app deployment and once we have that, expose it as a service using the Expose option shown in the below screenshot.

GKE console

You would need to provide the service name. Keep a track of that, we are gonna need that for our next step.

Expose the application to the internet using ingress

Deploy an ingress resource on the cluster to forward incoming traffic to the backend flask app. Here’s the one I created, you would need to provide the service name mentioned in the previous step.

If it all goes right, you should be able to see the public endpoint under the Ingress section of GKE.
We now have an endpoint that returns lyrics of a song. Test it providing some artists and track parameters.

lyrics-api

We are now going to create a Spring Boot application that uses the flask app created above to get the lyrics and of a song and then store it in a database.
Check it out here.
The basic logic here is to scrap for the lyrics if its not present in the database and then store it in the database, so when the next time the request for the same lyrics come in, we just fetch it from the DB, which is way quicker than scraping it.

Database

Create a DB Server on GCP to store lyrics on. You can follow this guide.
Once done, you would also need to add a network under the Server’s Connections setting in order to enable access.
Get the DB Server IP which we are going to use to create a connection string.

We would be receiving the incoming requests on the path /lyrics-api.
We are creating an Entity, SongLyrics, which would create a table by the same in the database, and store all these scraped song lyrics.

App to DB Connectivity

Add the following to the app’s application.properties file. In our case we have named our DB as LyricsAPI

App Dependencies

Check out the gradle file for our application to find the dependencies we have set up.

Creating the image

Use Google’s jib tool to create an image out of your spring boot app following this guide.
Make sure you properly authenticate the tool before exporting the image.
Now we can create the image using the following command:

gradle jib — image=gcr.io/<your project name>/lyrics-api:v3

Deployment on GKE

Now that we have our image, let’s deploy it on GKE. This is the deployment yaml file I created, and this is the corresponding ingress resource to expose the app to the internet.
Make sure to create a service before deploying the ingress resource like we did for the flask app.

One thing to note here is that I had to add listeners on the root path for both the ingress resources. GKE by default seems to add a health probe on the root path of the backend. This isn’t really an issue, if anything, we can set a listener on the root path which can be used with a readiness probe.

Now you should have a public endpoint to access your spring boot app to get the lyrics of your favorite songs (just like they say it in the ads).

We have successfully deployed our application on GKE (if nothing goes south that is).

But that’s not where the story ends. Enter…

Auto-scaling

Remember when I said we’ll get into the nodepool configuration later? Yeah, this is later.

  • flask-pool: we have set this nodepool to have only one node and this single node has enough resources to support 3 pods of our flask-app.
    Then go to the Workloads section and set the flask app deployment to auto scale up to 3 pods max.
    This is an implementation of Horizontal Pod Scaling where we are only using single node to host all the pod replicas.
  • api-pool: for this nodepool we are doing something different. We are not scaling up the app on the same node, instead we are scaling up the nodepool such that each node holds only one replica of the pod.
    Here, we have the nodepool set to auto scale up to 3 nodes max. Now, go the Workloads section again, and the spring boot app deployment to auto scale up to 3 pods max.
    If you notice, you’d see that in our spring boot deployment yaml file we are setting up pod anti affinity rule, this ensures that if a node already hosts a pod of our app, no other pod of the same app is scheduled on it.
    This means that when our deployment scales up and creates a new pod, the pod remains unscheduled, consequently, the nodepool is scaled up as well so as to create a new node to host the pod on.
    This is an implementation of Cluster Auto-scaling.

And now, we are all set. Go the GCP console, send high volume of requests to your app endpoints (you could send get requests in a loop or use a tool like Apache ab), and watch your apps scale up. Trust me its very satisfying.

Our application has a lot a room for improvement. To begin with, we could definitely use a better lyrics scraper. Also, we should probably separate the interaction with the flask app in our spring boot, and put it in a new method.

Feel free to drop any questions in the comments section. I’ll check them out and update the story if I missed something.

Hey 👋 there. If I helped you in some way and you’re feeling generous today, you can now buy me a coffee!

--

--

Amit Singh
Amit Singh

Written by Amit Singh

A Software Engineer who believes that technological progress should be more about extension than replacement.