Deploying Data Index and multiple SonataFlow application on Minikube
This document describes how to deploy a multiple SonataFlow workflow applications and the Data Index service using a local Kubernetes cluster, such as Minikube, using the SonataFlow Operator.
For more information about Minikube and related system requirements, see Getting started with Minikube documentation.
This use case is intended to represent an installation with:
-
A singleton Data Index Service with PostgreSQL persistence
-
The
greeting
workflow (no persistence), that is configured to register events to the Data Index Service. -
The
helloworld
workflow (no persistence), that is configured to register events to the Data Index Service. -
Both workflows are configured to register the process events on the Data Index Service.
You can directly access the UseCase2 example application we are going to follow at SonataFlow Data Index Use Cases with operator.
-
Minikube installed with
registry
addon enabled -
kubectl
command-line tool is installed. Otherwise, Minikube handles it. -
SonataFlow operator installed if workflows are deployed. To install the operator you can see Install the SonataFlow Operator.
We recommend that you start Minikube with the following parameters, note that the
To verify that the registry addon was property added you can execute this command:
| registry | minikube | enabled ✅ | Google | | registry-aliases | minikube | disabled | 3rd party (unknown) | | registry-creds | minikube | disabled | 3rd party (UPMC Enterprises) | |
You can check the Minikube installation by entering the following commands in a command terminal:
minikube version
kubectl
CLI versionkubectl version
If kubectl is available using Minikube
|
-
After cloning the SonataFlow examples repository. Open a terminal and run the following commands
cd serverless-operator-examples/serverless-workflow-dataindex-use-cases/
-
Create the namespace:
kubectl create namespace usecase2
-
Deploy the Data Index Service and postgresql database:
Here you can find the infrastructure kustomization required to deploy Data Index service and a postgresql database explained in this use case.
Thas folder contains four files:
-
kustomization.yaml
-
01-postgres.yaml
-
02-dataindex.yaml
-
application.properties
kustomization.yaml
resources that deploy Data Index deployment with persistence to a postgresql databaseresources: - 01-postgres.yaml (1) - 02-dataindex.yaml (2) secretGenerator: - name: postgres-secrets literals: - POSTGRES_USER=sonataflow - POSTGRES_PASSWORD=sonataflow - POSTGRES_DB=sonataflow - PGDATA=/var/lib/postgresql/data/mydata configMapGenerator: - name: dataindex-properties files: - application.properties
1 Postgres database deployment 2 Data Index deployment 01_postgres.yaml
that deploys Postgresql database--- apiVersion: v1 kind: PersistentVolumeClaim metadata: labels: app.kubernetes.io/name: postgres name: postgres-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: postgres name: postgres spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: postgres template: metadata: labels: app.kubernetes.io/name: postgres spec: containers: - name: postgres image: postgres:13.2-alpine imagePullPolicy: 'IfNotPresent' ports: - containerPort: 5432 volumeMounts: - name: storage mountPath: /var/lib/postgresql/data envFrom: - secretRef: name: postgres-secrets readinessProbe: exec: command: ["pg_isready"] initialDelaySeconds: 15 timeoutSeconds: 2 livenessProbe: exec: command: ["pg_isready"] initialDelaySeconds: 15 timeoutSeconds: 2 resources: limits: memory: "256Mi" cpu: "500m" volumes: - name: storage persistentVolumeClaim: claimName: postgres-pvc --- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/name: postgres name: postgres spec: selector: app.kubernetes.io/name: postgres ports: - port: 5432
02-dataindex.yaml
that deploys Data Index with persistence to the previous defined postgresql databaseapiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: data-index-service-postgresql name: data-index-service-postgresql spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: data-index-service-postgresql template: metadata: labels: app.kubernetes.io/name: data-index-service-postgresql spec: containers: - name: data-index-service-postgresql image: quay.io/kiegroup/kogito-data-index-postgresql:latest imagePullPolicy: Always resources: limits: memory: "256Mi" cpu: "500m" ports: - containerPort: 8080 name: http protocol: TCP env: - name: KOGITO_DATA_INDEX_QUARKUS_PROFILE value: http-events-support - name: KUBERNETES_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: QUARKUS_DATASOURCE_USERNAME valueFrom: secretKeyRef: key: POSTGRES_USER name: postgres-secrets - name: QUARKUS_DATASOURCE_PASSWORD valueFrom: secretKeyRef: key: POSTGRES_PASSWORD name: postgres-secrets volumeMounts: - name: application-config mountPath: "/home/kogito/config" livenessProbe: failureThreshold: 3 httpGet: path: /q/health/live port: 8080 scheme: HTTP initialDelaySeconds: 0 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /q/health/ready port: 8080 scheme: HTTP initialDelaySeconds: 0 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 10 volumes: - name: application-config configMap: name: dataindex-properties initContainers: - name: init-postgres image: registry.access.redhat.com/ubi9/ubi-minimal:latest imagePullPolicy: IfNotPresent command: ['sh', '-c', 'until (echo 1 > /dev/tcp/postgres.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local/5432) >/dev/null 2>&1; do echo "Waiting for postgres server"; sleep 3; done;'] --- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/name: data-index-service-postgresql name: data-index-service-postgresql spec: ports: - name: http port: 80 targetPort: 8080 selector: app.kubernetes.io/name: data-index-service-postgresql type: NodePort
application.properties
referenced bykustomization.yaml
quarkus.http.port=8080 quarkus.http.cors=true quarkus.http.cors.origins=/.*/ quarkus.datasource.jdbc.url=jdbc:postgresql://postgres:5432/sonataflow?currentSchema=data-index-service quarkus.hibernate-orm.database.generation=update quarkus.flyway.migrate-at-start=true # Disable kafka client health check since the quarkus-http connector is being used instead. quarkus.smallrye-health.check."io.quarkus.kafka.client.health.KafkaHealthCheck".enabled=false
Perform the deployments executing
kubectl kustomize infra/dataindex | kubectl apply -f - -n usecase2
configmap/dataindex-properties-hg9ff8bff5 created secret/postgres-secrets-22tkgc2dt7 created service/data-index-service-postgresql created service/postgres created persistentvolumeclaim/postgres-pvc created deployment.apps/data-index-service-postgresql created deployment.apps/postgres created
Give some time for the data index to start, you can check that it’s running by executing.
kubectl get pod -n usecase2
NAME READY STATUS RESTARTS AGE data-index-service-postgresql-5d76dc4468-lb259 1/1 Running 0 2m11s postgres-7f78499688-lc8n6 1/1 Running 0 2m11s
-
-
Deploy the workflow:
Here you can find the use case kustomization required to deploy the workflow
Use case kustomization.yaml resources that deploys the workflowresources: - ../../infra/service_discovery - ../../workflows/sonataflow-greeting - ../../workflows/sonataflow-helloworld
To see in more detail access to Building and Deploying Workflows with the Operator
Perform the deployment executing
kubectl kustomize usecases/usecase2 | kubectl apply -f - -n usecase2
configmap/greeting-props created configmap/helloworld-props created sonataflow.sonataflow.org/greeting created sonataflow.sonataflow.org/helloworld created
Give some time for the sonataflow operator to build and deploy the workflow. To check that the workflow is ready you can use this command.
kubectl get workflow -n usecase2
NAME PROFILE VERSION URL READY REASON greeting 0.0.1 True helloworld 0.0.1 True
-
Expose the workflows and get the urls:
kubectl patch svc greeting helloworld -p '{"spec": {"type": "NodePort"}}' -n usecase2
minikube service greeting --url -n usecase2
minikube service helloworld --url -n usecase2
-
Create a workflow instance:
You must use the URLs calculated in step 5.
curl -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' -d '{"name": "John", "language": "English"}' http://192.168.49.2:32407/greeting
curl -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' -d '{}' http://192.168.49.2:32327/helloworld
-
Clean the use case:
kubectl delete namespace usecase2
Querying Data Index service on Minikube
You can use the public Data Index endpoint to play around with the GraphiQL interface.
This procedure apply to all use cases with that deploys the Data Index Service.
-
Get the Data Index Url:
minikube service data-index-service-postgresql --url -n my_usecase
-
Open the GrahiqlUI
Using the url returned, open a browser window in the following url http://192.168.49.2:32409/graphiql/,
that IP and port will be different in your installation, and don’t forget to add the last slash "/" to the url, otherwise the GraphiqlUI won’t be opened. |
To see the process instances information you can execute this query:
{
ProcessInstances {
id,
processId,
processName,
variables,
state,
endpoint,
serviceUrl,
start,
end
}
}
The results should be something like:
{
"data": {
"ProcessInstances": [
{
"id": "3ed8bf63-85c9-425d-9099-49bfb63608cb",
"processId": "greeting",
"processName": "workflow",
"variables": "{\"workflowdata\":{\"name\":\"John\",\"greeting\":\"Hello from JSON Workflow, \",\"language\":\"English\"}}",
"state": "COMPLETED",
"endpoint": "/greeting",
"serviceUrl": "http://greeting",
"start": "2023-09-13T06:59:24.319Z",
"end": "2023-09-13T06:59:24.400Z"
}
]
}
}
To see the jobs instances information, if any, you can execute this query:
{
Jobs {
id,
processId,
processInstanceId,
status,
expirationTime,
retries,
endpoint,
callbackEndpoint
}
}
The results should be something like:
{
"data": {
"Jobs": [
{
"id": "55c7aadb-3dff-4b97-af8e-cc45014b1c0d",
"processId": "callbackstatetimeouts",
"processInstanceId": "299886b7-2b78-4965-a701-16783c4162d8",
"status": "EXECUTED",
"expirationTime": null,
"retries": 0,
"endpoint": "http://jobs-service-postgresql/jobs",
"callbackEndpoint": "http://callbackstatetimeouts:80/management/jobs/callbackstatetimeouts/instances/299886b7-2b78-4965-a701-16783c4162d8/timers/-1"
}
]
}
}
Found an issue?
If you find an issue or any misleading information, please feel free to report it here. We really appreciate it!