Skip to content

How to run a Jakarta EE microservices app in Kubernetes using plain maven

License

Notifications You must be signed in to change notification settings

OndrejM-demonstrations/JakartaEE-Kubernetes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

First Cup of Jakarta EE in Kubernetes

This is an example project that demonstrates how to deploy simple Jakarta EE application to a Kubernetes cluster in a way that is familiar to Java developers. The application is based on an application from the "First Cup of Jakarta EE" tutorial.

Description of the application

The application consists of a frontend "firstcup-war" service and a separate "dukes-age" REST microservice. The firstcup-war frontend provides a simple Web-based frontend and calls the dukes-age microservice to retrieve information about the age of Duke, the Java mascot.

When run locally, the firstcup-war service contacts the dukes-age service at a URL that points to localhost. This can be changed by supplying a system property or an environment variable. When deployed to Kubernetes, the dukes-age service is assigned a DNS name and the firstcup-war is configured using an environment variable to contact the dukes-age service using that DNS name.

Deployment in Kubernetes

Both services are built as a Docker image based on the official Payara Micro Docker image. The JIB maven plugin copies the exploded WAR directory to the Docker image and then instructs Payara Micro to deploy the application from that directory.

The Docker images are then deployed to a Docker repository from which the Kubernetes cluster can pull them. It might be the public Docker Hub or a private repository. The default configuration of the build assumes that the Kubernetes cluster runs locally using MicroK8s and that there's a private local repository provided by MicroK8s.

The JKube Kubernetes Maven plugin is used to prepare the Kubernetes deployment files and also to apply them to a running Kubernetes cluster using the kubectl CLI tool.

For the firsctup-war frontend, a Kubernetes service of type LoadBalancer is created so that it can be accessed from outside of the Kubernetes cluster. The default deployment generated by the maven plugin is modified in pom.xml to set the image pull policy to Always (while in development phase) and in src/main/jkube/deployment.yml template file to set the environment variable DUKES_AGE_URL to point to the URL of the dukes-age service using its DNS name.

For the dukes-age service, a Kubernetes service is created so that the dukes-age service is assigned a fixed DNS name used by the firstcup-war service to access it. We chose the type LoadBalancer only to allow scaling of the dukes-age service to multiple replicas if needed.

Build the example

Clone this repository and build the example using:

mvn package

Run the example locally

Run the Duke's age service

In the directory dukes-age, run:

mvn payara-micro:start  

It should start the service at http://localhost:8080/. Test using http://localhost:8080/webapi/dukesAge.

Run the First Cup frontend

In the directory firstcup-war, run:

mvn payara-micro:start  

It should start the service at http://localhost:8081/. Open the URL in a browser.

Run the example in a Kubernetes cluster

Before going further, this example project assumes that:

  • you already have a Kubernetes cluster to which you can deploy this example application
  • the kubectl command is installed and configured to access an existing Kubernetes cluster (it was tested with MicroK8s)
  • you already have a Docker registry to which you can deploy Docker images. The path to the registry is by default set to localhost:32000, this can be changed by a maven property docker.registry. If you have a local MicroK8s cluster, you can just enable the registry add-on with microk8s enable registry. If you want to use the public Docker Hub registry, set the property to docker.io with the -D maven command line option or in the parent pom.xml.

Then you can build and deploy the application to the Kubernetes cluster using the following maven command:

mvn install

You can then access the firstcup-war frontend either using the URL generated by your cloud provider on port 8080 or forward the port 8080 to your local machine using the following kubectl command:

kubectl port-forward service/firstcup-war 8082:8080

Then you can access it using http://localhost:8082

Deploying the application step by step

If you want to play with the build configuration, you can perform the deployment steps individually. First build the project using mvn package and then invoke individual deployment steps as follows:

Build and deploy Docker images

In order to build and deploy Docker images to a local MicroK8s Docker repository at http://localhost:32000, run the following in the project root:

mvn jib:build

If you want to deploy to a different Docker repository, specify its address with the docker.registry property like this:

mvn -Ddocker.registry=docker.io jib:build

Generate K8s resources from maven

mvn k8s:resource

The resources are generated in the directory target/classes/META-INF/jkube for each service. Their content is configured in the Kubernetes plugin configuration in pom.xml and using the template files in src/main/jkube for each service.

Deploy to K8s from maven

mvn k8s:apply

This uses the kubectl command to apply the K8s resources previously generated by the k8s:resource goal.

About

How to run a Jakarta EE microservices app in Kubernetes using plain maven

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published