Connecting PetClinic application to an Operator-backed PostgreSQL database
In this configuration, we leverage the Service Binding Operator to collect the binding data from the PostgreSQL database and to project them into the Spring PetClinic application.
The PostgreSQL database in this scenario is deployed using the |
This scenario involves the following procedures:
Creating a PostgreSQL database instance
This scenario uses a PostgreSQL database service, which you must install using the Operator Lifecycle Manager (OLM).
-
You have installed the Crunchy Postgres Operator from Crunchy Data available at OperatorHub.io and the Operator is available in the
my-petclinic
namespace.
The installation of the Crunchy PostgreSQL Operator does not create a database instance. To create a database service instance, you must create the following custom resource (CR), which will be processed by the Operator:
PostgresCluster
resource to run the actual database instance
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.4-0
postgresVersion: 14
instances:
- name: instance1
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.38-0
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
Procedure
-
To create a database instance, create a
PostgresCluster
CR by running the following command:kubectl apply -f https://redhat-developer.github.io/service-binding-operator/userguide/getting-started/_attachments/pgcluster-deployment.yaml -n my-petclinic
-
After the database is created, verify that all the pods in the
my-petclinic
namespace are running (it will take a few minutes):kubectl get pods -n my-petclinic
Example output:NAME READY STATUS RESTARTS AGE hippo-backup-bthn-p6xmn 0/1 Completed 0 16s hippo-instance1-jqpz-0 4/4 Running 0 99s hippo-repo-host-0 2/2 Running 0 99s
The previous output verifies that the database service is created and configured.
Now, after the database is configured for the application, you can deploy the application and connect it to the database service.
Deploying the Spring PetClinic application
To deploy the Spring PetClinic application on our Kubernetes cluster, use a deployment configuration consisting of the following resources:
Deployment
resource to run the actual application instance
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-petclinic
labels:
app: spring-petclinic
spec:
replicas: 1
selector:
matchLabels:
app: spring-petclinic
template:
metadata:
labels:
app: spring-petclinic
spec:
containers:
- name: app
image: quay.io/service-binding/spring-petclinic:latest
imagePullPolicy: Always
env:
- name: SPRING_PROFILES_ACTIVE
value: postgres
ports:
- name: http
containerPort: 8080
Service
resource to provide a way to access the application UI
apiVersion: v1
kind: Service
metadata:
labels:
app: spring-petclinic
name: spring-petclinic
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: spring-petclinic
Procedure
-
Create the application resources by running the following command:
kubectl apply -f https://redhat-developer.github.io/service-binding-operator/userguide/getting-started/_attachments/petclinic-deployment.yaml -n my-petclinic
-
At this stage, the application is not yet connected to the database service. Hence the pod fails to start. To verify run the following command:
kubectl get pods -n my-petclinic
Example output:NAME READY STATUS RESTARTS AGE spring-petclinic-5d47b7dbcd-7zd8v 0/1 CrashLoopBackOff 1 (7s ago) 28s
You can now use the Service Binding Operator to connect the application to the database service.
Connecting the application to the database service with Service Binding Operator
In the absence of the Service Binding Operator, as an administrator of the application, you must perform the following steps manually to extract all the configuration details, create a
|
To leverage the Service Binding Operator as a way to easily and safely 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:
ServiceBinding
resource to project the binding data
apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
name:
spring-petclinic-pgcluster
spec:
services:
- group: postgres-operator.crunchydata.com
version: v1beta1
kind: PostgresCluster
name: hippo
application:
name: spring-petclinic
group: apps
version: v1
resource: deployments
The .spec
field of the ServiceBinding
CR has two sections:
-
The first section is a list of service resources (
.spec.services
). The services resources point to the database service resources. For more information on how the values are exposed from the service resources, see the Exposing binding data section. -
The second section is the application (
.spec.application
). The application points to aDeployment
or any resource that is compliant with PodSpec.
Procedure
-
Create the
ServiceBinding
CR by running the following command in shell:kubectl apply -f https://redhat-developer.github.io/service-binding-operator/userguide/getting-started/_attachments/petclinic-pgcluster-binding.yaml -n my-petclinic
-
Verify that the request for service binding is successful by running the following command:
kubectl get servicebindings -n my-petclinic
Example output:NAME READY REASON AGE spring-petclinic-pgcluster True ApplicationsBound 28s
By creating this
ServiceBinding
resource, we now have the binding data values from the database that is to be projected into the application container as files, by default. Alternatively, you can also choose to project the binding data values as environment variables if you prefer. If you check under the/bindings/spring-petclinic-pgcluster
directory, you can see all the values from theSecret
resource projected there.In the case of the previous example, you can find
username
andpassword
as the projected values. The values pointed out through the annotation are also projected, such as thedatabase
,host
, andport
values. For connectivity, thetype
value is projected as the binding data.The application looks for the
SERVICE_BINDING_ROOT
environment variable to find the location of the/bindings
directory. The Spring Boot application used here uses the Spring Cloud Bindings library and it looks for theSERVICE_BINDING_ROOT
environment variable to get the projected binding data. For more information on how an application uses these values, see the Projecting binding data section. -
Verify that the binding is successful by setting up the port forwarding from the application port to access the sample application from your local environment:
kubectl port-forward --address 0.0.0.0 svc/spring-petclinic 8080:80 -n my-petclinic
Example output:Forwarding from 0.0.0.0:8080 -> 8080
-
Access http://localhost:8080.
You can now remotely access web UI of the application and see that the application is now connected to the database service.
For more information on creating requests for service binding, see the Creating service binding section.
Conclusion
In this scenario, we set up an Operator-backed PostgreSQL database and connected it to the Spring PetClinic application using the Service Binding Operator to collect the binding data and expose them to the application.
Next Steps
By using service bindings, developers are able to more easily leverage the services available to them on a Kubernetes cluster. This method provides consistency across different services and is repeatable for the developers. Service binding provides a unified way to create a binding connection between the application and service and eliminates the need for the usual manual and error-prone configuration.
For more information, see the following sections: