Deploying Spring Boot Application in Kubernetes

Seyed Sahil
6 min readOct 22, 2020

Hello there and welcome to my new article on Kubernetes. Today I will show you how to deploy a simple Spring Boot web application in Kubernetes. For this tutorial, I have developed a small Spring Boot web application and will deploy it locally using Minikube.

Building the Docker Image…

Before we begin we have to create a Docker image based on the Spring Boot web application. Read the below given article on how build the a Docker image. It will not take more than 10 minutes. 🙂

Docker and Spring Boot…

Configuring Minikube…

Minikube is a tool that lets you run Kubernetes locally. Read more about Minikube here.

Installation…

$ brew install minikube

This will install Minikube on your Mac. You can see the version by executing the following command.

$ minikube versionOutput >
minikube version: v1.14.0
commit: b09ee50ec047410326a85435f4d99026f9c4f5c4

Deploying Minikube…

To deploy Minikube, we have to use one of the supported drivers. Read more about Minikube drivers here. In this tutorial I will be using vmware driver as I have VMWare Fusion installed in my system.

Download the vmware driver using the following command.

$ brew install docker-machine-driver-vmware

Starting Minikube

To start the Minikube cluster on the local machine use the following command.

$ minikube start --memory=8192 --driver=vmwareOutput >
😄 minikube v1.14.0 on Darwin 10.15.7
✨ Using the vmware driver based on existing profile
👍 Starting control plane node minikube in cluster minikube
🔄 Restarting existing vmware VM for "minikube" ...
🐳 Preparing Kubernetes v1.19.2 on Docker 19.03.12 ...
🔎 Verifying Kubernetes components...
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" by default

Note: Here I am using 8 GB cluster memory and vmware driver.

Understanding the Environments

Minikube has its own copy of Docker and it is different from the one installed in our host machine.

This means that by default the images present in host machine cannot be used by Minikube while during deployments. But there is a way to connect host your host machine to Minikube cluster on a session basis. We will see that in the next section.

To check host machine Docker execute the following command.

$ docker -v

Output >
Docker version 19.03.13, build 4484c46d9d

To check the Docker version inside Minikube, you have to first connect to the Minikube cluster and then execute the above command.

$ minikube ssh
$ docker -v

Output >
Docker version 19.03.12, build 48a66213fe

To exit Minikube, execute the following command.

$ exit

Creating a Kubernetes Deployment…

I am assuming that you have already created the Docker image. Open a new session on your host machine and check this using docker command. It should list hello_world_app.

$ docker images

Output >
REPOSITORY TAG IMAGE ID CREATED SIZE
hello_world_app latest 4023bb800126 6 seconds ago 660MB

Now lets create the Kubernetes deployment file and name it hello-world-deployment.yml

Execute the following command in host to create the deployment along with replica set and pods.

$ kubectl create -f hello-world-deployment.ymlOutput >
deployment.apps/hello-world created

Let’s check if the pods are started or not by running the following command.

$ kubectl get pods

Output >
NAME READY STATUS RESTARTS AGE
hello-world-64987b65b8-pctvh 0/1 ErrImagePull 0 74s

Output will show that image pull failed with error. Because there is not image with name hello_world_app present in Minikube’s Docker registry.

Understanding Image Pull in Minikube…

Minikube is configured to pull latest image from the repository every time. This is why we are getting the previous error. One way to fix the issue is by setting image pull policy to Never. This will tell the Kubernetes to not pull the image and always use the existing image from Minikube’s Docker registry.

Add the below line in deployment file after the image declaration.

imagePullPolicy: Never

Now you have to remove the failed deployment and create a new one.

$ kubectl delete -f hello-world-deployment.ymlOutput >
deployment.apps "hello-world" deleted
$ kubectl create -f hello-world-deployment.ymlOutput >
deployment.apps/hello-world created

Let’s check the pods again to see if it is created or not.

$ kubectl get pods

