6 min read

JHipster MicroService Application in Kubernetes KIND

On this blog post I will be going through all the process from creating a MicroServices application with JHipster to run the application into a KIND Kubernetes cluster.

Prerequisites

We will generate an Application form a JHipster JDL DSL, which describes a JHipster Application using the MicroServices approach. This application is composed by:

  • A Gateway that also hosts the User Internface
  • Invoice Service (which hosts three entities: Shipment, Order, Invoice)
  • Review Service (which doesn't have any entity but will be in charge of reviewing the Invoice Service Entities)

You can find the app.jdl file in this repository.

Generating a JHipster Application

In order to create the source code for this application we need to import our JDL file by calling (you can find the **app.jdl** file inside the example-app/ directory):

> jhipster import-jdl app.jdl

By running this command we will generate 3 maven projects:

  • gateway (will run by default in port 8080)
  • invoice (use 8081)
  • review (use 8081)

Running your application in Kubernertes

In order to run your application (microservices) in Kubernetes you need to generate Kubernetes Manifests, which are basically files that describe how Kubernetes will deploy and manage your services.
In general to work with JHipster into Kubernetes you will follow these steps:

Today, there are three ways in which you can create the K8s manifests:

  • You create your own manifests
  • You can use jhipster kubernetes generator
  • You can use jhipster kubernetes-helm generator

Let's use the second option for simplicity (but I encourage you to try the HELM approach as well):

> mkdir kubernetes/ > cd kubernetes/ > jhipster kubernetes

**Note**: The generated manifest can be found inside [example-app/kubernetes/](https://github.com/salaboy/jhipster-operator/tree/master/example-app).

These manifests points to public docker images, if you want to use your locally generated images in KIND, you will need to modify the deployment manifests.

Then choose:

1) Microservice application + Enter 2) root directory ../ + Enter 3) select the three services (gateway, invoice, review) with space and the arrows and then Enter 4) Monitoring -> No 5) Admin password (admin) Enter 6) namespace: I will use "jhipster" + Enter 7) name for the docker repository name (if you are planning to push your images to hub.docker.com) you should use your user name, I will use a local docker registry, so just Enter 8) docker push (default value) + Enter 9) No Istio for now 10) Service Type for your edge services (in this case the gateway), I will choose LoadBalancer + Enter

An example of these manifests can be found here
After this all the Kubernetes Manifest to run your services are generated. The only missing step is to generate your docker images that are going to be used by these manifest to run your services in the cluster.
The output of the generation shows how to create these docker images for each service. Everytime that you make a change in the service, you should generate a new docker image to contain those changes:

To generate the missing Docker image(s), please run: ./mvnw -Pprod verify jib:dockerBuild in /gateway ./mvnw -Pprod verify jib:dockerBuild in /invoice ./mvnw -Pprod verify jib:dockerBuild in /review

You will also see in the output:

WARNING! You will need to push your image to a registry. If you have not done so, use the following commands to tag and push the images: > docker push gateway > docker push invoice > docker push review

This last step (of pushing the docker images) is only required if the Cluster is remote and you have no other way to make the images available to the cluster.
Now all you need is a cluster to run these services, welcome Kubernetes KIND.

Kubernetes KIND

KIND stands for Kubernetes in Docker and based on their own description:

kind is a tool for running local Kubernetes clusters using Docker container "nodes".kind is primarily designed for testing Kubernetes 1.11+, initially targeting the conformance tests.

This is a great tool because it allows us to run a multi node cluster only depending on Docker. We don't need any VM tooling such as Vagrant used in projects like Minikube, for example. Also the fact that KIND is targeting conformance tests, means that we have an hermetic environment where we can run our tests against a cluster that looks (from the API and topology prespective) pretty much as our production environments.


KIND allows us to create and delete clusters in an automated fashion, then we can automate deploying our services into it. This becomes really important when we have services or Operators which needs to interact with the cluster, due we don't want to mock those interactions, we want to test the real cluster behaviour for our components.


With KIND installed just run:

> kind create cluster

Once the cluster is up, you can try it out with:

> kubectl get pods

This should output:

No resources found.

Deploying our application to KIND Cluster

Before moving forward we need to generate the docker images for our services, let's run what was suggested by the "jhipster kubernetes" generator

To generate the missing Docker image(s), please run: ./mvnw -Pprod verify jib:dockerBuild in /gateway ./mvnw -Pprod verify jib:dockerBuild in /invoice ./mvnw -Pprod verify jib:dockerBuild in /review

Once this is done, we now should have 3 docker images loaded in our local Docker Deamon. Now we need to make these images available to KIND.Which we can do with:

> kind load docker-image gateway > kind load docker-image invoice > kind load docker-image review

Before running the services, we need to adapt some of the Manifests to make sure that the Docker Images are not downloaded from a remote docker registry.

*This is KIND specific.** And this is only required if you want to run with your own custom images. If you want to run this application in a remote clusterthe docker images for these services are published in Docker Hub:

salaboy/gateway:jhipster
salaboy/invoice:jhipster
salaboy/review:jhipster

We need to change the following files inside the kubernetes (manifest directory, generated by jhipster kubernetes.):

  • gateway/gateway-deployment.yml
  • invoice/invoice-deployment.yml
  • review/review-deployment.yml

You need to locate the section:

containers: - name: gateway-app image: gateway

and add:

imagePullPolicy: Never

to look like:

containers: - name: gateway-app image: gateway imagePullPolicy: Never

Then, as suggested by the generator to deploy all the services into K8s:

> bash kubectl-apply.sh

The output should look like:

namespace/jhipster created configmap/application-config created secret/registry-secret created service/jhipster-registry created statefulset.apps/jhipster-registry created deployment.apps/gateway created deployment.apps/gateway-mysql created service/gateway-mysql created service/gateway created deployment.apps/invoice created deployment.apps/invoice-mysql created service/invoice-mysql created service/invoice created deployment.apps/review created deployment.apps/review-mysql created service/review-mysql created service/review created

Notice that this created in the first line a new namespace called **jhipster** as it was instructred in the generator wizard.Also notice that we are creating 3 pods which will run MySQL, and KIND will need to fetch from Docker Hub the MySQL docker image the first time that you run these commands.


In order to change the current namespace (so we can get resources without specifying the namespace everytime) we can switch to the jhipster one by running:

> kubectl config set-context $(kubectl config current-context) --namespace=jhipster

Once this is done we can check that our services are running:

> kubectl get pods

We should see all the Pods up and running:

gateway-9ffdb4796-jf2j2          1/1     Running   0          6m17s gateway-mysql-6dc7d6dcf8-glgmz   1/1     Running   0          6m17s invoice-6c8cb9f459-6m99n         1/1     Running   0          6m17s invoice-mysql-7fbbbb77b6-kx5jr   1/1     Running   0          6m17s jhipster-registry-0              1/1     Running   0          6m17s jhipster-registry-1              1/1     Running   0          5m38s review-7b9b756d95-txctz          1/1     Running   0          6m16s review-mysql-6db96464bd-scvsw    1/1     Running   0          6m16s

Then to access the service, because we are running in a local cluster, we need to use port-forward

> kubectl port-forward svc/gateway 8080:8080 -n jhipster

Now you should be able to access your JHipster Application by pointing your browser to http://localhost:8080

Summing up

Now you can run your JHipster Applications using KIND, which enable you to have a repeatable environment which is really close to what a production environment will look like.

Future work might include use KIND for integration testing of our JHipster Applications. If you have questions feel free to drop me a message here on in Twitter: @salaboy.