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:
VeryLargeJavaService: A memory-intensive service written in Java that generates the front-end graphics and web pages for our application
DataProcessingService: A Java service that manages requests for information between the two services.
VeryLargeDataStore: A large datastore service that contains the sample data for our Edgey Corp store.
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:
xxxxxxxxxx
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:
x
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dataprocessingservice ClusterIP 10.3.250.98 <none> 3000/TCP 10s
kubernetes ClusterIP 10.3.240.1 <none> 443/TCP 2m6s
verylargedatastore ClusterIP 10.3.242.75 <none> 8080/TCP 7s
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.
git clone https://github.com/datawire/edgey-corp-java.git
2. Change directories into the DataProcessingService
xxxxxxxxxx
cd edgey-corp-java/DataProcessingService
3. Start the Java server:
xxxxxxxxxx
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
xxxxxxxxxx
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 3000 (http) with context path ''
...
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`.
xxxxxxxxxx
$ curl localhost:3000/color
"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.
Install the Telepresence CLI :
xxxxxxxxxx
# Mac OS X
sudo curl -fL https://app.getambassador.io/download/tel2/darwin/amd64/latest/telepresence -o /usr/local/bin/telepresence
#Linux
sudo curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o /usr/local/bin/telepresence
Make the binary executable
xxxxxxxxxx
sudo chmod a+x /usr/local/bin/telepresence
Test Telepresence by connecting to the remote cluster
xxxxxxxxxx
telepresence connect
Send a request to the Kubernetes API server using the cluster's internal service domain name:
xxxxxxxxxx
curl -ik https://kubernetes.default.svc.cluster.local
You should see something similar to this response (a 4XX error is expected):
xxxxxxxxxx
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache, private
Content-Type: application/json
Www-Authenticate: Basic realm=”kubernetes-master”
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.
Create the intercept:
xxxxxxxxxx
telepresence intercept dataprocessingservice --port 3000
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.
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.
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:
Read the docs
Watch the demo video
Read more about Intercepts
Learn about Preview URLs for easy collaboration with teammates
Join our Slack channel to connect with the Telepresence community
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.