Deploy IBM OpenLiberty apps onto Kubernetes using Eclipse JKube

Note: This blog is a part of blog Series: Deploying Java applications onto Kubernetes using Eclipse JKube

Eclipse JKube deploying OpenLiberty app into Kubernetes

Today in this blog, I would continue showcasing how Eclipse JKube makes using Kubernetes easy for Java developers while maintaining their old traditional workflow. You might already have seen my older blog posts about Eclipse JKube deploying Spring Boot and Vert.x smoothly on Kubernetes. This time we’ll see IBM OpenLiberty and try to deploy it onto Kubernetes.

What is OpenLiberty?

OpenLiberty is a really lightweight open-source framework for building fast and efficient cloud-native Java applications. It allows Java developers to configure only needed features, resulting in small memory consumption. It’s one of the few cloud-native Java frameworks that support Docker and Kubernetes.

Setting up Kubernetes:

We would be deploying one of the OpenLiberty Getting started guide onto Kubernetes using the Eclipse JKube. But first, we need to make sure our Kubernetes Cluster is running. I am using minikube so I started it using this command:

minikube start

Once, minikube is running. We need build docker image in minikube. If you were using some other Kubernetes Cluster, you would need to build and push to some docker registry. You need to expose minikube VM’s internal docker daemon to your terminal session using the following command:

# To point your shell to minikube's docker-daemon, run:
eval $(minikube -p minikube docker-env)

Getting OpenLiberty Quickstart Guide:

Now we have got all the essential setup we need to deploy our application onto Kubernetes. We’re using OpenLiberty Getting Started Guide. It contains two projects start and finish, but we’ll only consider finish since it’s the end result of the guide:

We’ll clone the project first:

git clone https://github.com/OpenLiberty/guide-getting-started.git
cd guide-getting-started/finish

Build Project:

mvn clean install

Deploying to Kubernetes:

In order to deploy application onto Kubernetes, we would add Eclipse JKube’s Kubernetes Maven Plugin to pom.xml’s plugins section:

<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>1.0.0-rc-1</version>
</plugin>

I’m using whatever is the latest version available on maven central.

Containerizing the application into a Docker image:

We can now use Eclipse JKube in our project, let’s start by containerizing this application into a Docker image. If you notice carefully, this sample already has a Dockerfile in its root folder. Eclipse JKube detects Dockerfiles automatically and does a plain docker build based on that Dockerfile. We only need to do minor modifications inside the Dockerfile so that it is Eclipse JKube can work with it without any problems.

Eclipse JKube provides a really nice assembly mechanism that is similar to the maven assembly plugin. So you can copy your files into your container by providing simple assembly configuration. When you don’t provide any configuration(zero configuration modes), it’s maven/ by default. When you’re building in plain Dockerfile mode, your dockerfile’s parent directory is considered to be docker context directory. So it will be copied to your docker container under default assembly configuration(maven/). So you need to prefix your file references with maven. Here is how modified Dockerfile would look like:

Modifying project files’ relative path in Dockerfile and exposing ports

Note that I’ve only changed project file references and exposed a few ports so that it can be accessed from outside the image. Okay, we can proceed with building docker image using the k8s:build goal:

mvn k8s:build

finish : $ mvn k8s:build
[INFO] Scanning for projects...
[INFO]
[INFO] -----< io.openliberty.guides:guide-getting-started >-----
[INFO] Building guide-getting-started 1.0-SNAPSHOT
[INFO] --------------[ war ]---------------------------------
[INFO]
[INFO] --- kubernetes-maven-plugin:1.0.0-rc-1:build (default-cli) @ guide-getting-started ---
[INFO] k8s: Running in Kubernetes mode
[INFO] k8s: Building Docker image in Kubernetes mode
[INFO] k8s: [guides/guide-getting-started:latest]: Created docker-build.tar in 10 seconds
[INFO] k8s: [guides/guide-getting-started:latest]: Built image sha256:424e8
[INFO] k8s: [guides/guide-getting-started:latest]: Removed old image sha256:ad954
[INFO] --------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------------------------
[INFO] Total time: 01:35 min
[INFO] Finished at: 2020-08-22T19:46:23+05:30
[INFO] --------------------------------------------------------------------
finish : $ docker images | grep guide-getting-started
guides/guide-getting-started latest 424e87972dcb 6 min ago 741MB

