Docker Service Broker for Cloud Foundry

August 22, 2014 Ferran Rodenas

Editors Note (Update): Today (8/25/2014) VMware announced joint initiatives with Docker, Google and Pivotal to help enterprises run and manage container-based applications on a common platform at scale in private, public and hybrid clouds. In cooperation with Docker, Google, and Pivotal, VMware will enable enterprises to run and manage their containerized applications on their VMware infrastructure or on VMware vCloud Air hybrid service while minimizing complexity by reducing the need to build out new and separate infrastructure silos for their container initiatives. By offering a common platform, developers gain the speed and agility they need while providing IT teams with the control they require. Read full press release here.

There is no doubt that Docker is having an explosive growth since debuting last year.

The Pivotal CF team is a fan of Docker.

We firmly believe PaaS and containers are a good match, and Docker makes it super simple to build and share a consistent container image. With just a quick look at the Docker Hub Registry, we will find already 14,000 Docker images ready to use.

Previously, I have talked about integration points between Cloud Foundry and Docker. Recently, we introduced a Cloud Foundry BOSH release to manage stateful Docker containers. We are also replacing our Warden Linux backend to support libcontainer. If you attended the last CF-Summit, I’m pretty sure you heard about our plans with Diego and Docker.

But, our curiosity about how we can provide better integration points never ends!

Today, we take a step forward. In this article I will explain how using Docker you can easily add, just in minutes, a full catalog of development and testing services to your Cloud Foundry deployment like this:

Docker Services Marketplace

Cloud Foundry Service Brokers

Applications typically depend on services (for example, databases, messaging, third-party SaaS providers) to run, store data, push mobile notifications, etc. In addition to providing an easy, fast way for developers to deploy applications, Cloud Foundry also provisions new service instances and binds credentials on demand without the need to wait for service administrators to provide them.

When a Cloud Foundry developer provisions and binds a service to an application, the component responsible for providing the service instance is the “Service Broker.” This broker advertises a catalog of service offerings and service plans to Cloud Foundry, and receives calls from Cloud Foundry for four lifecycle functions: create, delete, bind, and unbind. The broker passes these calls to the service itself. Service providers determine how a service is implemented, and Cloud Foundry only requires that the service provider implements the “Service broker API”.

The task for a Cloud Foundry operator to add a new service offering usually involves two steps:

  • Deploy the services nodes. This could be a pre-existing and shared service node or a specific node to be used only by Cloud Foundry (deployable or not via CF-BOSH).
  • Create a specific service broker for that type of service. The service broker must adhere to the “Service broker API”, must implement the necessary actions to provision/unprovision a service instance, and, optionally, can implement a mechanism to grant/revoke credentials for a specific, bound application.

This task is not trivial. It is somewhat complex, especially when creating services for development and testing purposes. In these cases, there is no need to guarantee that the data can be recovered if it is destroyed or corrupted.

One of the main topics that arise in our conversations with prospects and customers is about improvement. We have talked a lot about making it easier to offer a full catalog of development services. Lately, due to Docker hype, we also talk about why teams have not been able to use Docker to run their development and testing services.

Docker Service Broker

Today, I am proud to announce an experimental project. We are providing the “Containers Service Broker for Cloud Foundry,” a generic containers service broker for the Cloud Foundry v2 services API.

This service broker allows Cloud Foundry operators to do a few things. They can expose and provision services offerings that run inside a compatible container backend (currently only Docker is supported) and bind applications to the service. The management tasks that the broker can perform are:

  • Provision a service container with random credentials
  • Bind a service container to an application:
    • Expose the credentials to access the provisioned service
    • Provide a syslog drain service for your application events and logs
  • Unbind a service container from an application
  • Unprovision a service container
  • Expose a service container management dashboard

The service broker can be started as a standalone Docker container (from a pre-built public Docker image; or creating your custom image from a Dockerfile) or be deployed alongside the Docker CF-BOSH release (who will also monitor the state of the service broker).

The configuration of the service broker is also pretty simple. You will need to expose your service catalog offering (name, description, metadata, plan, …), set the backend to run your containers (Docker), configure the properties of the service containers to start, and define the credentials to expose. There is more documentation on how to configure the service broker at the github repository README, but let’s see a service offering properties sample:

