Getting started with service binding on IBM Power Systems, IBM Z, and LinuxONE

The Service Binding Operator manages the data plane for workloads and backing services. This guide provides instructions with examples to help you create a database instance, deploy an application, and use the Service Binding Operator to create a binding connection between the application and the database service.

Prerequisites

  • You have access to an OKD cluster using an account with cluster-admin permissions.

  • You have installed the oc CLI.

  • You have installed PostgreSQL psql CLI.

  • You have installed the Service Binding Operator from OperatorHub.

Deploying a PostgreSQL Operator

  • To deploy the Dev4Devs PostgreSQL Operator in the my-postgresql namespace run the following command in shell:
  1. $ oc apply -f - << EOD
  2. ---
  3. apiVersion: v1
  4. kind: Namespace
  5. metadata:
  6. name: my-postgresql
  7. ---
  8. apiVersion: operators.coreos.com/v1
  9. kind: OperatorGroup
  10. metadata:
  11. name: postgres-operator-group
  12. namespace: my-postgresql
  13. ---
  14. apiVersion: operators.coreos.com/v1alpha1
  15. kind: CatalogSource
  16. metadata:
  17. name: ibm-multiarch-catalog
  18. namespace: openshift-marketplace
  19. spec:
  20. sourceType: grpc
  21. image: quay.io/ibm/operator-registry-<architecture> (1)
  22. imagePullPolicy: IfNotPresent
  23. displayName: ibm-multiarch-catalog
  24. updateStrategy:
  25. registryPoll:
  26. interval: 30m
  27. ---
  28. apiVersion: operators.coreos.com/v1alpha1
  29. kind: Subscription
  30. metadata:
  31. name: postgresql-operator-dev4devs-com
  32. namespace: openshift-operators
  33. spec:
  34. channel: alpha
  35. installPlanApproval: Automatic
  36. name: postgresql-operator-dev4devs-com
  37. source: ibm-multiarch-catalog
  38. sourceNamespace: openshift-marketplace
  39. ---
  40. apiVersion: rbac.authorization.k8s.io/v1
  41. kind: ClusterRole
  42. metadata:
  43. name: database-view
  44. labels:
  45. servicebinding.io/controller: "true"
  46. rules:
  47. - apiGroups:
  48. - postgresql.dev4devs.com
  49. resources:
  50. - databases
  51. verbs:
  52. - get
  53. - list
  54. EOD
1The Operator image.
  • For IBM Power Systems: quay.io/ibm/operator-registry-ppc64le:release-4.9

  • For IBM Z and LinuxONE: quay.io/ibm/operator-registry-s390x:release-4.8

After the operator is installed, list the operator subscriptions in openshift-operators namespace:

  1. $ oc get subs -n openshift-operators

Example output

  1. NAME PACKAGE SOURCE CHANNEL
  2. postgresql-operator-dev4devs-com postgresql-operator-dev4devs-com ibm-multiarch-catalog alpha
  3. rh-service-binding-operator rh-service-binding-operator redhat-operators stable

Creating a PostgreSQL database instance

To create a PostgreSQL database instance, you must create a Database custom resource (CR) and configure the database.

