Important
|
This document is deprecated, you want to look at A tale of four backing service bindings instead. |
How does Cody connect his function or app to a backing service? First off, what do we mean by backing service?
A backing service is any service the app consumes over the network as part of its normal operation. Examples include datastores (such as MySQL or CouchDB), messaging/queueing systems (such as RabbitMQ or Beanstalkd), SMTP services for outbound email (such as Postfix), and caching systems (such as Memcached).
https://12factor.net/backing-services
Cody can provision a backing service in a variety of ways and we might have to adjust how we bind to them based on the way they actually are provisioned.
To allow for several ways of provisioning the service we can introduce a Binding
object to hold the information that is needed for a succesfull binding and we can populate this object in different ways depending on the way the service was provisioned.
The Binding
object might contain fields like:
- name - uri - jdbcUrl - databaseName - username - secretReference - passwordKey
The Binding resource might look something like this:
apiVersion: service.projectriff.io/v1alpha1
kind: Binding
metadata:
name: mypets
namespace: demo
spec:
connection:
uri: mysql://mypets-mysql.demo.svc.cluster.local:3306/petclinic
username: riff
secretReference:
name: mypets-mysql
passwordKey: mysql-password
Most of the work is going to be in the area of mapping and providing the connection properties needed by the app based on data provided by the service bindings and secrets and any additional info provided by the user.
Cody can create a new database using the following Helm command:
helm install --name mypets --namespace demo \
--set mysqlUser=riff --set mysqlDatabase=petclinic stable/mysql
We can see the following in the NOTES section when the chart is executed :
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mypets-mysql.demo.svc.cluster.local
This gives us most of the info we need to bind to the new database. The uri
can be constructed by using mysql://<service-host>:<service-port>/<database>
The only missing piece is the generated password. When the chart is executed it also creates a secret named mypets-mysql
with mysql-password
and mysql-root-password
keys, so this should give us all that we need.
Now Cody can create the service binding:
riff binding create mypets --namespace demo --secret-ref mypets-mysql \
--uri mysql://mypets-mysql.demo.svc.cluster.local:3306/petclinic \
--username riff \
--password-key mysql-password
Note
|
We are using a slightly modified MySQL chart for this example. Starting with tke kibosh-sample mysql chart we are then adding database name and username to the binding/secret that is generated. |
Cody can provision the database using the svcat
CLI:
svcat provision mypets --namespace demo --class mysql --plan small \
--params-json '{"mysqlUser": "riff", "mysqlDatabase": "petclinic"}'
He can then check on the status:
$ svcat get instances --namespace demo
NAME NAMESPACE CLASS PLAN STATUS
+--------+-----------+-------+-------+--------+
mypets demo mysql small Ready
Next Cody creates the Service Catalog binding:
svcat bind mypets --name mypets --namespace demo
This command creates a servicebinding.servicecatalog.k8s.io
object as well as a regular Secret named mypets
in the demo
namespace.
Depending on the broker and offer that was used to provision the service there might be enough information available in the ServiceBinding to connect to the service, but if there is not we can use the Secret and create a binding.service.projectriff.io
object that has all the information.
riff binding create mypets --namespace demo --secret-ref mypets \
--uri-key uri \
--jdbc-url-key jdbcUrl \
--username-key username \
--password-key password
Crossplane provides a way to provision a database in addition to all other features that it provides. We’ll provision a MySQL database using GCP Cloud SQL in this example.
Note
|
We’ll use the experimental "xpl" CLI generated by Mark Fisher |
Alana has already configured Crossplane so Cody can now simply provision a database:
xpl resource create mypets -t mysql -c standard -n demo
This command should create a MySQLInstance
resource like this:
apiVersion: storage.crossplane.io/v1alpha1
kind: MySQLInstance
metadata:
name: mypets
namespace: demo
spec:
classReference:
name: standard-mysql
namespace: crossplane-system
engineVersion: "5.7"
This also creates a secret that has the following content:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: mypets-database
namespace: demo
data:
endpoint: MTAuMTEuMTIuMTM=
password: ZYbnFQVnZ180UnlSQXI4MlBuTk44OWlmQWdB
username: cm9vdA==
Using the information in the secret Cody can create the following binding:
riff binding create mypets --namespace demo --secret-ref mypets-database \
--host-key endpoint \
--port 3306 \
--username-key username \
--password-key password
We’ll add some coverage of ISM once that project gets to an alpha release.
When Cody deploys a function or an app he can simply reference the binding that he created earlier. Let’s see what Binding
resources we have available:
$ kubectl get bindings.service.projectriff.io
NAME URI SECRET
mypets mysql://mypets-mysql.demo.svc.cluster.local:3306/petclinic mypets-mysql
Note
|
The |
Since Codey is deploying a Spring Boot based function he selects spring-boot
as the binding type.
riff handler create pets --namespace demo \
--function-ref pets \
--binding-ref mypets \
--binding-type spring-boot
Cody should now have the pets
function deployed and connected to the provisioned database.