Make use of my local Camunda 8 cluster

A short recap from the previous article (Camunda 8 on k0s – the zero friction Kubernetes). I have a running Camunda 8 cluster on my local machine, and I’m able to access its components via Web UI. I even managed to create a new user in Keycloack and login to Camunda 8 Operate as this new user. Now I’ll try to make use of it, i.e. to deploy and run my first BPMN process.

Connect Camunda Desktop Modeler to Camunda 8 Self-Hosted cluster

Very straightforward exercise. Go to the download page https://camunda.com/download/modeler/, grab a binary for the respective desktop platform and create the first, very simple process, which I’ll describe later. Don’t forget to select the right execution platform – Camunda Platform 8.1.

Time to deploy!


Well, this didn’t go as expected… Let’s verify the settings one by one.

Target – Camunda Platform 8 Self-Manager, this was easy – Check!

Cluster endpoint – a less obvious one, but in my understanding, one would interact with the zeebe cluster through the zeebe gateway, and http://zeebe.camunda-example is its URL accordingly to our Ingress configuration (see Helm chart explanation in the previous article here – Camunda 8 on k0s – the zero friction Kubernetes ) – Check!

Authentication – None. After reading the documentation and studying the settings in Operate and Keycloak, I figured that the gateway endpoint doesn’t have any protection in the default setup. Let’s say – Check!

I then checked the respective ingress configuration and confirmed that gRPC is configured as its back-end protocol:

olegme@master-node:~$ kubectl get ing c8-zeebe-gateway -n c8 -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/rewrite-target: /
    meta.helm.sh/release-name: c8
    meta.helm.sh/release-namespace: c8
    nginx.ingress.kubernetes.io/backend-protocol: GRPC
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
  creationTimestamp: "2022-12-28T17:41:45Z"

...

There is also a nice CLI utility zbctl, described here: https://docs.camunda.io/docs/apis-clients/cli-client/. Let’s try using it from our desktop (outside of the cluster). The --insecure option is needed to prevent the TLS handshake; it will fail as we haven’t configured any SSL-based authentication.

olegme@master-node:~/k0s$ zbctl --insecure --address http://zeebe.camunda-example  status
Error: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp: address tcp///zeebe.camunda-example: unknown port"

It doesn’t work as well. Let’s divide and conquer. Two major parts here, the gateway and the Ingress.

Connecting to the zeebe gateway from within the cluster.

Actually, from the gateway POD itself.

exec kubectl exec -i -t -n c8 c8-zeebe-gateway-86885f7fcb-ndmg5 -c zeebe-gateway  -- sh -c "clear; (bash || ash || sh)"

I’ll skip the installation of the node package and zbctl command, this is done in a very usual Debian-ish way. Let’s check the connection:

root@c8-zeebe-gateway-86885f7fcb-ndmg5:/usr/local/zeebe# zbctl --insecure status
Cluster size: 1
Partitions count: 1
Replication factor: 1
Gateway version: 8.1.5
Brokers:
  Broker 0 - c8-zeebe-0.c8-zeebe.c8.svc:26501
    Version: 8.1.5
    Partition 1 : Leader, Healthy

Wow, works like a charm. It even didn’t need the address; it worked with the default one – 127.0.0.1:26500. This led me to conclude that something was wrong with my Ingress configuration. Instead of investigating the Ingress configuration, I went for a simple workaround.

Deploy a service on an external IP

First of all, external IP means external in relation to my cluster. So it can be reached from my desktop.

After taking a closer look at the definition of the c8-zeebe-gateway service, I decided to implement an additional, standalone service which will use LoadBalancer as its type and connect to zeebe gateway as its backend. Like this:

apiVersion: v1
kind: Service
metadata:
  name: example-load-balancer
spec:
  selector:
    app: camunda-platform
    app.kubernetes.io/component: zeebe-gateway
    app.kubernetes.io/instance: c8
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: zeebe-gateway
    app.kubernetes.io/part-of: camunda-platform
  ports:
  - name: http
    port: 9600
    protocol: TCP
    targetPort: 9600
  - name: gateway
    port: 26500
    protocol: TCP
    targetPort: 26500
  type: LoadBalancer

Here we see it deployed and available outside of the cluster on 192.168.2.242:

olegme@master-node:~$ kubectl get svc example-load-balancer  -n c8
NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                          AGE
example-load-balancer   LoadBalancer   10.98.193.71   192.168.2.242   9600:30625/TCP,26500:32169/TCP   162m

Let’s make a connectivity test from the master-node:

olegme@master-node:~/k0s$ zbctl --insecure --address 192.168.2.242  status
Cluster size: 1
Partitions count: 1
Replication factor: 1
Gateway version: 8.1.5
Brokers:
  Broker 0 - c8-zeebe-0.c8-zeebe.c8.svc:26501
    Version: 8.1.5
    Partition 1 : Leader, Healthy

Wow, it works! Why don’t we try then to modify the Helm chart we used to deploy our Camunda 8 cluster to replace the Ingress configuration for the zeebe gateway with a LoadBalancer-based one? Let’s move on.

LoadBalancer with an external IP for zeebe gateway

Based on the file values.yaml provided here https://github.com/camunda/camunda-platform-helm/blob/main/charts/camunda-platform/ I just replaced the ingress definition with a LoadBalancer-based service definition; here is an excerpt from the configuration:

...
zeebe-gateway:
  replicas: 1
  # Service configuration for the gateway service (copied over from https://github.com/camunda/camunda-platform-helm/blob/main/charts/camunda-platform/values.yaml)
  service:
    # Service.type defines the type of the service https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
    type: LoadBalancer
    # Service.loadBalancerIP defines public ip of the load balancer if the type is LoadBalancer
    loadBalancerIP: ""
    # Service.loadBalancerSourceRanges defines list of allowed source ip address ranges if the type is LoadBalancer
    loadBalancerSourceRanges: []
    # Service.httpPort defines the port of the http endpoint, where for example metrics are provided
    httpPort: 9600
    # Service.httpName defines the name of the http endpoint, where for example metrics are provided
    httpName: "http"
    # Service.gatewayPort defines the port of the gateway endpoint, where client commands (grpc) are sent to
    gatewayPort: 26500
    # Service.gatewayName defines the name of the gateway endpoint, where client commands (grpc) are sent to
    gatewayName: "gateway"
    # Service.internalPort defines the port of the internal api endpoint, which is used for internal communication
    internalPort: 26502
    # Service.internalName defines the name of the internal api endpoint, which is used for internal communication
    internalName: "internal"
    # Service.annotations can be used to define annotations, which will be applied to the zeebe-gateway service
    annotations: {}
...

Command line connectivity test works:

olegme@master-node:~$ zbctl --insecure --address 192.168.2.242:26500 status
Cluster size: 1
Partitions count: 1
Replication factor: 1
Gateway version: 8.1.5
Brokers:
  Broker 0 - c8-zeebe-0.c8-zeebe.c8.svc:26501
    Version: 8.1.5
    Partition 1 : Leader, Healthy

And the desktop Modeler can now connect as well:


Here is what the success looks like:

Conclusion

Now we can deploy our BPMN model to Camunda 8 cluster and start a process. Note, though, that the zeebe gateway end-point is completely unprotected. How to do that in a Self-Hosted version calls for a new article, but sometime in the distant future. In my next article, I’ll review how to re-implement an existing BPMN process I implemented on Camunda 7 and see what it means for Camunda 8. Read on – Make Use Of My Local Camunda 8 Cluster – Part II

Comments

comments