Rapidly Develop Java Microservices on Kubernetes With Telepresence

Many organizations adopt cloud native development practices with the dream of shipping features faster. Kubernetes has become the de facto container orchestration platform for building cloud native applications and although it provides great opportunities for development teams to move faster, the learning curve can be steep and the burden often falls on application developers who have to learn new processes and tools. 

Challenges of Developing Locally With Kubernetes

For larger enterprises, Kubernetes and cloud architectures present a critical challenge compared to monolithic legacy applications. As Kubernetes applications evolve into complex microservice architectures, the development environments also become more complex as every microservice adds additional dependencies. These services quickly start to need more resources than are available in your typical local development environment. 

For Java developers this challenge is magnified as Java services are often more resource intensive than services written in other languages. If you can’t run your application on your local machine, how do you develop quickly? 

In this tutorial, we’ll set up a development environment for Kubernetes and make a change to a Java microservice. Normally to develop locally and integrate with other services in a remote cluster, we would have to wait for a container to build, a push to the registry, and a deploy in order to see the effect of our code change. Instead, we’ll use Telepresence to see the results of our change instantly. 

Step 1: Deploy a Sample Microservices Application

For our example, we’ll make code changes to a Java data processing service that is running between a resource-intensive Java service and a large datastore. We’ll start by deploying a sample microservice application consisting of 3 services: 

Note: We’ve called these “VeryLarge” services to emphasize the fact that your local environment may not have enough CPU and RAM to run these, or you may just not want to pay for all that extra overhead for every developer. 


In this architecture diagram, you’ll notice that requests from users are routed through an ingress controller to our services. For simplicity’s sake, we’ll skip the step of deploying an ingress controller in this tutorial. 

If you’re ready to use Telepresence in your own setup and need a simple way to set up an ingress controller, we recommend checking out the Ambassador Edge Stack which can be easily configured with the K8s Initializer. 

Let’s deploy the sample application to your Kubernetes cluster with a simple kubectl command:

Plain Text
 




xxxxxxxxxx
1


 
1
kubectl apply -f https://raw.githubusercontent.com/datawire/edgey-corp-java/main/k8s-config/edgey-corp-web-app-no-mapping.yaml



If you run kubectl get svc you should see something similar to this:

Plain Text
 




x


 
1
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
2
dataprocessingservice   ClusterIP   10.3.250.98    <none>        3000/TCP   10s
3
kubernetes              ClusterIP   10.3.240.1     <none>        443/TCP    2m6s
4
verylargedatastore      ClusterIP   10.3.242.75    <none>        8080/TCP   7s
5
verylargejavaservice    ClusterIP   10.3.241.208   <none>        8080/TCP   8s



Step 2: Set up Your Local Java Development Environment 

We’ll need a local development environment so that we can edit the `DataProcessingService` service. As you can see in the architecture diagram above, the `DataProcessingService` is dependent on both the `VeryLargeJavaService` and the `VeryLargeDataStore`, so in order to make a change to this service, we’ll have to interact with these other services as well. Let’s get started!

1. Clone the repository for this application from GitHub.

Shell
 




x


 
1
git clone https://github.com/datawire/edgey-corp-java.git



2. Change directories into the DataProcessingService

Shell
 




xxxxxxxxxx
1


 
1
cd edgey-corp-java/DataProcessingService



3. Start the Java server:

Shell
 




xxxxxxxxxx
1


 
1
mvn spring-boot:run



4. After Maven finishes downloading a few dependencies you should be able to see your service running and listening on port 3000 

Plain Text
 




xxxxxxxxxx
1


 
1
o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 3000 (http) with context path ''
2
 
          
3
...
4
 
          
5
 g.d.DataProcessingServiceJavaApplication : Started DataProcessingServiceJavaApplication in 1.408 seconds (JVM running for 1.684)



5. In another terminal window, curl localhost:3000/color to see that the service is returning `blue`.

Shell
 




xxxxxxxxxx
1


 
1
$ curl localhost:3000/color
2
"blue"



Step 3: Rapid Development With Telepresence

Instead of waiting for a container image to build and then pushing to a repository and deploying to your Kubernetes cluster you are going to use Telepresence, an open source Cloud Native Computing Foundation (CNCF) project. Telepresence creates a bidirectional network connection between your local development and the Kubernetes cluster to enable fast, efficient Kubernetes development. 

  1. Install the Telepresence CLI : 

Shell
 




xxxxxxxxxx
1


 
1
# Mac OS X
2
 
          
3
sudo curl -fL https://app.getambassador.io/download/tel2/darwin/amd64/latest/telepresence -o /usr/local/bin/telepresence 
4
 
          
5
 
          
6
#Linux
7
 
          
8
sudo curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o /usr/local/bin/telepresence



  1. Make the binary executable 

Shell
 




xxxxxxxxxx
1


 
1
sudo chmod a+x /usr/local/bin/telepresence



  1. Test Telepresence by connecting to the remote cluster 

Shell
 




xxxxxxxxxx
1


1
telepresence connect



  1. Send a request to the Kubernetes API server using the cluster's internal service domain name: 

Shell
 




xxxxxxxxxx
1


 
1
curl -ik https://kubernetes.default.svc.cluster.local 



You should see something similar to this response (a 4XX error is expected):

Plain Text
 




xxxxxxxxxx
1


 
1
HTTP/1.1 401 Unauthorized 
2
Cache-Control: no-cache, private 
3
Content-Type: application/json 
4
Www-Authenticate: Basic realm=”kubernetes-master”
5
Date: Tue, 09 Feb 2021 23:21:51 GMT



Great! You’ve successfully configured Telepresence. Right now, Telepresence is intercepting the request you’re making to the Kubernetes API server, and routing over its direct connection to the cluster instead of over the Internet. 


Step 4: Intercept Your Java Service 

An intercept is a routing rule for Telepresence. We can create an intercept to route traffic intended for the `DataProcessingService` in the cluster and instead route all of the traffic to the local version of the `DataProcessingService` running on port 3000. 

  1. Create the intercept:

Shell
 




xxxxxxxxxx
1


 
1
telepresence intercept dataprocessingservice --port 3000



  1. Access the application directly with Telepresence. Visit http://verylargejavaservice:8080. Again, Telepresence is intercepting requests from your browser and routing them directly to the Kubernetes cluster. You should see a web page that shows the current application's architecture. The title of the page should also be shown in blue.

  2. Now, we’ll make a code change. Open the file located at `edgey-corp-java/DataProcessingService/src/main/resources/application.properties` and change the value of the `app.default.color` variable on line 2 from `blue` to `orange`. Save the file and restart your Java server.

  3. Reload the page in your browser and see how the title color has changed from blue to orange! 

That’s it! With Telepresence you saw how quickly you can go from editing a local service to seeing how these changes will look when deployed with the larger application. 

When you compare it to the traditional process of building and deploying a container after every change it’s very easy to see how much time you can save, especially as you make more complex changes or run even larger services. 

Learn More About Telepresence 

Today, you’ve learned how to use Telepresence to rapidly iterate on a Java microservice running in Kubernetes. Now, instead of waiting for slow local development processes consisting of a container build-push-deploy, we can iterate quickly with an instant feedback loop and a productive cloud native development environment. 

If you want to learn more about Telepresence, check out the following resources: 

In our next tutorial, we’ll use Telepresence to set up a local Kubernetes development environment and then use IntelliJ to set breakpoints and debug a broken service. To be notified when more tutorials are available, make sure to check out our website or follow us on Twitter. 

 

 

 

 

Top