Jolie micro services on Kubernetes

Jolie is a (micro) service-oriented language.
Jolie's capabilities work well with Docker and you can find an example in the official documentation here.
So deploying a Jolie service in a Docker container is quite easy.
Now it's time to go onboard with Kubernetes ;-)


This is only a little demo on how to set up a Kubernetes environment on your PC (thanks to minikube) and build up a scalable clusterized version of Jolie's "Hello world" example.

You can find Jolie examples on this GitHub project.


What we are going to do now is to transform "01_getting_started" sample (which simply twices a number) into a powerful Kubernetes scalable app (doing exactly the same thing, but in a cool way).

If you object that this is very unreasonable, I have to remind you that it is perfectly aligned with today's software industry standards. :-P

To be honest I'm not going to explain what Kubernetes is and how it does what it does, so please go read a tutorial or the beautiful official documentation.

My favourite starting point is this (it's not a joke).

First of all, let's set up your box!
You need:
  • Linux (tested on Ubuntu 18.04) or Windows 10 Pro (tested on 1909) with HyperV support enabled
  • Jolie language
  • Docker
  • Minikube (on Win10 I suggest you to force version 1.5.0 installation to avoid some fresh annoying bugs)
Ok, ready?
Now you can clone this repository and go ahead.

STEP 1 - Create a Docker image containing your Jolie application

As previously said this is very simple following the official documentation and using images available on Docker Hub.

This is our Dockerfile to build an image exposing the "twice-a-number" server on 8000 port:

FROM jolielang/jolie
EXPOSE 8000
COPY server.ol server.ol
COPY twiceInterface.iol twiceInterface.iol
CMD jolie server.ol
Before creating the image we have to configure Docker's environment to point to minikube, otherwise images wouldn't be available to your local cluster.

Linux
$ eval $(minikube docker-env)
Win10 (on PowerShell)
PS> & minikube docker-env | Invoke-Expression

Ok, now we can build our image (if not specified commands are the same on both platforms, don't miss the final dot):

$ docker build -t jolie-k8s-sample .

and verify all went as expected:

$ docker images
REPOSITORY                TAG                 IMAGE ID     
jolie-k8s-sample          latest              2df927523a30 ...

STEP 2 - Create a Kubernetes deployment

So we are ready to use our brand new image in a Kubernetes deployment, setting replicas parameter to 2.

This means Kubernetes ensures to have always 2 pods (the furry blue little animals Phippy introduced to you) running our container.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jolie-sample-deployment
  labels:
    app: jolie-sample
spec:
  replicas: 2
  selector:
    matchLabels:
      app: jolie-sample
  template:
    metadata:
      labels:
        app: jolie-sample
    spec:
      containers:
      - name: jolie-k8s-sample
        image: jolie-k8s-sample
        ports:
        - containerPort: 8000
        imagePullPolicy: IfNotPresent

To start deployment roll-out just type:


$ kubectl apply -f jolie-k8s-deployment.yml


And after a few seconds you can see your pods up and running:


$ kubectl get pods
NAME READY STATUS RESTARTS AGE
jolie-sample-deployment-655f8b759d-bmzk7 1/1 Running 0 4s
jolie-sample-deployment-655f8b759d-mq8cn 1/1 Running 0 4s


Exciting!

STEP 3 - Expose deployment by a service

Now we have 2 running instances of our (micro)service but we lack a communication channel to reach the container's port 8000 from outside of Kubernetes virtual network.
Kubernetically speaking this is a service.
Just follow the minikube tutorial and type:

$ kubectl expose deployment jolie-sample-deployment --type=LoadBalancer --port=8000
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jolie-sample-deployment LoadBalancer 10.109.47.147 <pending> 8000:30095/TCP 13s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP

So there's a service exposing pods' port 8000 on cluster's port 30095.
To make this visible from your host you have to go through a "minikube service":

$ minikube service jolie-sample-deployment
|-----------|-------------------------|-------------|-----------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|-------------------------|-------------|-----------------------------| | default | jolie-sample-deployment | | http://192.168.99.100:30095 | |-----------|-------------------------|-------------|-----------------------------|
* Opening service default/jolie-sample-deployment in default browser...

Close the automatically opened browser and let's go on.

Step 4 - Invoke micro services from client

As final step we want to call the Jolie service running inside Kubernetes cluster.
Open client.ol with a text editor and modify line 5, setting IP and port of exposed minikube service:

Location: "socket://192.168.99.100:30095"

Save and try:

$ jolie client.ol jolie-sample-deployment-655f8b759d-mq8cn -> 10 $ jolie client.ol jolie-sample-deployment-655f8b759d-bmzk7 -> 10 $ jolie client.ol jolie-sample-deployment-655f8b759d-mq8cn -> 10 $ jolie client.ol jolie-sample-deployment-655f8b759d-bmzk7 -> 10

As you can see we are getting the right response (client.ol has an hardcoded 5 value as input) and so we demonstrated Kuberntes can at least multiply an integer by another integer!
But server.ol running on containers was modified from the example's original to write out the hostname too:

getenv@Runtime( "HOSTNAME" )( hostname_env ) result = hostname_env + " -> " + number * 2

And that allow us to verify that:
  1. our Jolie server is running on multiple pods
  2. the infrastructure is hidden to clients
  3. calls are automatically managed and balanced by Kubernetes engine (output shows each call gets its response from different pod)
  4. BONUS if you need more power to multiply number 5 you can scale up your deployment:
    $ kubectl scale deployment jolie-sample-deployment --replicas=<N>

Commenti

Post popolari in questo blog

Jolie on Azure Functions

Gateway Consorzio Triveneto per WP e-commerce

FaaS - Fuffa as a Service [Prima parte]