Service Broker Introduction

by Ade Attwood
A service broker is a way of provisioning services and binding them to applications. With a service broker you can provision a database and bind it to a deployment.
Feb 10, 2021

What is a service broker?

A service broker is a way of provisioning services and binding them to applications. For example, if we have a WordPress application that depends on a MySQL database. With a service broker you can provision a database and bind it to that WordPress deployment.

The open service broker API is a platform agnostic API that that allows you to provision services consistently. Once you have a service broker, you can provision services from the API directly or use a platform that will integrate with the broker like Cloud Foundry or Svcat in Kubernetes. In the following example, we will be deploying service in to Kubernetes via Svcat.

What problem does it solve?

Dependency management for services

With our applications we have a composer.json to define the PHP dependencies, and then we can run composer install to get the dependencies. We also have docker-compose to define the local development dependencies, but nothing for production services. Specifically when deploying to Kubernetes you can keep the resource manifests with your deployment config in version control just the same has your language package manager config file

Secret rotation with bindings

In the MySQL example, each deployment has its own binding and own credentials to the database. When an application is removed the credentials for the service are also removed. Then, when a service is created again, a new binding and credentials are created inherently giving us secret rotation. As a result redeploying a new version your application will get a new service binding and credentials. This is particular useful when deploying with a blue-green strategy.

Installing

To install a service broker it will be different per the service broker that you are using. This one is deployed with helm, and more detailed instructions can be found in the project readme. Below is a quick example but it is recommended to read the documentation to install the project dependencies.

1
2
3
helm repo add ibm https://charts.s3.eu-gb.cloud-object-storage.appdomain.cloud
kubectl create ns service-broker
helm install service-broker ibm/service-broker --namespace service-broker

Now the service broker is installed you can list the available services you can provision with kubectl by listing the clusterserviceclasses.servicecatalog.k8s.io resource.

1
kubectl get clusterserviceclasses.servicecatalog.k8s.io

You can also list all the services with svcat a CLI tool provided by the svcat project. This CLI tool can be used to manage all parts of the service brokers including giving you and alternative way to install service brokers. All the info can be found on the project page.

1
svcat get classes

Create a service

To create a service to be deployed with a Kubernetes config file. The below config will create a mysql-instance with the default plan. This will tell the service broker that you want a new service instance and it is therefore the broker’s responsibility to provision the desired service.

1
2
3
4
5
6
7
8
apiVersion: servicecatalog.k8s.io/v1beta1
kind
: ServiceInstance
metadata
:
  name
: mysql-instance-service-instance
  namespace
: test-ns
spec
:
  clusterServiceClassExternalName
: mysql-instance
  clusterServicePlanExternalName
: default

Create a binding

Once a service has been provisioned you will need to bind it to your application. This will generate the credentials needed to connect to the service, and create you a Kubernetes secret with the credentials in.

1
2
3
4
5
6
7
8
apiVersion: servicecatalog.k8s.io/v1beta1
  kind
: ServiceBinding
metadata
:
  name
: mysql-instance-service-binding
  namespace
: test-ns
spec
:
  instanceRef
:
    name
: mysql-instance-service-instance

Configure an application

To configure the application you can now use the secret that was created by the binding. The below config is a basic example of a WordPress deployment that will use the provisioned MySQL instance. The database credentials will be injected from the secret into the container via environment variables. This can be configured per application, note that this can also be injected into your application as file mounts. You can find more about secrets and secret bindings on the Kubernetes docs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
apiVersion: apps/v1
  kind
: Deployment
  metadata
:
    name
: wordpress
    namespace
: test-ns
    labels
:
      app
: wordpress
  spec
:
    selector
:
      matchLabels
:
        app
: wordpress
    template
:
      metadata
:
        labels
:
          app
: wordpress
      spec
:
        containers
:
        - image
: wordpress:apache
          name
: wordpress
          env
:
          - name
: WORDPRESS_DB_HOST
            valueFrom
:
              secretKeyRef
:
                name
: mysql-instance-service-binding
                key
: host
          - name
: WORDPRESS_DB_USER
            valueFrom
:
              secretKeyRef
:
                name
: mysql-instance-service-binding
                key
: user
          - name
: WORDPRESS_DB_NAME
            valueFrom
:
              secretKeyRef
:
                name
: mysql-instance-service-binding
                key
: database
          - name
: WORDPRESS_DB_PASSWORD
            valueFrom
:
              secretKeyRef
:
                name
: mysql-instance-service-binding
                key
: password
          ports
:
          - containerPort
: 80
            name
: wordpress

Next steps

Now that we can deploy service with our applications we can get into the mind set of deploying to Kubernetes as applications not at a collection of resources. Most of the configuration is the same when deploying a container into Kubernetes. This will mean we can generate all the config for the deployment and all the accompanying resource from a could foundry style manifest.yaml we could even generate docker compose files from a config as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
name: Test Application
baseDomain
: "example.com"

applications
:
  - name
: app
    image
: jonfairbanks/docker-node-app:latest
    port
: 8080
   services
:
     - name
: database
       env
:
         WORDPRESS_DB_HOST
: host
         WORDPRESS_DB_USER
: user
         WORDPRESS_DB_NAME
: database
         WORDPRESS_DB_PASSWORD
: password

services
:
 - name
: database
   type
: mysql-instance
   plan
: default

Conclusion

The service brokers have a lot to give when deploying applications to Kubernetes. I love the idea of deploying an application, and defining the service dependencies while having the credentials injected into the container. This gives developers the power to deploy an application with little effort and get test or play time applications onto a server directly. These versions would usually stay on the development machine never to be seen again.

Although this was provisioning services into Kubernetes, a service broker can provision the service anywhere, on any service, and then return the connection credentials. For example Azure has a service broker to provision cloud services form their own service broker, so you don’t need to use the web console so create the service in which your application needs to run. There is a list of compatible service brokers on the open service broker website.