For cloud-native applications Kubernetes and Istio deliver a lot of important functionality out of the box, for example to ensure resiliency and scalability. This functionality works generically for microservices, no matter in which language they have been implemented and independent from the application logic.
Some cloud-native functionality however cannot be handled by Kubernetes and Istio, since it needs to be handled in the business logic of the microservices, for example application specific failover functionality, metrics and fine-grained authorization.
That’s why I started to look into Eclipse MicroProfile which is an extension to JavaEE to build microservices-based architectures and a great programming model for Istio. In addition to the application specific logic that Istio cannot handle, it also comes with convenience functionality that you typically need when developing microservices, for example invoking REST APIs and implementing REST APIs including their documentation.
Get the code of the cloud-native starter sample.
The first thing you need to run MicroProfile applications on Kubernetes is an image. MicroProfile is supported by several Java application servers, different JVMs can be used and there are different versions of all of these components. Because of this there are many different images you need to choose from.
FROM openliberty/open-liberty:microProfile2-java8-openj9 ADD https://github.com/WASdev/sample.opentracing.zipkintracer/releases/download/1.2/liberty-opentracing-zipkintracer-1.2-sample.zip / RUN unzip liberty-opentracing-zipkintracer-1.2-sample.zip -d /opt/ol/wlp/usr/ \ && rm liberty-opentracing-zipkintracer-1.2-sample.zip COPY liberty/server.xml /config/ ADD target/articles.war /config/dropins/
The image contains these components:
There are several different images available for Open Liberty. I picked a community image since it comes with OpenJ9 instead of the IBM version of OpenJ9. Unfortunately that image doesn’t seem to support MicroProfile 2.2 yet (at least I haven’t found it).
Additionally I download and copy a file needed for Zipkin tracing onto the image which you need to do manually at this point if you want to use the tracing functionality built into MicroProfile. This functionality is pretty useful since it allows you to see the chains of invocations between microservices.
This screenshot shows the Jaeger dashboard. The BFF (backend for frontend) ‘web-api’ microservice invokes another ‘articles’ service:
Variations of the Dockerfile
In order to avoid downloading the Zipkin file every time a new image is built, I’ve created a slightly different Dockerfile where the file is added from a local directory. The image is built with a script that downloads the file if it doesn’t exist locally. Alternatively you can download the file via Maven (check out the example pom.xml and example Dockerfile).
Additionally I have created another variation of the Docker image so that my sample application can be installed even by people who don’t have Java and Maven installed locally (or who have wrong Java/Maven versions). This Dockerfile uses a multistage build.
FROM maven:3.5-jdk-8 as BUILD COPY src /usr/src/app/src COPY pom.xml /usr/src/app RUN mvn -f /usr/src/app/pom.xml clean package FROM openliberty/open-liberty:microProfile2-java8-openj9 ADD liberty-opentracing-zipkintracer-1.2-sample.zip / RUN unzip liberty-opentracing-zipkintracer-1.2-sample.zip -d /opt/ol/wlp/usr/ \ && rm liberty-opentracing-zipkintracer-1.2-sample.zip COPY liberty/server.xml /config/ COPY --from=BUILD /usr/src/app/target/articles.war /config/dropins/
$ git clone https://github.com/nheidloff/cloud-native-starter.git $ scripts/check-prerequisites.sh $ scripts/deploy-articles-java-jee.sh $ scripts/deploy-web-api-java-jee.sh