Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 19, 2024
Now more than ever, Java developers have many options for building and deploying applications with Kubernetes. In this tutorial, we’ll look at one such tool named JKube.
JKube is a collection of tools that make it easy to build Java applications with the intention of deploying them to a cloud environment. It’s a project managed by the Eclipse Foundation and available to use under their ECL-2.0 license.
More specifically, JKube allows us to compile Java applications into Docker container images and then deploy those images to Kubernetes or OpenShift.
It also provides other tools to make monitoring and debugging cloud applications easier.
Most of the core JKube tools are provided via Maven or Gradle plugins. For brevity, the examples below will focus only on the Maven plugin with a Kubernetes environment.
To get started, we simply add the plugin to our Maven POM:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>1.13.1</version>
</plugin>
Notably, the Maven Kubernetes plugin takes some opinionated views to make setup simple. However, it also supports fine-grain control via XML and YAML configuration. We can see the developer docs for full details.
Without any further configuration, we can generate a Docker image:
mvn package k8s:build
This inspects the project structure and picks a suitable base image to use:
[INFO] --- kubernetes-maven-plugin:1.13.1:build (default-cli) @ jkube-demo ---
[INFO] k8s: Building Docker image
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java:0.0.19 as base / builder
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Created docker-build.tar in 112 milliseconds
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Built image sha256:6c9d0
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Removed old image sha256:e2458
[INFO] k8s: [example/jkube-demo:latest] "spring-boot": Tag with latest
And we can confirm the image exists in our local Docker daemon:
> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
example/jkube-demo latest 6c9d08bcd538 5 minutes ago 605MB
In addition to building Docker images, we can use JKube to generate resource descriptors and deploy our application to Kubernetes.
To do this, we need to execute 2 Maven goals:
mvn k8s:resource k8s:apply
The first goal generates a deployment and service YAML file for our application, setting as many defaults as it can:
[INFO] --- kubernetes-maven-plugin:1.13.1:resource (default-cli) @ jkube-demo ---
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java:0.0.19 as base / builder
[INFO] k8s: Using resource templates from jkube-demo/src/main/jkube
[INFO] k8s: jkube-controller: Adding a default Deployment
[INFO] k8s: jkube-service: Adding a default service 'jkube-demo' with ports [8080]
[INFO] k8s: jkube-service-discovery: Using first mentioned service port '8080'
[INFO] k8s: jkube-revision-history: Adding revision history limit to 2
[INFO] k8s: validating jkube-demo/target/classes/META-INF/jkube/kubernetes/jkube-demo-deployment.yml resource
[INFO] k8s: validating jkube-demo/target/classes/META-INF/jkube/kubernetes/jkube-demo-service.yml resource
The second goal actually deploys to a Kubernetes cluster:
[INFO] --- kubernetes-maven-plugin:1.13.1:apply (default-cli) @ jkube-demo ---
[INFO] k8s: Using Kubernetes at https://kubernetes.docker.internal:6443/ in namespace null with manifest /Users/mike/github/jkube-demo/target/classes/META-INF/jkube/kubernetes.yml
[INFO] k8s: Creating a Service from kubernetes.yml namespace default name jkube-demo
[INFO] k8s: Created Service: target/jkube/applyJson/default/service-jkube-demo.json
[INFO] k8s: Creating a Deployment from kubernetes.yml namespace default name jkube-demo
[INFO] k8s: Created Deployment: target/jkube/applyJson/default/deployment-jkube-demo.json
Finally, we can use JKube to undeploy our application from the Kubernetes cluster:
mvn k8s:undeploy
Remember that each of these commands to build Docker images and deploy to Kubernetes uses opinionated views. However, JKube offers the ability to configure each of them. For full details, see the goals overview.
In addition to building Docker images and deploying them to Kubernetes, JKube offers several other tools to help with the development of applications. Below we’ll take a closer look at some of them.
This goal works similarly to the Unix tail command. It continuously shows the output of a previously deployed application.
To run this goal, we use the following command:
mvn k8s:log
The debug goal allows us to attach a Java debugger to a deployed application. Here’s the syntax of the command:
mvn k8s:debug -Djkube.debug.port=8000
Running this command does several things. First, it redeploys the application with debug enabled. Second, it creates a Kubernetes port forward on the specified debug port. After running this command, we can attach a Java debugger to the specified port and begin remote debugging.
Because constantly redeploying our application can be time-consuming, we can speed things up by always deploying with debug enabled. To do this, we have two options. First, we can add an extra flag to the deploy command:
mvn k8s:deploy -Djkube.debug.enabled=true
Alternatively, we can update our Maven settings.xml file:
<?xml version="1.0"?>
<settings>
<profiles>
<profile>
<id>enable-debug</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<jkube.debug.enabled>true</jkube.debug.enabled>
</properties>
</profile>
</profiles>
</settings>
By doing this, we avoid the waiting time while a pod restarts each time we run the debug goal.
This goal automatically redeploys an application when it detects changes in the project. To enable it, we run the command:
mvn k8s:watch
With the watch enabled, whenever a file in the project changes, JKube rebuilds and redeploys for us. JKube provides several different watchers for various frameworks, including Spring Boot.
The build command we saw earlier publishes new images to the local Docker daemon. We can then use the push goal to publish those images to any remote registry:
mvn k8s:push
Similar to the resource goal above, this goal generates deployment descriptors for Helm using suitable defaults detected from the project:
mvn k8s:resource k8s:helm
It’s worth noting that we must run the resource goal with the helm goal. This goal has a number of ways to configure the generated Helm chart.
In this article, we looked at JKube, a tool that simplifies many aspects of building Java applications for Kubernetes and OpenShift.
Through a robust Maven and Gradle plugin, it provides several tools for building, monitoring, and deploying applications to two of the most popular container management systems available.
The examples above can be found over on GitHub.