Output >
NAME READY STATUS RESTARTS AGE
hello-world-55cbd4dc4c-2k4d8 0/1 ErrImageNeverPull 0 118s

Why it failed again ?

The reason is pretty straight forward, we don’t have our hello_world_app image in Minikube’s Docker registry.

Connecting to Minikube’s Docker Registry…

One easy way to fix this problem is by reconfiguring the local Docker daemon. Reconfigure the local Docker daemon to use Minikube’s Docker registry.

Execute the following command to reconfigure the Docker daemon.

$ eval $(minikube -p minikube docker-env)

To verify this just execute the following command and see that the images listed are from Minikube’s Docker registry.

$ docker images

Now rebuild the the image again using the following command.

$ docker build -f .Dockerfile -t hello_world_app .Output >
Sending build context to Docker daemon 17.12MB
Step 1/3 : FROM java:8
---> d23bdf5b1b1b
Step 2/3 : ADD target/docker-hello-world-0.0.1-SNAPSHOT.jar docker-hello-world-0.0.1-SNAPSHOT.jar
---> 35a6afd3ea9b
Step 3/3 : ENTRYPOINT ["java", "-jar", "docker-hello-world-0.0.1-SNAPSHOT.jar"]
---> Running in 9872a0bdf62a
Removing intermediate container 9872a0bdf62a
---> e50aadbac523
Successfully built e50aadbac523
Successfully tagged hello_world_app:latest

Note: The article mentioned in the beginning is using Docker on Windows, that is why the file path specified is different.

The Docker file used here is given below.

Recreate the Deployment…

Delete the failed deployment and recreate the same again.

$ kubectl delete -f hello-world-deployment.ymlOutput >
deployment.apps "hello-world" deleted
$ kubectl create -f hello-world-deployment.ymlOutput >
deployment.apps/hello-world created

Now if you execute the following command, you can see the pod is started and running.

$ kubectl get pods

Output >
NAME READY STATUS RESTARTS AGE
hello-world-55cbd4dc4c-q99k7 1/1 Running 0 65s

One thing before last section.

Here we have created deployment, replica set and pods. to see all items execute following command.

$ kubectl get allOutput >
NAME READY STATUS RESTARTS AGE
pod/hello-world-55cbd4dc4c-q99k7 1/1 Running 0 2m52s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP - <none> 443/TCP 2d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hello-world 1/1 1 1 2m52s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hello-world-55cbd4dc4c 1 1 1 2m52s

Accessing Web Application…

Now we have our deployment created. It is time to access the web application.

For this you need to create a service first, it can be done with the following command.

$ kubectl expose deployment hello-world --type=NodePort --name=hello-world-serviceOutput >
service/hello-world-service exposed

Now it is time for you to connect to the web application. For this you need two things, NodePort of above service and IP address of our Minikube cluster.

To get the Cluster IP of Minikube, execute the following command.

$ kubectl cluster-infoOutput >
Kubernetes master is running at https://192.168.75.130:8443
KubeDNS is running at https://192.168.75.130:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

The Cluster IP here is 192.168.75.130 and protocol should be http as we are not doing a secure access.

Now we need the NodePort. For this we have to execute the following command.

$ kubectl describe services hello-world-serviceOutput >
Name: hello-world-service
Namespace: default
Labels: name=hello-world
Annotations: <none>
Selector: name=hello-world
Type: NodePort
IP: -
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30104/TCP
Endpoints: -
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>

Now you have the NodePort and it is 30104 here.

Now construct the URL as given below and hit the same.

http://192.168.75.130:30104/hello

You will see the Web Application page displaying the famous Hello World! message :).

Oh Yeah!!!

Congratulations, You have successfully deployed the web application in Kubernetes 🙂

Thank You for Reading

Seyed Sahil

Originally published at http://sydlabz.wordpress.com on October 22, 2020.

--

--

Seyed Sahil

Coding Since 2011, Software Engineer, Game Developer, Artist, Photographer. Passionate about Security and Web Technologies. Favourites — C, Java, Javascript.