You can check the image build by inspecting with docker, you can also go ahead and push your image to some specified registry using k8s:push goal. But since we’re doing all this locally inside minikube, I’m skipping it for now.

Generating and applying Kubernetes manifests:

Now that your image is built, you can go ahead and generate resource manifests for your project. Eclipse JKube checks image ports and generates opinionated Service and Deployment. if you want to customize it, you can provide custom YAML fragments in src/main/jkube directory or using XML configuration. I will be using two properties to override some Service configuration:

<jkube.enricher.jkube-service.port>9080</jkube.enricher.jkube-service.port>
<jkube.enricher.jkube-service.type>NodePort</jkube.enricher.jkube-service.type>

The first one tells Eclipse JKube’s enricher API to consider 9080 port for Service and second one tells Eclipse JKube to generate a Service of type NodePort(by default a ClusterIP service is generated).

Okay, Once you add these properties, you can go ahead and run k8s:resource goal. You can also go ahead and apply the generated resources using k8s:apply goal

mvn k8s:resource k8s:apply

finish : $ mvn k8s:resource k8s:apply
[INFO] Scanning for projects...
[INFO]
[INFO] ------< io.openliberty.guides:guide-getting-started >--------
[INFO] Building guide-getting-started 1.0-SNAPSHOT
[INFO] ----------------------[ war ]-------------
[INFO]
[INFO] --- kubernetes-maven-plugin:1.0.0-rc-1:resource (default-cli) @ guide-getting-started ---
[INFO] k8s: jkube-controller: Adding a default Deployment
[INFO] k8s: jkube-service: Adding a default service 'guide-getting-started' with ports [9080]
[INFO] k8s: jkube-revision-history: Adding revision history limit to 2
[INFO] k8s: validating /home/rohaan/work/repos/openliberty-guide-getting-started/finish/target/classes/META-INF/jkube/kubernetes/guide-getting-started-service.yml resource
[INFO] k8s: validating /home/rohaan/work/repos/openliberty-guide-getting-started/finish/target/classes/META-INF/jkube/kubernetes/guide-getting-started-deployment.yml resource
[INFO]
[INFO] --- kubernetes-maven-plugin:1.0.0-rc-1:apply (default-cli) @ guide-getting-started ---
[INFO] k8s: Using Kubernetes at https://192.168.39.71:8443/ in namespace default with manifest /home/rohaan/work/repos/openliberty-guide-getting-started/finish/target/classes/META-INF/jkube/kubernetes.yml
[INFO] k8s: Using namespace: default
[INFO] k8s: Creating a Service from kubernetes.yml namespace default name guide-getting-started
[INFO] k8s: Created Service: target/jkube/applyJson/default/service-guide-getting-started-1.json
[INFO] k8s: Creating a Deployment from kubernetes.yml namespace default name guide-getting-started
[INFO] k8s: Created Deployment: target/jkube/applyJson/default/deployment-guide-getting-started-1.json
[INFO] k8s: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] --------------------------------------------------------------------[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------------------------[INFO] Total time: 8.726 s
[INFO] Finished at: 2020-08-22T20:02:47+05:30
[INFO] --------------------------------------------------------------------
finish : $

Checking deployed application running in Kubernetes:

You can check whether application got deployed using kubectl:

Checking application pods running in Kubernetes after jkube deploy

You can see that your application has been successfully deployed into minikube. You can try accessing it using minikube service command:

finish : $ minikube service guide-getting-started|-----------|-------------|-------------|--------------------------|
| NAMESPACE | NAME| TARGET PORT | URL | |-----------|-------------|-------------|--------------------------|
| default | guide-getting-started | glrpc/9080 | http://192.168.39.71:31104 |
|-----------|---------------|-------------|------------------------|
🎉 Opening service default/guide-getting-started in default browser...
OpenLiberty Geting started sample running inside minikube(output of minikube service)

You can also check for logs of your application using k8s:log goal:

mvn k8s:log

Once everything is done, you can simply undeploy your application from Kubernetes using k8s:undeploy goal:

mvn k8s:undeploy

This concludes today blog. I hope you found it useful. I have a fork of the original OpenLiberty getting-started-guide used in the project with everything set up, maybe you can check it out:

For more information, please visit project website:

This post is also published on my Wordpress