Spring Boot + Docker + Kubernetes = The new Summum Bonum
In this post I will show how easy is to deploy a Spring Boot microservice in a Kubernetes container using a Docker image.
First things first, what is an image? An image is a lightweight stand-alone executable package, it includes everything you need to run a piece of software including the code, a runtime, libraries, environment variables and config files.
A container is a runtime instance of an image - what the image becomes in memory when actually executed. It runs completely isolated from the environment by default, only accessing host files and ports if configured to do so.
Docker containers running on a single machine share that machine's operating system kernel; they start instantly and use less compute and ram.
Google has been running production workloads for 15 years using Kubernetes. I dare you to find a better container to run your image.
Now, let's build our image and deploy it. You will find the Spring Boot app and a detailed description of what we're going to do on my GitHub.
What do you need to create the image of your app and run it on your local machine?
- VirtualBox
- Minikube
- Kubernetes command line tool (or kubectl)
Creating a Spring Boot microservice
1- If you don't want to use the example I created on my GitHub you can create your own using Spring Initializer. In my example I added the following dependencies: web, actuator, jpa, rest, hsqldb (an in-memory db) and lombok.
Alternatively you can use the following command line:
# curl https://start.spring.io/hello.zip -d bootVersion=1.5.9.RELEASE \ -d dependencies=web, actuator, jpa, rest, hsqldb, lombok \ -d groupId=com.ssense.k8s -d artifactId=users \ -d name=user -d baseDir=user -o user.zip #unzip user.zip #cd user2 - Once you create the endpoints you need on your Spring Boot app, you need to add a property enabling the /application/env endpoint. This allows us to inspect environment variables added by Kubernetes. Change your "src/main/resources/application.properties" file and add:
endpoints.env.enabled=true3 - Now we need to add in the same file the connection properties for the in-memory DB.
spring.datasource.url=jdbc:hsqldb:file:target/testdb spring.datasource.username=sa spring.jpa.hibernate.ddl-auto=create spring.datasource.initialize=true4 - It is time to create a Dockerfile so we can package the app as a docker image, the Dockerfile is created at the root level, on the same directory as your pom file.
#the parent image FROM openjdk:8 # the volume where your docker image will be saved locally VOLUME /tmp # copy your app into the container ADD ./target/users-0.0.1-SNAPSHOT.jar /users.jar RUN sh -c 'touch /users.jar' # allows to configure a container that will run as an executable ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/users.jar"]The Dockerfile will define what goes on the environment inside your container.
5 - I'm assuming you have installed the pre-requisites needed. Start Docker, start the virtualBox and the minikube with a local Kubernetes cluster.
minikube start6 - Build the app and the Docker image. Note: we share the Docker environment used by Minikube, so we can communicate with the built-in Docker inside the Minikube.
eval $(minikube docker-env) ./mvnw clean package docker build -t $USER/users:0.0.1 .Once you create your image you can check where your image is with this command:
docker images7 - It's time to run the Kubernetes deployment on the running Minikube cluster
kubectl run users --image $USER/users:0.0.1 --port 8080 kubectl expose deployment users --type=NodePort8- Our service now runs on the Minikube cluster. These are 3 commands you can use to find out the IP address for the Minikube and the external port for our service.
minikube service users --url kubectl get service users kubectl describe services usersand if you need to check the pods deployed
kubectl get pods9- Do you want to scale up your application? No worries, we can add 4 more pods (5 in total).
kubectl scale deployment users --replicas=5 kubectl get pods10 - Finally when it's time to update your deployed app, you just need to build a new version, create the new image and update in in Kubernetes
docker build -t $USER/users:0.0.2 . kubectl set image deployment/users users=users:0.0.2Clean everything
kubectl delete all -l run=users minikube stopI hope my post on how to build a Spring Boot microservice, creating the image of that microservice and deploy it on a Kubernetes container will help you out in the future.
Enjoy !!
Comments
Post a Comment