services:
  - id: '23eefc93-6814-4db8-bbf0-eaa6c3c5fecc'
    name: 'mongodb26'
    description: 'MongoDB 2.6 service for application development and testing'
    bindable: true
    tags:
      - 'mongodb26'
      - 'mongodb'
      - 'document'
    metadata:
      displayName: 'MongoDB 2.6'
      longDescription: 'A MongoDB 2.6 service for development and testing running inside a Docker container'
      providerDisplayName: 'Pivotal Software'
      documentationUrl: 'http://docs.run.pivotal.io'
      supportUrl: 'http://support.run.pivotal.io/home'
    dashboard_client:
      id: 'p-mongodb26-client'
      secret: 'p-mongodb26-secret'
      redirect_uri: "http://cf-containers-broker.run.pivotal.io/manage/auth/cloudfoundry/callback"
    plans:
      - id: '6d8024b1-7deb-4dc7-a72a-33ec3f7a1bfc'
        name: 'free'
        container:
          backend: 'docker'
          image: 'frodenas/mongodb'
          tag: '2.6'
          command: '--smallfiles --httpinterface'
          persistent_volumes:
            - '/data'
        credentials:
          username:
            key: 'MONGODB_USERNAME'
          password:
            key: 'MONGODB_PASSWORD'
          dbname:
            key: 'MONGODB_DBNAME'
          uri:
            prefix: 'mongodb'
            port: '27017/tcp'
        description: 'Free Trial'
          metadata:
            costs:
              - amount:
                  usd: 0.0
                unit: 'MONTHLY'
            bullets:
              - 'Dedicated 2.6 MongoDB server'
              - 'MongoDB 2.6 running inside a Docker container'

Now, let’s see this in action. I will start the service broker on a Linux VM as a Docker container from the public image hosted at the Docker Hub Registry. Once started, I will register the service broker at our Cloud Foundry deployment and make all services in the broker’s catalog publicly visible. The Cloud Foundry marketplace will show us all available services. So, we can start provisioning several services. You will see how running the Cloud Foundry services provision command from our laptop will create a docker container on the service broker host running our “Dockerized” service.

Learn more in “Docker Service Broker for Cloud Foundry – Part 1” at youtube.com/watch?v=cxBKN_nV59g.

Where are My Credentials?

Having the ability to provide a single-tenant service on-demand allows developers to interact with the service as if they were administrators. This is very powerful. It allows admins to create/destroy databases, configure the engine system, and more, without interfering with other users.

On the other hand, most applications expect that a database and a user with enough privileges to access the database have been created previously to start the application. Cloud Foundry Services API allows services to provide “bindable” service instances. This means that binding a service to an application will add credentials for the service instance through the VCAP_SERVICES environment variable.

But how we can make a service container bindable and set up credentials when binding an application? Let’s see an example. At the properties showed previously, there is a section inside the plan named “credentials.” This is where you define the set of credentials (user, password and dbname) for the container:

credentials:
  username:
    key: 'MONGODB_USERNAME'
  password:
    key: 'MONGODB_PASSWORD'
  dbname:
    key: 'MONGODB_DBNAME'
  uri:
    prefix: 'mongodb'
    port: '27017/tcp'

Each container backend is responsible for injecting those credentials options into the container. For example, the Docker backend will inject the credentials using environment variables, the “username” will be injected using the environment variable “MONGODB_USERNAME,” and the value of the username will be created randomly by the service broker.

To make this really work, the container must support creating a username and a database on container’s start up based on the injected environment variables. Take a quick look on how the MongoDB Docker image uses the injected environment variables to create a username and a database. There is also more documentation about how to set the credentials at the CREDENTIALS document at the service broker github repository.

Let’s see the above example in action. I will provision a Docker MongoDB service and bind it to a demo application. I will show how the credentials are injected into the Docker service container on boot time and later how the application receives the credentials via the environment variable VCAP_SERVICES, which can also be seen with the “cf env APPNAME” command.

Visit youtu.be/AaWguQi_18g for the “Docker Service Broker for Cloud Foundry – Part 2” video.

Use Cases and Multi-Database Engines Tests

A nice use case for the Docker service broker is when you want to test your application on several database engines. Enabling multiple database services with the service broker is now really easy. You just need to find the appropriate Docker image. As well, developers can switch from one service to another by simply binding the first service to the application, performing the tests, unbinding the first service, binding the second service, and testing again. This provides developers with an outstanding and fast way to test their applications on multiple database services.

Let’s see how this is possible using the “Containers Service Broker for Cloud Foundry”.

