1
0
mirror of https://github.com/openshift/openshift-docs.git synced 2026-02-05 12:46:18 +01:00
Files
openshift-docs/modules/sbo-advanced-binding-options.adoc
2024-03-15 12:39:37 +00:00

187 lines
7.7 KiB
Plaintext

// Module included in the following assemblies:
//
// * /applications/connecting_applications_to_services/binding-workloads-using-sbo.adoc
:_mod-docs-content-type: CONCEPT
[id="sbo-advanced-binding-options_{context}"]
= Advanced binding options
You can define the `ServiceBinding` custom resource (CR) to use the following advanced binding options:
* Changing binding names: This option is available only for the `binding.operators.coreos.com` API group.
* Composing custom binding data: This option is available only for the `binding.operators.coreos.com` API group.
* Binding workloads using label selectors: This option is available for both the `binding.operators.coreos.com` and `servicebinding.io` API groups.
[id="changing-binding-names_{context}"]
== Changing the binding names before projecting them into the workload
You can specify the rules to change the binding names in the `.spec.namingStrategy` attribute of the `ServiceBinding` CR. For example, consider a Spring PetClinic sample application that connects to the PostgreSQL database. In this case, the PostgreSQL database service exposes the `host` and `port` fields of the database to use for binding. The Spring PetClinic sample application can access this exposed binding data through the binding names.
.Example: Spring PetClinic sample application in the `ServiceBinding` CR
[source,yaml]
----
# ...
application:
name: spring-petclinic
group: apps
version: v1
resource: deployments
# ...
----
.Example: PostgreSQL database service in the `ServiceBinding` CR
[source,yaml]
----
# ...
services:
- group: postgres-operator.crunchydata.com
version: v1beta1
kind: PostgresCluster
name: hippo
# ...
----
If `namingStrategy` is not defined and the binding names are projected as environment variables, then the `host: hippo-pgbouncer` value in the backing service and the projected environment variable would appear as shown in the following example:
.Example
[source,yaml]
----
DATABASE_HOST: hippo-pgbouncer
----
where:
[horizontal]
`DATABASE`:: Specifies the `kind` backend service.
`HOST`:: Specifies the binding name.
After applying the `POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV` naming strategy, the list of custom binding names prepared by the service binding request appears as shown in the following example:
.Example
[source,yaml]
----
POSTGRESQL_DATABASE_HOST_ENV: hippo-pgbouncer
POSTGRESQL_DATABASE_PORT_ENV: 5432
----
The following items describe the expressions defined in the `POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV` naming strategy:
* `.name`: Refers to the binding name exposed by the backing service. In the previous example, the binding names are `HOST` and `PORT`.
* `.service.kind`: Refers to the kind of service resource whose binding names are changed with the naming strategy.
* `upper`: String function used to post-process the character string while compiling the Go template string.
* `POSTGRESQL`: Prefix of the custom binding name.
* `ENV`: Suffix of the custom binding name.
Similar to the previous example, you can define the string templates in `namingStrategy` to define how each key of the binding names should be prepared by the service binding request.
[id="composing-custom-binding-data_{context}"]
== Composing custom binding data
As an application developer, you can compose custom binding data under the following circumstances:
* The backing service does not expose binding data.
* The values exposed are not available in the required format as expected by the workload.
For example, consider a case where the backing service CR exposes the host, port, and database user as binding data, but the workload requires that the binding data be consumed as a connection string.
You can compose custom binding data using attributes in the Kubernetes resource representing the backing service.
.Example
[source,yaml]
----
apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
name: spring-petclinic-pgcluster
namespace: my-petclinic
spec:
services:
- group: postgres-operator.crunchydata.com
version: v1beta1
kind: PostgresCluster
name: hippo <1>
id: postgresDB <2>
- group: ""
version: v1
kind: Secret
name: hippo-pguser-hippo
id: postgresSecret
application:
name: spring-petclinic
group: apps
version: v1
resource: deployments
mappings:
## From the database service
- name: JDBC_URL
value: 'jdbc:postgresql://{{ .postgresDB.metadata.annotations.proxy }}:{{ .postgresDB.spec.port }}/{{ .postgresDB.metadata.name }}'
## From both the services!
- name: CREDENTIALS
value: '{{ .postgresDB.metadata.name }}{{ translationService.postgresSecret.data.password }}'
## Generate JSON
- name: DB_JSON <3>
value: {{ json .postgresDB.status }} <4>
----
<1> Name of the backing service resource.
<2> Optional identifier.
<3> The JSON name that the {servicebinding-title} generates. The {servicebinding-title} projects this JSON name as the name of a file or environment variable.
<4> The JSON value that the {servicebinding-title} generates. The {servicebinding-title} projects this JSON value as a file or environment variable. The JSON value contains the attributes from your specified field of the backing service custom resource.
[id="binding-workloads-using-a-label-selector_{context}"]
== Binding workloads using a label selector
You can use a label selector to specify the workload to bind. If you declare a service binding using the label selectors to pick up workloads, the {servicebinding-title} periodically attempts to find and bind new workloads that match the given label selector.
For example, as a cluster administrator, you can bind a service to every `Deployment` in a namespace with the `environment: production` label by setting an appropriate `labelSelector` field in the `ServiceBinding` CR. This enables the {servicebinding-title} to bind each of these workloads with one `ServiceBinding` CR.
.Example `ServiceBinding` CR in the `binding.operators.coreos.com/v1alpha1` API
[source,yaml]
----
apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
name: multi-application-binding
namespace: service-binding-demo
spec:
application:
labelSelector: <1>
matchLabels:
environment: production
group: apps
version: v1
resource: deployments
services:
group: ""
version: v1
kind: Secret
name: super-secret-data
----
<1> Specifies the workload that is being bound.
.Example `ServiceBinding` CR in the `servicebinding.io` API
[source,yaml]
----
apiVersion: servicebindings.io/v1beta1
kind: ServiceBinding
metadata:
name: multi-application-binding
namespace: service-binding-demo
spec:
workload:
selector: <1>
matchLabels:
environment: production
apiVersion: app/v1
kind: Deployment
service:
apiVersion: v1
kind: Secret
name: super-secret-data
----
<1> Specifies the workload that is being bound.
[IMPORTANT]
====
If you define the following pairs of fields, {servicebinding-title} refuses the binding operation and generates an error:
* The `name` and `labelSelector` fields in the `binding.operators.coreos.com/v1alpha1` API.
* The `name` and `selector` fields in the `servicebinding.io` API (Spec API).
====
.Understanding the rebinding behavior
Consider a case where, after a successful binding, you use the `name` field to identify a workload. If you delete and recreate that workload, the `ServiceBinding` reconciler does not rebind the workload, and the Operator cannot project the binding data to the workload. However, if you use the `labelSelector` field to identify a workload, the `ServiceBinding` reconciler rebinds the workload, and the Operator projects the binding data.