Skip to content

Commit

Permalink
kie-kogito-docs-556: SonataFlow Operator based service discovery conf…
Browse files Browse the repository at this point in the history
…iguration guide (#565)
  • Loading branch information
wmedvede authored Mar 11, 2024
1 parent 7340851 commit 09c6411
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 1 deletion.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion serverlessworkflow/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@
*** xref:cloud/operator/supporting-services.adoc[Deploy Supporting Services]
*** xref:cloud/operator/workflow-status-conditions.adoc[Custom Resource Status]
*** xref:cloud/operator/building-custom-images.adoc[Building Custom Images]
*** xref:cloud/operator/known-issues.adoc[Roadmap and Known Issues]
*** xref:cloud/operator/customize-podspec.adoc[Custom Workflow PodSpec]
*** xref:cloud/operator/service-discovery.adoc[Service Discovery]
*** xref:cloud/operator/known-issues.adoc[Roadmap and Known Issues]
* Integrations
** xref:integrations/core-concepts.adoc[]
* Job Service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
The Kubernetes service discovery allows you to describe the Kubernetes resource you want to perform HTTP requests on using a custom URI. Under the hood, it will discover the network endpoint (URL) to where to make the request.

The service discovery occurs during the operator managed deployment of a workflow, or during the application startup if you are using a standalone Quarkus Workflow Project.
In both cases, this feature scans all the Quarkus configurations in search of the URI pattern. Therefore, you must remember that if the application startup time matters, consider using a known static URL instead.

Following is the custom URI pattern in Kubernetes service discovery:

.URI pattern in Kubernetes service discovery
[source,shell]
----
kubernetes:<kind>.<version>.<group>/<namespace>/<resourceName>?<attributeName>=<attributeValue>
\________/ \____/ \_______/ \_____/ \_________/ \____________/ \______________________________/
scheme kind version group namespace resourceName additional resource attributes
\____________________/ \__________________________/
GVK Supported values:
- port=<PORT_NAME>
- label-name1=label-value1
- label-name2=label-value2
----

The following scheme values are supported in the URI pattern:

* `kubernetes`
* `openshift`
* `knative`
The following resources are supported for the Kubernetes GVK (Group, Version, and Kind):

* `services.v1`
* `services.v1.serving.knative.dev`
* `pods.v1`
* `deployments.v1.apps`
* `deploymentconfigs.v1.apps.openshift.io`
* `statefulsets.v1.apps`
* `routes.v1.route.openshift.io`
* `ingresses.v1.networking.k8s.io`
[NOTE]
====
When using `knative`, you can also use a simplified URI like:
[source]
----
knative:<namespace>/<serviceName>
----
The above URI looks directly for services.v1.serving.knative.dev resource.
====

[IMPORTANT]
====
The `namespace` in the URI is optional, however, if `namespace` contains an empty value, the current namespace or context is used.
====

Query parameters in URI::
+
--
Also known as query string. The query parameters are defined the similar way with URLs to assign value to specific attributes.

The following query parameters help the engine to be more precise when querying for a given Kubernetes resource:

* *Custom labels*: The custom labels are used to filter services in case there are more than one service with the same label selector but exposing different ports. In this case, you can instruct the engine that if more than one service is found, then the engine must use the service containing the provided label.
+
The label is defined with the following expression and in case of multiple labels, you can use ampersand (&):
+
`label-name1=label-value1&label-name2=label-value2`
+
.Example label definition in URI
[source,shell]
----
kubernetes:pods.v1/<namespace>/<pod-name>?tier=backend
----
+
Using the previous URI example, if there are more than one service exposing the given pod, the `tier=backend` label is used to filter the service. If the label does not exist, the first found service is used.
* *Custom port*: The custom `port` is used to determine which port to use when multiple ports are configured in the target service. You can configure the port name to be queried using the following pattern:
+
`port=<PORT_NAME>`
--
8 changes: 8 additions & 0 deletions serverlessworkflow/modules/ROOT/pages/cloud/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ xref:cloud/operator/customize-podspec.adoc[]
Learn how to customize the workflow `PodSpec` template to control the deployment details
--

[.card]
--
[.card-title]
xref:cloud/operator/service-discovery.adoc[]
[.card-description]
Learn how to configure and use the {operator_name} Kubernetes service discovery
--

[.card]
--
[.card-title]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Note that it's important to respect the properties format, otherwise the operato

Here's an example of a Workflow properties stored within a ConfigMap:

[#example-of-workflow-config-map]
.Example of a Workflow ConfigMap Properties
[source,yaml,subs="attributes+"]
----
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
= Kubernetes service discovery in {operator_name}
:compat-mode!:
// Metadata:
:description: Explain what is and how the operator managed service discovery works
:keywords: sonataflow, workflow, quarkus, serverless, service-discovery, operator, enhanced-service-discovery

include::../../../pages/_common-content/service-discovery/kubernetes-service-discovery-introduction.adoc[]

[IMPORTANT]
====
When you work with operator managed workflow deployments, there is no specific configuration required for the Kubernetes service discovery except by using the expected URI pattern.
====

[[kubernetes-service-discovery-resolution]]
== Kubernetes service discovery resolution

Based on the resource to be discovered, the Kubernetes service discovery follows specific paths as shown in the following figure:

image::cloud/operator/service-discovery/OperatorServiceDiscovery.jpg[]

[[example-kubernetes-service-discovery]]
== Example of Kubernetes service discovery in {operator_name}

The Kubernetes service discovery is performed by the operator at workflow deployment time.
At this point, the operator scans the workflow configuration parameters in the associated <<workflow_config_map, ConfigMap>>, and searches for the Kubernetes URI pattern.
If the URI pattern is found, the operator parses the URI, queries the Kubernetes API searching for the given resource, and overrides the given parameter with the resolved value by adding an entry in the corresponding <<workflow_managed_properties_config_map, managed properties ConfigMap>>.

For example, consider a workflow with the name `mortgage-workflow` that consumes a resource running on Kubernetes to execute financial operations implemented by the Knative Service `financial-service`.

[#workflow_config_map]
.mortgage-workflow ConfigMap Properties
[source,yaml,subs="attributes+"]
----
kind: ConfigMap
apiVersion: v1
metadata:
name: mortgage-workflow-props
namespace: example
labels:
app: mortgage-workflow
sonataflow.org/workflow-app: mortgage-workflow
data:
application.properties: >+
# service discovery configuration to resolve the financial-service
quarkus.rest-client.financial_service_yaml.url=${knative:services.v1.serving.knative.dev/financial-service}
----

[NOTE]
====
* The service discovery URI must always be included in between `${}`
====

Finally, as part of the deployment procedure the operator will create the following `mortgage-workflow-managed-props` ConfigMap, that contains all the configurations that are managed by the operator, including the service discovery properties that were calculated for the configuration above.

[#workflow_managed_properties_config_map]
.mortgage-workflow-managed-props ConfigMap Properties
[source,yaml,subs="attributes+"]
----
kind: ConfigMap
apiVersion: v1
metadata:
name: mortgage-workflow-managed-props
namespace: example
labels:
app: mortgage-workflow
sonataflow.org/workflow-app: mortgage-workflow
data:
application-dev.properties: >
org.kie.kogito.addons.discovery.knative\:services.v1.serving.knative.dev\/financial-service
= http://financial-service.example.svc.cluster.local
quarkus.rest-client.financial_service_yaml.url =
http://financial-service.example.svc.cluster.local
quarkus.http.port = 8080
quarkus.http.host = 0.0.0.0
... other operator calculated properties
----

As you can see, the service discovery URI `${knative:services.v1.serving.knative.dev/financial-service}` was resolved to the URL `\http://financial-service.example.svc.cluster.local`.

[NOTE]
====
* In the URI above, the namespace `example` was omitted intentionally on the assumption that the `mortgage-workflow` and the `financial-service` are deployed on the same `example` namespace.
If this is not the case, you must add the `financial-service's` namespace to that URI. For example `${knative:services.v1.serving.knative.dev/**finance-department**/financial-service}`
====


[IMPORTANT]
====
The `mortgage-workflow-managed-props` is generated by the operator, and any external change on that ConfigMap will be overwritten in the next reconciliation cycle.
====

include::../../../pages/_common-content/report-issue.adoc[]

0 comments on commit 09c6411

Please sign in to comment.