Deploy Java EE applications to Kubernetes

Last Updated:  February 16, 2020 | Published: July 6, 2019

Kubernetes is currently the de-facto standard for deploying applications in the cloud. Every major cloud provider offers a dedicated Kubernetes service (eg. Google Cloud with GKE, AWS with EKS, etc.) to deploy applications in a Kubernetes cluster. Once your stateless Java EE application (this is important, as your application will run with multiple instances) is dockerized you are ready to deploy the application to Kubernetes.

In this blog post, I'll show you how to deploy a sample Java EE 8 and MicroProfile 2.2 application running on Payara 5.192 to a local Kubernetes cluster. You can apply the same for every Kubernetes cluster in the cloud (with small adjustments for the container registry).

Setup Java EE backend

The sample application contains only the Java EE 8 and MicroProfile 2.2 API dependency and built with Maven:

The application contains just one JAX-RS resource to return a message injected via the MicroProfile Config API.

Furthermore, I've added HealthResource which implements the HealthCheck interface of the MicroProfile Health 1.0 API. This class is optional, but nice-to-have as Kubernetes will, later on, have to identify if your application is ready for traffic. In this example, the implementation is rather simple as it just returns the UP status but you could also add further business logic to mark your application as ready. There can also be multiple implementations of the HealthCheck interface in one application to check for multiple things like e.g. free disk space, database availability, etc. The result of all the health checks is then combined together under /health.

With MicroProfile 3.0 there will also be dedicated annotations for @Readiness and @Liveness to differentiate between these two states.

Prepare Kubernetes deployment

First, we need to create a Docker image for our Kubernetes deployment. With Java EE applications this is pretty straightforward, as we just copy the .war file to the deployment folder of the targeted application server. For this example, I've chosen the Payara server-full 5.192 base image.

Next, we create a so-called Kubernetes Deployment. With this Kubernetes object, we define metadata for our application. This includes which image to use, which port to expose, where to find the health endpoint. In addition, we define here how many pods (containers) should run in parallel:

In this example, I'm using a local Docker registry and reference therefore to localhost:5000/java-ee-kubernetes for the application's Docker image. If you plan to deploy your Java EE application to a Kubernetes cluster running in the cloud, you have to push your Docker image to this registry and replace the localhost:5000 e.g. eu.gcr.io/java-ee-kubernetes (gcr is Google's container registry service).

To give the pod some time for the startup I've added the initialDelaySeconds attribute to wait 45 seconds until the readiness and liveness probes are requested.

With just the deployment we wouldn't be able to access our application for outside. Therefore we have to specify the access with a so-called Kubernetes Service. The service references our previous deployment and uses the type NodePort. With this configuration, we specify a port on our Kubernetes nodes which forwards to our application's port.  For our example we use port 31000 on the Kubernetes node and forward to port 8080 of our Java EE application:

For a more advanced configuration, have a look at the Kubernetes Ingress Controllers.

Deploy to a local Kubernetes cluster

In this example, I'm deploying the application to a local Kubernetes cluster. The Kubernetes add-on is available in the latest Docker for Mac/Windows version and creates a simple cluster on-demand.

With the following steps you deploy the application to your local Kubernetes cluster:

After the two pods are up and running, you can access the application at http://localhost:31000/resources/sample and to get a greeting from the Java EE application.

You can find the source code with a step-by-step guide on GitHub.

Have fun deploying your Java EE application to Kubernetes,

Phil

>