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.
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.
Leave a comment