Build your Spring Boot Microservice with Kubernetes

In this article I will build my first Spring Boot microservice with Kubernetes. For that, I will build a microservice using Spring Initializr and create my Kubernetes cluster in Minikube.

Content:

  • Spring Initializr
  • Package with Docker
  • Kubernetes
  • Minikube

In the following video, I show how to build a Spring Boot Microservice with Kubernetes in less than 10 minutes.

All the code can be found in this repository.

Welcome to this first article where I will build a complete microservices architecture with Kubernetes and Spring Cloud. In this first article i will build a Kubernetes cluster and my first microservice in less than 10 minutes. Ready for this quest?

Spring Initializr

As I said in the introduction article, I want to build a microservice architecture for a bookstore website. I will start with a dummy web service, just to have an endpoint to test. I will create a Spring Boot application with Spring Initializr. Spring Initializr helps me to build a Spring Boot application with the needed dependencies, the Maven structure, and the specified Java version. I will add just one dependency, web, to accept the HTTP requests via a controller.

Spring Initializr
Spring Initializr

Unzip the file, and open it with IntelliJ.

Let’s first create a controller with a single endpoint.

@RestController
public class DummyController {

    @GetMapping("/")
    public String hello() {
        return "Hello World";
    }
}

And now, test it.

> curl localhost:8080/
Hello World

Yeah, it works! I will now package this microservice into a Docker container. Nothing really complicated.

Package with Docker

FROM adoptopenjdk:11-jre-hotspot
MAINTAINER Sergio Lema <thedevworldsl@gmail.com>

COPY target/*.jar app.jar
CMD ["java", "-jar", "app.jar"]

Three lines! As I said, nothing complicated. Let’s first create the jar file and then build the Docker image.

> mvn clean package
...
> docker build -t service-dummy .
...

And now, run the container.

> docker run --publish 8080:8080 service-dummy:latest

Kubernetes

Okay, i have a Spring Boot application tested and running from a Docker container. Now put this container into a Kubernetes cluster. Kubernetes is a service orchestration. It manages services present in a cluster. Which means that first I need a cluster. A cluster is a set of virtual or physical machines which will be managed by Kubernetes. It’s composed by a control panel, which will manages all the stuff and the nodes, which are the available virtual or physical machines. Inside the nodes are located the pods. The pods are available slots for the containers, for the Docker images. But a pod doesn’t host a single container but a set of containers, a set of similar containers.

So to run Kubernetes i need an available cluster. If I were in the cloud, in AWS or GCP, I will need to identify the available virtual machines and the other needed cloud resources. But I am on my own computer. How can I do it? I will use Minikube. Which will create a small cluster in my own computer, which will create like a small cloud in my own computer.

I can’t directly create a pod. I can create jobs, which are tasks which will be running once and then shut down; or I can create deployments, which are long-living services. I first create a folder where to locate all the Kubernetes configuration files. And now the configuration of my first deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8-service-dummy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8-service-dummy
  template:
    metadata:
      labels:
        app: k8-service-dummy
    spec:
      containers:
        - name: service-dummy
          image: service-dummy:latest
          imagePullPolicy: Never

Why i said never to image pull policy? To avoid Kubernetes fetching the image Docker from the public registery. Only use the local one. But the local one is the one located in the cluster.

Minikube

For that, I need to build the Docker image in the Minikube cluster. I will first link my computer to the Minikube environment.

> eval $(minikube docker-env)

And now build again the Docker image, but this time, it will be stored in the Minikube cluster.

> docker build -t service-dummy .
...
> minikube ssh
(minikube) > docker images
REPOSITORY       TAG       IMAGE ID          CREATED          SIZE
service-dummy    latest    5143ce183530      14 seconds ago   263MB
...

Here it is, ready to test my first deployment with Kubernetes.

> kubectl create -f ./k8s
deployment.apps/bookstore created
> kubectl get pods
NAME                         READY    STATUS    RESTARTS   AGE
bookstore-6C96c7f858-24sw8   1/1      Running   0          4s
> kubectl get deployments
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
bookstore   1/1     1            1           15s

Here is my pod and my deployment. Great! I have my Spring Boot application in a Kubernetes cluster. But how can I request my dummy service? I can’t use localhost because it’s hosted in Minikube. The deployment are long-living tasks and the services are public deployments. So I have to tell Kubernetes to use the previous deployment as a service.

apiVersion: v1
kind: Service
metadata:
  name: k8-service-dummy
spec:
  ports:
    - name: 80-8080
      port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: k8-service-dummy
  type: LoadBalancer

Now apply those changes to the existing cluster.

> kubectl apply -f ./k8s
deployment.apps/k8-service-dummy configured
service/k8-service-dummy created

And tell Minikube to publish the servers k8-service-dummy.

> minikube service k8-service-dummy
|-----------|------------------|-------------|-------------------------|
| NAMESPACE |      NAME        | TARGET PORT |           URL           |
|-----------|------------------|-------------|-------------------------|
|  default  | k8-service-dummy |  80-8080/80 | http://172.17.0.3:32479 |
|-----------|------------------|-------------|-------------------------|
Starting tunnel for service k8-service-dummy.
|-----------|------------------|-------------|-------------------------|
| NAMESPACE |      NAME        | TARGET PORT |           URL           |
|-----------|------------------|-------------|-------------------------|
|  default  | k8-service-dummy |             | http://127.0.0.1:57509  |
|-----------|------------------|-------------|-------------------------|

Okay, I have now an IP to test. I will take the localhost address with the port which is mapped to the destination service.

> curl http://127.0.0.1:57509
Hello World

Here it is, finally I can request my Spring Boot application hosted in a Kubernetes cluster.

Conclusion

Let’s recap what I’ve done.

  • I’ve created a Spring Boot application with the web dependency with Spring Initializr.
  • I’ve created a dockerfile.
  • I’ve built the Docker image in Minikube.
  • I’ve created the deployment configuration file for the image.
  • I’ve created a service configuration file to have the container publicly available.
  • And i’ve asked Minikube to return me an IP address for the created service.

References

And the code is available in the following repository.

My New ebook, How to Master Git With 20 Commands, is available now.

One response to “Build your Spring Boot Microservice with Kubernetes”

  1. […] And each microservers will be running in a Docker container. And to orchestrate all of these, Kubernetes, of course. With all of this, i can have this architecture in any cloud: AWS, GCP, Azur, or even in […]

    Like

Leave a comment

A WordPress.com Website.