The Spring-Music application has been built to store the same domain objects in one of a variety of different persistence technologies – relational, document, and key-value stores. The application uses Spring Java configuration and bean profiles to configure the connection objects needed to use the persistence stores. It also uses the Spring Cloud library to inspect the environment when running on Cloud Foundry and configure the appropriate Spring profile. First, I will bind a MySQL service to the application. Once the application is restarted, the application is reconfigured automatically to use the MySQL instance as the persistence layer. Later, I will switch from a MySQL to PostgreSQL instance, and I will show again how the application, after restart, is reconfigured to use the new persistence backend.

Learn more with Part 3 of the video series at youtu.be/192ogfmJPPc.

Draining logs, ‘cause Operational Problems Happen

Cloud Foundry keeps a limited amount of application logging information in memory. When you want to persist more log information than this, you must drain logs to a third-party log management service. You can then use the third-party service to analyze the logs. For example, you could produce metrics for application response times or error rates.

The “Containers Service Broker for Cloud Foundry” allows services to declare a syslog drain port. When the service container is provisioned and bound to an application, the service broker will expose the syslog drain URL to Cloud Foundry. It will start automatically and emit application events and logs to the bound service.

Again, let’s see a demo example. I will provision a “Dockerized” Logstash service that enables syslog draining. Once I bind the provisioned service to an application, I will check the service logs via the service broker management dashboard to see how the bound application events and logs are started to be drained to the Logstash service.

Whatch the demo in Part 4 of the video series at youtu.be/9hTo6Vk_cWk.

Known Limitations

The “Containers Service Broker for Cloud Foundry” is not presently a production ready service broker. It is suitable for experimentation and may not become supported in the future.

There are also some caveats:

  • The service broker, when using Docker as a backend, can only be configured to connect a single daemon. That means that you can only have a single node for a service broker. If you want to provide more than one node, you will need to create as many service broker nodes as you want to support.
  • The service broker does not provide any kind of monitoring and self-healing for containers. In the case a container started by the service broker fails or it is stopped, the service broker will not restart it.
  • The service broker allows to set up persistent data for your services by defining a host volume mount point for the container. The broker will automatically create a host directory using the service instance ID and the volume name as the directory name. Then, it will bind it to the container volume mount point. If the container dies or it is stopped, as there is no self-healing mechanism, a manual action will be required to start the container again and mount the correct host directory, allowing the persistent data to be available again for the service.
  • When defining and mounting a container’s volumes using a host directory, there is no disk quota. So, heavy applications can quickly fill the host storage disk and affect all containers running in the same host.

Summary & Links to Get Started

In this post, we explained how the “Containers Service Broker for Cloud Foundry” is pretty easy to use. We can create a full catalog of “Dockerized” services for development and testing purposes. Then, we can expose them to your Cloud Foundry users. This happens without the need to deploy a multi-tenant service node or the overhead of a separate service broker for each service instance type.

We also explained how easy it is to run the service broker as a single Docker container or deployed using the Docker CF-BOSH release.

Lastly, all Docker service examples showed in this post are available at the Docker Hub Registry: ArangoDB, CouchDB, Elasticsearch, Logstash, Memcached, MongoDB, MySQL, Neo4j, PostgreSQL, RabbitMQ and Redis. An example of a configuration for each service offering is available at the Docker CF-BOSH release examples directory.

So, what are you waiting for to expose to your developers a full set of Docker services ready to consume?

Engaging the Community on Additional Work

As the project is open source, we hope the community will contribute to the project with whatever ideas to make this Cloud Foundry Service Broker even better. Please feel free also to share your Docker services with the whole, vibrant Cloud Foundry community. This way, everyone can use them within their environments (hmm, we will need a “Docker services for Cloud Foundry” web page :) ).

Some ideas to improve the service broker experience: enable developers with the ability to start/restart/stop containers from the service broker management dashboard; add monitoring and self-healing capabilities for containers; adding quotas for persistent data, etc.

Also, the service broker allows you to add a new container backend, how about supporting Warden? or better, having multiple nodes for a single service broker (Diego?). Other ideas?

Learn More:

About the Author

Biography

Previous
Reconfiguring Rails Conventions – Highlighting Missing Strong Parameters
Reconfiguring Rails Conventions – Highlighting Missing Strong Parameters

Let's say we were creating an API that allows us to create 'foo's. Foos, as far as we know, will have a fir...

Next
Using Docker For CI Pipelines
Using Docker For CI Pipelines

A previous post explained CI pipelines for loggregator, and this post zooms in on why the Cloud Foundry eng...