Kubernetes Remote Development in Java Using Kubernetes Maven Plugin
Introduction
In this article, we’re going to look at some pain points while developing Java applications on top of Kubernetes. We’re going to look at newly added functionality in Eclipse JKube’s Kubernetes Maven Plugin that allows your application running on your local machine to get exposed in Kubernetes Cluster.
If you haven’t heard about Eclipse JKube or Kubernetes Maven Plugin, I’d suggest you read the following DZone articles first:
- DZone: Deploy Maven Apps to Kubernetes With JKube Kubernetes Maven Plugin
- DZone: Containerize Gradle Apps and Deploy to Kubernetes With JKube Kubernetes Gradle Plugin
Target Audience:
- This blog post targets Java developers who are working with Kubernetes and are familiar with containerized application development. We’re assuming that the reader has experience with Docker and Kubernetes.
- Eclipse JKube’s Kubernetes Remote Development functionality is suitable for Java developers working on Java applications communicating with several micro-services in Kubernetes, which is difficult to replicate on your local machine.
Current Solutions
- Docker Compose: You can provide your own YAML file to configure your application services and start all services by your provided YAML configuration. This is only limited to Docker environment. Sometimes these services can be impossible to start due to resource constraints. Also, we may not be allowed to duplicate sensitive data locally.
- Dev Services: Some popular frameworks also support the automatic provisioning of dependent services in development/testing environments. Developers only need to worry about enabling this feature, and the framework takes care of starting the service and wiring it with your application. This is also limited to Docker environment.
- Build and Deploy Tooling: Use Kubernetes-related tooling to deploy all dependent services and then deploy your application to Kubernetes.
- Not smooth as compared to previous alternatives that are limited to Docker
- Building and deploying applications on every small change leads to slower development iterations
What Is Eclipse JKube Kubernetes Remote Development
Our team at Eclipse Cloud Tooling is focused on creating tools that ease developer activity and development workflow across distributed services. While working and testing on Kubernetes Maven Plugin, we noticed that repeatedly building and deploying applications to Kubernetes while developing locally isn’t the most effective way of working.
In v1.10.1 of Kubernetes Maven Plugin, we added a new goal k8s:remote-dev . This goal tries to ease java developer workflow across distributed services via:
- Consuming remote services that are running inside the Kubernetes cluster
- Live application coding while interacting with other services running in Kubernetes Cluster
- Exposing applications running locally or by connecting to remote services
Why Kubernetes Remote Development?
Let’s consider a scenario where we’re writing a joke microservice that tries to fetch joke strings from other microservices. Here is a diagram for you to get a better understanding:
Custom Joke Service is our main application which has one endpoint /random-joke. It depends on two other microservices ChuckNorris and Jokes via /chuck-norris and /joke endpoints, respectively. The user requests a joke using /random-joke endpoint, and our application fetches a joke string from one of the two microservices randomly.
In order to develop and test our application, we need access to these dependent ChuckNorris and Jokes services, respectively. Let’s see what the developer’s workflow would look like:
- While developing and testing Custom Joke Microservice locally, the developer has to set up dependent microservices locally again and again.
- In order to verify the application is working properly in Kubernetes. The developer has to build, package and deploy the Custom Joke application to Kubernetes in every development iteration.
- The dependent Services (ChuckNorris and Joke) might be quite heavyweight services and might have some dependent services of their own. It might not be straightforward to set up these locally in the developer’s environment.
Exposing Remote Kubernetes Services Locally
Let’s assume you have two applications already running in Kubernetes Cluster on which your current application is dependent:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service1 NodePort 10.101.224.227 <none> 8080:31878/TCP 113s
service2 NodePort 10.101.224.227 <none> 8080:31879/TCP 113s
Let us expose these remote services running in Kubernetes Cluster to our local machine. Here is a diagram for you to better understand:
In order to do that, we need to provide XML configuration to our plugin for exposing these services:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<remoteDevelopment>
<remoteServices>
<remoteService>
<hostname>service1</hostname> <!-- Name of Service -->
<port>8080</port> <!-- Service port -->
<localPort>8081</localPort> <!-- Local Port where to expose -->
</remoteService>
<remoteService>
<hostname>service2</hostname> <!-- Name of Service -->
<port>8080</port> <!-- Service Port -->
<localPort>8082</localPort> <!-- Local Port where to expose -->
</remoteService>
</remoteServices>
</remoteDevelopment>
</configuration>
</plugin>
The above configuration is doing these two things:
- Expose Kubernetes service named service1 on port 8081 on your local machine
- Expose Kubernetes service named service2 on port 8082 on your local machine
Run Kubernetes Remote Development goal:
$ mvn k8s:remote-dev
[INFO] Scanning for projects...
[INFO]
[INFO] -----------< org.eclipse.jkube.demos:random-jokes-generator >-----------
[INFO] Building random-jokes-generator 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- kubernetes-maven-plugin:1.10.1:remote-dev (default-cli) @ random-jokes-generator ---
[INFO] k8s: Waiting for JKube remote development Pod [jkube-remote-dev-9cafc1e1-054b-4fab-8f4e-b4345056478e] to be ready...
[INFO] k8s: JKube remote development Pod [jkube-remote-dev-9cafc1e1-054b-4fab-8f4e-b4345056478e] is ready
[INFO] k8s: Opening remote development connection to Kubernetes: jkube-remote-dev-9cafc1e1-054b-4fab-8f4e-b4345056478e:54252
[INFO] k8s: Kubernetes Service service1:8080 is now available at local port 8081
[INFO] k8s: Kubernetes Service service2:8080 is now available at local port 8082
Try accessing services available locally on ports:
$ curl localhost:8081/
Chuck Norris's OSI network model has only one layer - Physical.
$ curl localhost:8082/
Why do Java programmers have to wear glasses? Because they don't C#.
As you can see, You are able to access Kubernetes services service1 and service2 locally on ports 8081 and 8082, respectively.
Conclusion
In this article, you learned about Eclipse JKube’s Kubernetes Maven Plugin’s remote development goal and how you can expose your local applications to the Kubernetes cluster and vice versa.
In case you’re interested in knowing more about Eclipse JKube, you can check these links:
- Documentation
- Github Issue Tracker
- StackOverflow
- YouTube Channel
- Gitter Chat