In this tutorial we will learn how to install a Spring Boot application on Kubernetes using Minikube and JKube Maven plugin.
Install a Kubernetes Cluster with Minikube
Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications. The simplest way to get started with Kubernetes is to install Minikube.
Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing a single node and ships with a CLI that provides basic bootstrapping operations for working with your cluster, including start, stop, status, and delete
The procedure for installing Minikube is detailed at: https://minikube.sigs.k8s.io/docs/start/
To install the binary distribution you can just download it and run the “install” command on it:
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 $ sudo install minikube-linux-amd64 /usr/local/bin/minikube
When done, launch the “minikube start“command which will select the Driver for your environment and download the Virtual Machine required to run Kubernetes components:
minikube start 😄 minikube v1.15.1 on Fedora 29 ▪ KUBECONFIG=/home/francesco/taskforce/install/auth/kubeconfig ✨ Using the kvm2 driver based on existing profile 👍 Starting control plane node minikube in cluster minikube 🎉 minikube 1.24.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.24.0 💡 To disable this notice, run: 'minikube config set WantUpdateNotification false' 🔄 Restarting existing kvm2 VM for "minikube" ... 🐳 Preparing Kubernetes v1.19.4 on Docker 19.03.13 ... 🔎 Verifying Kubernetes components... 🔎 Verifying registry addon... 🌟 Enabled addons: default-storageclass, storage-provisioner, registry, dashboard ❗ /usr/local/bin/kubectl is version 1.15.3, which may have incompatibilites with Kubernetes 1.19.4. ▪ Want kubectl v1.19.4? Try 'minikube kubectl -- get pods -A' 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Next, verify that the default and kube-system services are available:
minikube service list |----------------------|-----------------------------|--------------|-----| | NAMESPACE | NAME | TARGET PORT | URL | |----------------------|-----------------------------|--------------|-----| | default | kubernetes | No node port | | kube-system | kube-dns | No node port | | kube-system | registry | No node port | | kubernetes-dashboard | dashboard-metrics-scraper | No node port | | kubernetes-dashboard | kubernetes-dashboard | No node port | |----------------------|-----------------------------|--------------|-----|
Great, you Kubernetes cluster is now up and running.
Then, in order to build the Docker image using Minikube’s Docker instance, execute:
$ eval $(minikube docker-env)
The command minikube docker-env returns a set of Bash environment variable exports to configure your local environment to re-use the Docker daemon inside the Minikube instance.
If you fail to configure your Minikube environment, you will see an error when deploying your resource: “Connection reset by peer”
Coding a sample Spring Boot application
We will deploy on Minikube a minimal Spring Boot application with just an Hello World Controller in it:
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/") public String index() { return "Greetings from Spring Boot!!"; } }
In order to deploy this Spring Boot application on Kubernetes we will use JKube.
Eclipse JKube is a collection of plugins and libraries that are used for building container images using Docker, JIB or S2I build strategies. Eclipse JKube generates and deploys Kubernetes/OpenShift manifests at compile time too.
To use JKube, just add it as Maven plugin to your project:
<?xml version="1.0" encoding="UTF-8"?><profile> <id>kubernetes</id> <build> <plugins> <plugin> <groupId>org.eclipse.jkube</groupId> <artifactId>kubernetes-maven-plugin</artifactId> <version>${jkube.version}</version> <configuration> <resources> <labels> <all> <testProject>spring-boot-sample</testProject> </all> </labels> </resources> <generator> <includes> <include>spring-boot</include> </includes> <config> <spring-boot> <color>always</color> </spring-boot> </config> </generator> <enricher> <excludes> <exclude>jkube-expose</exclude> </excludes> <config> <jkube-service> <type>NodePort</type> </jkube-service> </config> </enricher> </configuration> <executions> <execution> <goals> <goal>resource</goal> <goal>build</goal> <goal>helm</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile>
Deploying the Spring Boot application on Kubernetes
Deploying the application on Kubernetes, just requires 3 simple steps:
1) Create your Kubernetes resource descriptors.
mvn clean k8s:resource -Pkubernetes
Then start docker build by hitting the build goal.
mvn package k8s:build -Pkubernetes
Finally, deploy your application on the Kubernetes cluster:
mvn k8s:deploy -Pkubernetes
Once deployed, you can see the pods running inside your Kubernetes cluster:
$ kubectl get pods NAME READY STATUS RESTARTS AGE spring-boot--5b7d6dfb6f-2nsnm 1/1 Running 0 23s
You can try to access your application using minikube service command like this:
$ minikube service spring-boot |-----------|-------------|-------------|----------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|-------------|-------------|----------------------------| | default | spring-boot | http | http://192.168.39.76:32429 | |-----------|-------------|-------------|----------------------------| Opening service default/spring-boot in default browser...
Please notice that there’s a known issue which affects some JDKs: https://bugs.openjdk.java.net/browse/JDK-8236039
When this occurs the client throws an exception:
“javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request”
This happens because JDK 11 onwards has support for TLS 1.3 which can cause the above error.
You can work around this issue by setting the property -Djdk.tls.client.protocols=TLSv1.2 to the JVM args to make it use 1.2 instead. As an alternative, update to the latest version od JDK (it’s fully solved in JDK 15).
Enjoy Spring Boot on Kubernetes!
You can find the source code for this Maven project at: https://github.com/eclipse/jkube/tree/master/quickstarts/maven/spring-boot
Found the article helpful? if so please follow us on Socials