Procedure

  1. Create the Database CR and the my-postgresql namespace by running the following command in shell:

    1. $ oc apply -f - << EOD
    2. apiVersion: postgresql.dev4devs.com/v1alpha1
    3. kind: Database
    4. metadata:
    5. name: sampledatabase
    6. namespace: my-postgresql
    7. annotations:
    8. host: sampledatabase
    9. type: postgresql
    10. port: "5432"
    11. service.binding/database: 'path={.spec.databaseName}'
    12. service.binding/port: 'path={.metadata.annotations.port}'
    13. service.binding/password: 'path={.spec.databasePassword}'
    14. service.binding/username: 'path={.spec.databaseUser}'
    15. service.binding/type: 'path={.metadata.annotations.type}'
    16. service.binding/host: 'path={.metadata.annotations.host}'
    17. spec:
    18. databaseCpu: 30m
    19. databaseCpuLimit: 60m
    20. databaseMemoryLimit: 512Mi
    21. databaseMemoryRequest: 128Mi
    22. databaseName: "sampledb"
    23. databaseNameKeyEnvVar: POSTGRESQL_DATABASE
    24. databasePassword: "samplepwd"
    25. databasePasswordKeyEnvVar: POSTGRESQL_PASSWORD
    26. databaseStorageRequest: 1Gi
    27. databaseUser: "sampleuser"
    28. databaseUserKeyEnvVar: POSTGRESQL_USER
    29. image: registry.redhat.io/rhel8/postgresql-96:latest
    30. databaseStorageClassName: nfs-storage-provisioner
    31. size: 1
    32. EOD

    The annotations added in this Database CR enable the service binding connection and trigger the Operator reconciliation.

    The output verifies that the database instance is created:

    Example output

    1. database.postgresql.dev4devs.com/sampledatabase created
  2. After you have created the database instance, ensure that all the pods in the my-postgresql namespace are running (it will take a few minutes):

    1. $ oc get pods -n my-postgresql

    The output verifies that the database is created:

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. sampledatabase-cbc655488-74kss 0/1 Running 0 32s

    The new database is empty at this stage. You can set its schema and project a sample data set to interact with the sample application.

  3. Initialize the database with the schema and sample data. To do so, use the following custom shell script by copying the code into the shell and running it:

    1. $ cat << EOD | bash
    2. #!/bin/bash
    3. export pgo_cluster_name=sampledb
    4. export cluster_namespace=my-postgresql
    5. export pgo_cluster_username=sampleuser
    6. nohup oc -n "\${cluster_namespace}" port-forward svc/sampledatabase 5432:5432 &
    7. sleep 5
    8. curl -LO https://raw.githubusercontent.com/spring-petclinic/spring-petclinic-rest/master/src/main/resources/db/postgresql/initDB.sql
    9. psql -h localhost -U "\${pgo_cluster_username}" "\${pgo_cluster_name}" -f initDB.sql
    10. curl -LO https://raw.githubusercontent.com/spring-petclinic/spring-petclinic-rest/master/src/main/resources/db/postgresql/populateDB.sql
    11. psql -h localhost -U "\${pgo_cluster_username}" "\${pgo_cluster_name}" -f populateDB.sql
    12. EOD

The output in the terminal shows you that the database is being configured for the application.

After the database is configured, you can deploy the sample application and connect it to the database service.

Deploying the Spring PetClinic sample application

To deploy the Spring PetClinic sample application on an OKD cluster, you must use a deployment configuration and configure your local environment to be able to test the application.

