Deploy Spring Boot application to GKE

In this tutorial, we'll see how to set up and deploy the sample Spring Boot application to Google Kubernetes Engine (GKE)

1. Introduction

If you’ve been learning programming for some time you probably heard about Kubernetes (also known as Kube or K8s). In simple words, Kubernetes is a system for automating loads of processes, like deployment, scaling, and management of containerized applications.

There is no doubt that the K8s can improve our productivity and make our application more stable. However, maintaining the whole system might become more difficult and time-consuming. Fortunately, we can find lots of cloud providers offering Kubernetes as a managed service, like:

  • Google Kubernetes Engine (GKE),
  • Azure Kubernetes Service (AKS),
  • Amazon Elastic Container Service for Kubernetes (Amazon EKS)

Choosing a provider-managed solution transfers the responsibility for managing and provisioning the master node to the cloud provider allowing us to focus more on the development itself.

In this tutorial, we’ll see how to set up and deploy the sample Spring Boot application to Google Kubernetes Engine (GKE).

2. Prerequisites

To follow the tutorial you need the following prerequisites:

  • kubectl (Kubernetes CLI to manage a cluster)
  • gcloud (CLI tool to create and manage Google Cloud resources)
  • Google Cloud Account (free $ 300 trial)

3. Create TestController Class With Test Endpoint

Let’s start with implementing the example TestController with getHelloMessage function:

@RestController
@RequestMapping("/api/hello")
class TestController {

    @GetMapping
    fun getHelloMessage() : ResponseEntity<String> = ResponseEntity.ok("Hello world!")
}

This is a very straightforward function responding to GET requests to /api/hello and returning “Hello world!” String as the response.

4. Create Dockerfile

As the next step, let’s prepare the Dockerfile we will use to build the Docker image later:

FROM openjdk
VOLUME /tmp
RUN mkdir /work
COPY . /work
WORKDIR /work
RUN /work/gradlew build
RUN mv /work/build/libs/*.jar /work/app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/work/app.jar"]

5. Build Docker Image

Secondly, let’s build a Docker image using already prepared Dockerfile:

docker build -t spring-boot-example .

When the command finishes its execution we will be informed that the image has been built and tagged successfully. We can also type docker images in the terminal to list all top-level images:

docker images

## command output
REPOSITORY                                          TAG                 IMAGE ID            CREATED              SIZE
spring-boot-example                                 latest              52eaa2a8ef8c        About a minute ago   1.12GB
openjdk                                             latest              0cd6de5fdbee        About a minute ago   511MB

As can be seen, the spring-boot-example image has been created and the OpenJDK image has been pulled as well.

6. Push Docker Image to Container Registry

As the next step, we will push the created image to the Google Container Registry. Before we will be able to do it, let’s make sure that we’ve got the container registry already configured and choose a correct hostname, which specifies the location where we will store the image.

Let’s start with tagging the local image with the registry name with the docker tag command:

docker tag spring-boot-example gcr.io/[PROJECT-ID]/spring-boot-example:0.0.1

Then, let’s push our image to the container registry:

docker push gcr.io/[PROJECT-ID]/spring-boot-example:0.0.1

Finally, when the command finishes its execution we can validate, whether the image has been uploaded successfully by listing Google Container Registry images:

gcloud container images list

## command output
NAME
gcr.io/[PROJECT-ID]/spring-boot-example

Please notice, that [PROJECT-ID] will be different depending on our project’s id.

7. Create a Cluster

Finally, we can create a new Kubernetes cluster within Google Kubernetes Engine. In this tutorial, we will use the cloud console (we could also do that using gcloud CLI). Let’s navigate to the panel and start by clicking the “Create cluster” button. Secondly, let’s configure cluster basics, like name and location type:

Image contains screenshot from Google Kubernetes Engine console page showing how to configure cluster basics, like name and location type

Then, let’s navigate to the node pools’ default-pool tab and set the number of nodes to 1 (this number will be bigger in the real scenarios, but for the educational purposes we do not need more):

Image contains screenshot from Google Kubernetes Engine console page showing how to set the number of nodes

As the last step, let’s click the Nodes tab, choose our machine type and boot disk size and click the “Create” button at the bottom of the site:

Image contains screenshot from Google Kubernetes Engine console page showing how to set machine type and boot disk size

Please notice, that it may take some time before the changes will take place.

8. Create Kubernetes Deployment and Service

In order to run our application in the K8s environment, we will prepare two configuration files- one for the Deployment and one for the Service. In a nutshell, a Deployment is an object representing an application running on our cluster and a Service allows us to expose an application as a network service.

8.1. Create Deployment

Firstly, let’s create the deployment.yaml file containing the following configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-example
  labels:
    app: spring-boot-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-example
  template:
    metadata:
      labels:
        app: spring-boot-example
    spec:
      containers:
        - image: gcr.io/[PROJECT-ID]/spring-boot-example:0.0.1
          name: spring-boot-example-container
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              port: 8080
              path: /api/status
            initialDelaySeconds: 5
            failureThreshold: 5
          livenessProbe:
            httpGet:
              port: 8080
              path: /api/status
            initialDelaySeconds: 5
            failureThreshold: 5

Please remember to replace [PROJECT-ID] with the correct value.

8.2. Create Service

Similarly, let’s create the service.yaml file containing service’s configuration:

apiVersion: v1
kind: Service
metadata:
  name: spring-boot-example-svc
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app: spring-boot-example
  type: LoadBalancer

And that’s all the configuration that we need to prepare in order to set up our Pods and Service.

10. Apply Deployment and Service

10.1. Configure Kubectl Context

As one of the last steps we need to fetch the credentials of the running cluster and configure our kubectl context:

gcloud container clusters get-credentials [CLUSTER-NAME] --zone [CLUSTER-ZONE] --project [PROJECT-ID]

## command output
Fetching cluster endpoint and auth data.
kubeconfig entry generated for example-cluster.

Finally, let’s apply our configurations using the apply command:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

11. Verification

11.1. Verify K8s Pods and Service

In order to check, whether the Pods have been created successfully let’s run kubectl get pods command:

kubectl get pods

## command output
NAME                                   READY   STATUS    RESTARTS   AGE
spring-boot-example-697976c749-klc64   1/1     Running   0          50s

As can be seen, all pods are ready and the status is Running, so we can check whether the service has been created and the external IP address has been assigned:

kubectl get svc

## command output
NAME                      TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes                ClusterIP      10.0.0.1     <none>        443/TCP        10m
spring-boot-example-svc   LoadBalancer   10.0.4.57    34.69.49.59   80:31509/TCP   2m56s

11.2. Verify Test Endpoint

Finally, let’s check our test endpoint:

curl 34.69.49.59/api/hello

And we see that we Hello world! text is returned as the response, meaning that our application has been deployed successfully and exposed to the world.

12. Conclusion

In this article, we’ve learned how to deploy the Spring Boot application to Google Kubernetes Engine (GKE). We’ve covered how to containerize our application, build the image, push it to Google Container Registry, and finally deploy it to GKE.

For the source code, please visit our project on GitHub.

If you are reading this paragraph, I want to know that I am more than happy that you decided to spend your time learning with Codersee and I hope that this article helped you to learn something new. If you have any ideas or comments that you would like to share with us, please let us know in the comments below, by our Facebook page or group, or by using our contact form.

Leave a Reply

Your email address will not be published. Required fields are marked *