Deploy a Spring Boot application to GKE

Last Updated:  August 27, 2021 | Published: July 26, 2019

Once your Spring Boot application is ready for deployment, you'll have to find an environment to deploy to.  Over the past years, Kubernetes has evolved and gained a lot of attention.  Today it is usually picked if you need service discovery, resource management, and autoscaling in addition to a convenient deployment model.  Setting up your own Kubernets cluster on bare metal might be challenging and time-consuming.  Fortunately, every major cloud provider (Google, Amazon, Microsoft …) offers a managed Kubernetes service ready to use in almost five minutes. To demonstrate how you can easily deploy your Spring Boot application to Kubernetes, I'll be using GKE (Google Kubernetes Engine) in this blog post.

The following technologies are used for this demo: Java 11, Docker, Kubernetes 1.13.x, Spring Boot 2.3

Prerequisites for deploying your app to GKE

To follow the tutorial you need the following prerequisites:

Once you installed the CLI tools and set up a Google Cloud account, you can create a new project in the Google Cloud console. This project is used to partition your different services and application under a common name:

googleCloudConsoleProjectSetupView

Google will automatically assign a unique ID for your project, which we'll need later on for pushing the Docker image to GCR (Google Container Registry).

Next, you'll have to create your first Kubernetes cluster. You can use either the web console for this or the gcloud CLI. To create the cluster in your browser, open the left-side menu and navigate to Kubernetes Engine -> Clusters:

If you've just created a new Google Cloud project, Google might need some minutes to enable the Kubernetes API for this project. Once it's enabled, you can create a new cluster:

googleCloudConsoleCreateCluster

For simplicity, you can choose the Standard cluster template from Google to configure your Kubernetes cluster.  In addition, you can rename the cluster, select a specific region and the Kubernetes version. Leave the other configuration options as the pre-configured values are fine for a first demo:

googleCloudConsoleConfigureCluster

Once you click on Create, Google will allocate the required machines and set up the cluster. This might takes some minutes and we can continue with the preparation of the Spring Boot application.

Prepare the Spring Boot application for a Kubernetes deployment

The sample Spring Boot application contains one REST endpoint to send a message over the wire:

The actual message gets injected and will be defined as an environment variable in the Kubernetes Pod specification. You can use this approach to configure any plain-text variable (e.g. stage, JDBC URL, feature toggles, etc.). In addition to the REST endpoint, I've added the Spring Boot Actuator dependency and enabled just the health endpoint:

We'll use the /actuator/health endpoint, later on, to configure liveness and readiness probes for the application. This will ensure that Kubernetes won't send traffic unless the application is ready. Furthermore, Kubernetes will monitor the liveness of the application and terminate the pod if the application is unhealthy and create a new one.

That's everything required from the code perspective. As we'll use Docker as the container engine, we need to create a Docker image containing the application. For this, I've used a straightforward Java 11 Dockerfile:

The actual Kubernets Deployment object is defined in a .yaml file and contains the following configuration:

This excerpt defines how the application is going to be deployed within the cluster. We'll use two instances, expose the port 8080, configure which Docker image to use, define the liveness and readiness probe HTTP endpoint and inject the message value. This is achieved with a Kubernetes ConfigMap:

To access the application from outside the cluster, we'll have to create a so-called Kubernetes Service. This is will expose the application on a pre-defined port. There are several types of Services and for this example, I've picked the LoadBalancer:

This will later on delegate the Google Cloud to create a load balancer with a public IP address. All of these Kubernetes objects are stored within a single deployment.yaml file and each object is delimited by ---.

Deploy the application to GKE

Once the application is ready, we can build the app and Docker image.

To push the Docker image to the Google Container Registry, we have to tag it according to the following pattern reginalEcrHostname/projectId/dockerImageName:tag. For this, you'll now need the unique project id and the region of your Kubernetes cluster (for the example it's eu.gcr.io as we are running in Europe). In addition, we need authentication to push images to the GCR. This is achieved with a simple glcoud operation:

Accessing the Kubernetes cluster in the cloud from your local machine requires configuration for your kubectl CLI. The Google Cloud Console provides you the required command once you select your Kubernetes cluster and click on the button Connect. 

As soon as you configured your kubectl cluster context with the gcloud command, you can deploy the application to the cluster with a single Kubernetes command:

Afterward, you can check if the two pods (instances) are up and running:

You'll get the public IP address if you query for all available services. Assigning the IP address might take some minutes

For this example, the application is now available at http://35.242.179.139/hello and returns the following output:

springBootAppDeployedToGKE

That's everything!

You can find the whole codebase on GitHub.

Looking for further Kubernetes related blog posts?

Have fun deploying your Spring Boot apps to GKE,

Phil

>