Procedure

  1. Deploy the spring-petclinic-rest application with the PostgresCluster custom resource (CR) by running the following command in shell:

    1. $ oc apply -f - << EOD
    2. ---
    3. apiVersion: apps/v1
    4. kind: Deployment
    5. metadata:
    6. name: spring-petclinic-rest
    7. namespace: my-postgresql
    8. labels:
    9. app: spring-petclinic-rest
    10. spec:
    11. replicas: 1
    12. selector:
    13. matchLabels:
    14. app: spring-petclinic-rest
    15. template:
    16. metadata:
    17. labels:
    18. app: spring-petclinic-rest
    19. spec:
    20. containers:
    21. - name: application
    22. image: quay.io/service-binding/spring-petclinic-rest:latest
    23. env:
    24. - name: SPRING_PROFILES_ACTIVE
    25. value: postgresql,spring-data-jpa
    26. - name: org.springframework.cloud.bindings.boot.enable
    27. value: "true"
    28. ports:
    29. - name: http
    30. containerPort: 9966
    31. ---
    32. apiVersion: v1
    33. kind: Service
    34. metadata:
    35. name: spring-petclinic-rest
    36. namespace: my-postgresql
    37. spec:
    38. ports:
    39. - port: 80
    40. targetPort: 9966
    41. selector:
    42. app: spring-petclinic-rest
    43. ---
    44. EOD

    The output verifies that the Spring PetClinic sample application is created and deployed:

    Example output

    1. deployment.apps/spring-petclinic-rest created
    2. service/spring-petclinic-rest created
    1. $ oc get pods -n my-postgresql

    The output verifies that the database is created:

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. sampledatabase-cbc655488-6n25f 0/1 Running 0 1m
    3. spring-petclinic-rest-7659d5b774-zkjpg 2/2 Running 0 2m
  2. Set up port forwarding from the application port to access the sample application from your local environment:

    1. $ oc port-forward --address 0.0.0.0 svc/spring-petclinic-rest 9966:80 -n my-postgresql
  3. Access http://localhost:9966/petclinic.

    You can now remotely access the Spring PetClinic sample application at localhost:9966.

    The application is not yet connected to the database service. If you try to interact with the application, it will return errors.

    For example, if you try to access the list of all pets using curl, you can see an error message similar to the following sample message:

    1. $ curl -X GET "http://localhost:9966/petclinic/api/pets" -H "accept: application/json"

    Example output

    1. {"className":"org.springframework.transaction.CannotCreateTransactionException","exMessage":"Could
    2. not open JPA EntityManager for transaction; nested exception is
    3. org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC
    4. Connection"}

You can now use the Service Binding Operator to connect the application to the database service.

Connecting the Spring PetClinic sample application to the PostgreSQL database service

To connect the sample application to the database service, you must create a ServiceBinding custom resource (CR) that triggers the Service Binding Operator to project the binding data into the application.

Procedure

  1. Create a ServiceBinding CR to project the binding data:

    1. $ oc apply -f - << EOD
    2. ---
    3. apiVersion: binding.operators.coreos.com/v1alpha1
    4. kind: ServiceBinding
    5. metadata:
    6. name: spring-petclinic-rest
    7. namespace: my-postgresql
    8. spec:
    9. services: (1)
    10. - group: postgresql.dev4devs.com
    11. version: v1beta1
    12. kind: Database (2)
    13. name: sampledatabase
    14. version: v1alpha1
    15. application: (3)
    16. name: spring-petclinic-rest
    17. group: apps
    18. version: v1
    19. resource: deployments
    20. EOD
    1Specifies a list of service resources.
    2The CR of the database.
    3The sample application that points to a Deployment or any other similar resource with an embedded PodSpec.

    The output verifies that the ServiceBinding CR is created to project the binding data into the sample application.

    Example output

    1. servicebinding.binding.operators.coreos.com/spring-petclinic-rest created
  2. To verify that the binding is successful, check the status conditions of the binding resource:

    1. $ oc get servicebindings spring-petclinic-rest -n my-postgresql -o jsonpath-as-json='{.status.conditions}'

    Example output

    1. [
    2. [
    3. {
    4. "lastTransitionTime": "2021-09-06T13:42:28Z",
    5. "message": "",
    6. "reason": "DataCollected",
    7. "status": "True",
    8. "type": "CollectionReady",
    9. },
    10. {
    11. "lastTransitionTime": "2021-09-06T13:42:28Z",
    12. "message": "",
    13. "reason": "ApplicationUpdated",
    14. "status": "True",
    15. "type": "InjectionReady",
    16. },
    17. {
    18. "lastTransitionTime": "2021-09-06T13:42:28Z",
    19. "message": "",
    20. "reason": "ApplicationsBound",
    21. "status": "True",
    22. "type": "Ready",
    23. },
    24. ],
    25. ]

    By default, the values from the binding data of the database service are projected as files into the workload container that runs the sample application.

  3. Once this is created, you can go to the topology to see the visual connection.

    img power

    Figure 1. Connecting spring-petclinic-rest to sampledatabase

  4. Set up the port forwarding from the application port to access the sample application from your local environment:

    1. $ oc port-forward --address 0.0.0.0 svc/spring-petclinic-rest 9966:80 -n my-postgresql
  5. Access http://localhost:9966/petclinic.

    You can now remotely access the Spring PetClinic sample application at localhost:9966.

  6. To verify that the application is now connected to the database service, access the list of all pets:

    1. $ curl -X GET "http://localhost:9966/petclinic/api/pets" -H "accept: application/json"

    Example output

    1. [{"id":1,"name":"Leo","birthDate":"2000/09/07","type":{"id":1,"name":"cat"},
    2. "owner":{"id":1,"firstName":"George","lastName":"Franklin","address":"110...

    The previous output shows the initially configured sample data and verifies that the application is now connected to the database service.

Additional Resources