Connecting PetClinic application to 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 Kubernetes Deployment of the postgres container image.
|
This scenario involves the following procedures:
Creating a PostgreSQL database instance
For the application to use a PostgreSQL database service, you must create a PostgreSQL database instance.
To create a PostgreSQL database instance, you must create the following Kubernetes resources:
Deployment
resource to run the actual database instance
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-petclinic-postgresql
labels:
app: spring-petclinic-postgresql
annotations:
service.binding/type: "postgresql"
service.binding/host: "path={.metadata.name}.{.metadata.namespace}"
service.binding/port: "path={.spec.template.spec.containers[0].ports[0].containerPort}"
service.binding: "path={.spec.template.spec.volumes[0].secret.secretName},objectType=Secret"
spec:
replicas: 1
selector:
matchLabels:
app: spring-petclinic-postgresql
template:
metadata:
labels:
app: spring-petclinic-postgresql
spec:
containers:
- name: postgresql
image: postgres:13
imagePullPolicy: IfNotPresent
env:
- name: POSTGRES_DB_FILE
value: /secrets/database
- name: POSTGRES_PASSWORD_FILE
value: /secrets/password
- name: POSTGRES_USER_FILE
value: /secrets/username
- name: PGDATA
value: /tmp/data
volumeMounts:
- name: spring-petclinic-postgresql
mountPath: "/secrets"
readOnly: true
ports:
- name: postgresql
containerPort: 5432
volumes:
- name: spring-petclinic-postgresql
secret:
secretName: spring-petclinic-postgresql
Secret
resource to store the database credentials
apiVersion: v1
kind: Secret
metadata:
name: spring-petclinic-postgresql
stringData:
database: spring-petclinic-postgresql-db
username: spring-petclinic-postgresql-user
password: spring-petclinic-postgresql-passwd
Service
resource to provide a way to access to the database
apiVersion: v1
kind: Service
metadata:
labels:
app: spring-petclinic-postgresql
name: spring-petclinic-postgresql
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
app: spring-petclinic-postgresql
Procedure
-
Create the database resources by running the following command:
kubectl apply -f https://pmacik.github.io/service-binding-operator/userguide/getting-started/_attachments/postgresql-deployment.yaml -n my-petclinic
-
After you have created the database instance, verify that the respective pod in the
my-petclinic
namespace is up and running (it will take less than a minute):kubectl get pods -n my-petclinic
Example output:NAME READY STATUS RESTARTS AGE spring-petclinic-postgresql-6db5594876-4556g 1/1 Running 0 16m
The previous output verifies that the setup of the database for the application is complete. You can deploy the sample application and connect it to the database service.
The
You can view them by running the following command:
These annotations are necessary to be set on the |
Based on the type of the resource, there are many ways to expose binding data from the backing service.
|
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://pmacik.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-postgresql
spec:
services:
- group: apps
version: v1
kind: Deployment
name: spring-petclinic-postgresql
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://pmacik.github.io/service-binding-operator/userguide/getting-started/_attachments/petclinic-postgresql-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-postgresql 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-postgresql
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 Using Projected Bindings 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 a 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: