Cloud Foundry Logo
blog single gear
Community

100-day Challenge #002: Running postgresql-cf-service-broker on Cloud Foundry

The 2nd topic of “Cloud Foundry 100-day Challenge” is postgresql-cf-service-broker, which may come as a little bit of a twisted feeling.

Basic Information

This application is actually is not a typical application. It is an application that functions as a service broker for Clould Foundry.

Having said that, the reason that we are covering this topic now is because we utilized this application to build the PostgreSQL service in the previous Kandan article, so we found it appropriate to cover this topic at this timing.

Additionally, we believed that this article will prove useful to readers who are, or are considering, building Cloud Foundry environments using bosh-lite, etc. on their own.

The following is a graphical representation of the overall summary (© @kenojiri; drawings in blue added by the author).

Overview of postgresql-cf-service-broker on Cloud Foundry bosh-lite

The summary of the overall flow is as follows:

  1. Running a PostgreSQL instance on the Docker container
  2. Deploying postgresql-cf-service-broker as an application on Cloud Foundry
    postgresql-cf-service-broker will connect to and manage the PostgreSQL instance based on environment variables information
    Registering and publicizing postgresql-cf-service-broker as a service broker of the Cloud Foundry environment
  3. (Example from previous post)
    Deploying Kandan as an application on Cloud Foundry
    postgresql-cf-service-broker creates DB/user/password for PostgreSQL in response to requests of create/bind service
    Credentials including the above information is passed on to Kandan
    Kandan accesses DB on the PostgreSQL using the above credentials

Now, we shall proceed to the main subject. As mentioned above, we will first explain the building of a PostgreSQL instance that will be used by the service broker.

Preparing a PostgreSQL Instance

Note: This section can be skipped if you already have a PostgreSQL instance that can be used for Cloud Foundry.

We have chosen to use Docker-based PostgreSQL instance because it is just for testing purposes.

The procedures are as follows:

  • 1) Installing Docker
  • 2) Installing psql (PostgreSQL CLI)
  • 3) Running PostgreSQL Docker image

Installing Docker

As Cloud Foundry runs on Ubuntu, so we will also run PostgreSQL Docker image on Ubuntu. First, Docker needs to be installed on Ubuntu.

$ sudo apt-get install -y docker.io

Checkint the result:

$ docker --version
Docker version 1.0.1, build 990021a

Installing psql (PostgreSQL CLI)

$ sudo apt-get install -y postgresql-client

Checkint the result:

$ psql --version
psql (PostgreSQL) 9.3.7

Running PostgreSQL Docker Image

Obtaining Docker Image

Here, we have decided to use the most recent version 9.4.2 as of the date of this post.

$ sudo docker pull postgres:9.4.2

Starting Docker image

Transfer port 5432 of the host to port 5432 of the container, set the initial user cf and the initial user password xxxxxxxx, and start up the obtained Docker Image.

$ sudo docker run --name cf-postgres -e POSTGRES_PASSWORD=xxxxxxxx -e POSTGRES_USER=cf -e LC_ALL=C.UTF-8 -p 0.0.0.0:5432:5432 -d postgres:9.4.2

Checking Connectivity

$ psql -U cf -W -l -h 192.168.xxx.xxx
Password for user cf:
                              List of databases
   Name    |  Owner   | Encoding | Collate |  Ctype  |   Access privileges
-----------+----------+----------+---------+---------+-----------------------
 cf        | postgres | UTF8     | C.UTF-8 | C.UTF-8 |
 postgres  | postgres | UTF8     | C.UTF-8 | C.UTF-8 |
 template0 | postgres | UTF8     | C.UTF-8 | C.UTF-8 | =c/postgres          +
           |          |          |         |         | postgres=CTc/postgres
 template1 | postgres | UTF8     | C.UTF-8 | C.UTF-8 | =c/postgres          +
           |          |          |         |         | postgres=CTc/postgres
(4 rows)

If all the settings are correct, a list of databases can be obtained with the above command.

If the connection does not come through and the below error message is displayed,

$ psql -U cf -W -l
Password for user cf:
psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

Use the command below to check the listening status of ports.

$ netstat -ltn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::5432                 :::*                    LISTEN
tcp6       0      0 :::10050                :::*                    LISTEN

At this point, if only the IPv6 address’s port 5432 of the host is listened, it may be a problem stemming from this issue. It seems that this issue is unresolved at the moment, but I was able to overcome this problem with the procedures outlined below.

Confirmation of the current status:

$ sysctl net.ipv6.conf.all.forwarding
net.ipv6.conf.all.forwarding = 0

Changing the parameter:

$ sudo sysctl net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.forwarding = 1

Checking the results of the change:

$ sysctl net.ipv6.conf.all.forwarding
net.ipv6.conf.all.forwarding = 1

Now the PostgreSQL instance is ready to use.

Deploying postgresql-cf-service-broker

Next, we will deploy postgresql-cf-service-broker on Cloud Foundry.

The procedures are outlined below:

  • 0) Preparation for deployment
    • 0.1) Installing JDK and Maven
    • 0.2) Retrieving source code and building application
    • 0.3) Creating Org and Space
    • 0.4) Configuring Application Security Group
  • 1) Deployment
    • 1.1) Pushng application without starting
    • 1.2) Configuring environment variables
    • 1.3) Starting application

Let us look at each step in detail.

Preparation for deployment

Installing JDK and Maven

This is a Java application, but Java applications must be compiled before deployment with the standard deployment methods of Cloud Foundry. Therefore, we will first prepare tools that build Java applications.

[OpenJDK 7]

$ sudo apt-get install openjdk-7-jdk -y

Confirmation:

$ which javac
/usr/bin/javac

[Maven 3]

$ sudo apt-get install maven -y

Confirmation:

$ which mvn
/usr/bin/mvn

Retrieving source code and building application

Clone the source code of the application from GitHub.

$ git clone https://github.com/cloudfoundry-community/postgresql-cf-service-broker.git

Then build the application:

$ cd postgresql-cf-service-broker
$ mvn package

Creating Org and Space

Here we will create an Org and a Space where to deploy this application.

Currently, the authority as a Cloud Foundry administrator is necessary in order to use the application as a service broker. As such, it makes sense to deploy the application itself also as the administrator. Especially for this occasion, we will be creating the Org and Space to deploy the service broker application. For those who are deploying this application for existing Org/Group, this procedure will be unnecessary.

$ cf create-org admin
$ cf create-space svcs

Configuring Application Security Group

Cloud Foundry has a function called Application Security Groups. This function restricts IP addresses that can be accessed from an application running on the Cloud Foundry environment; under the default settings for bosh-lite, an application cannot access private addresses (10.*.*.*, 192.168.*.*).

In this article’s occasion, the PostgreSQL (of Docker Image) exists on 192.168.*.*, so the setting for the application security group needs to be changed to allow for access. This procedure will not be necessary for those of you that have built the PostgreSQL instance on a public IP address.

[Existing security groups]

$ cf security-groups
Getting security groups as admin
OK

     Name              Organization   Space
#0   public_networks
#1   dns

Applications can only access the DNS, except public networks.

[Creating security groups]

Here, we will create an application security group that has a rule allowing to access to the PostgreSQL instance that has been built previously.

First, we create a file that contains the rule (in JSON format).

$ emacs postgresql-cf-service-broker.security-groups.json
...
$ cat postgresql-cf-service-broker.security-groups.json
[
    {
    "protocol": "tcp",
    "destination": "192.168.xxx.xxx",
    "ports": "5432" 
    }
]

You should fill the ‘xxx.xxx’ part with the IP address value where the PostgreSQL is running on.

Next, using Cloud Foundry cli, we register the application security group with the aforementioned rule to the Cloud Foundry environment. The name of the security group will be set as postgresql-cf-service-broker-security-groups.

$ cf create-security-group postgresql-cf-service-broker-security-groups postgresql-cf-service-broker.security-groups.json

Confirmation:

$ cf security-groups
Getting security groups as admin
OK

     Name                                           Organization   Space
#0   public_networks
#1   dns
#2   postgresql-cf-service-broker-security-groups

[Binding to the Default Running Security Group]

Here, we will bind the application security group, which has just been registered, to the Default Running Security Group.

The Default Running Security Group is a security group that is applied to all running applications. By this configuration, all applications will be able to access the PostgreSQL created earlier when running.

$ cf bind-running-security-group postgresql-cf-service-broker-security-groups

Confirmation:

$ cf running-security-groups
Acquiring running security groups as 'admin'
OK

public_networks
dns
postgresql-cf-service-broker-security-groups

Now, the preparation to deploy the application is finally complete.

Deployment

Note: This section is generally based on: https://github.com/cloudfoundry-community/postgresql-cf-service-broker/blob/2e550a065374ffab1a999657c3dabdaa312aa61b/README.md

Pushng application without starting

First, we will push the application onto the Cloud Foundry environment without starting.

Usually, pushed applications automatically start on Cloud Foundry, but this application requires the setting of environment variables prior to starting, so the application will not start up at this point. In order to do so, we specify the --no-start option with the cf push command.

Additionally, since a Java application is deployed as a war file (not as a directory), we specify the war file created in the earlier build as the -p option parameter.

Moreover, the memory size of the application is not specified in the README, but as the default size of 256MB seemed to strain the memory in several trials, we have set the memory size at 512MB.

$ cf push postgresql-cf-service-broker -p target/postgresql-cf-service-broker-2.3.0-SNAPSHOT.jar -m 512m --no-start

Configuring environment variables

We configure some environment variables of the application’s execution environment in accordance with the README.

$ cf set-env postgresql-cf-service-broker MASTER_JDBC_URL 'jdbc:postgresql://192.168.xxx.xxx:5432/cf?user=cf&password=xxxxxxxx'
$ cf set-env postgresql-cf-service-broker JAVA_OPTS "-Dsecurity.user.password=xxxxxxxx" 

We needed to take some research on the treatment of the username and password in the JDBC’s URL format. It took us a little time to figure out that the JDBC’s URL format is jdbc:<scheme>://<host>:<port>/<dbname>?user=<username>&password=<password> as opposed to DATABASE_URL (<scheme>://<username>:<password>@<host>:<port>/<database>).

cf. https://devcenter.heroku.com/articles/heroku-postgresql#spring-java

Confirmation of environment variables:

$ cf env postgresql-cf-service-broker
Getting env variables for app postgresql-cf-service-broker in org admin / space svcs as admin...
OK

System-Provided:

{
 "VCAP_APPLICATION": {
  "application_name": "postgresql-cf-service-broker",
  "application_uris": [
   "postgresql-cf-service-broker.10.244.0.34.xip.io" 
  ],
  "application_version": "82587e6c-b7c8-410f-bbba-5766d611c4f6",
  "limits": {
   "disk": 1024,
   "fds": 16384,
   "mem": 512
  },
  "name": "postgresql-cf-service-broker",
  "space_id": "a74d2274-c546-49f4-ad38-499df073d499",
  "space_name": "svcs",
  "uris": [
   "postgresql-cf-service-broker.10.244.0.34.xip.io" 
  ],
  "users": null,
  "version": "82587e6c-b7c8-410f-bbba-5766d611c4f6" 
 }
}

User-Provided:
JAVA_OPTS: -Dsecurity.user.password=xxxxxxxx
MASTER_JDBC_URL: jdbc:postgresql://192.168.xxx.xxx:5432/cf?user=cf&password=xxxxxxxx

No running env variables have been set

No staging env variables have been set

Starting application

$ cf start postgresql-cf-service-broker
...
requested state: started
instances: 1/1
usage: 512M x 1 instances
urls: postgresql-cf-service-broker.10.244.0.34.xip.io
last uploaded: Mon Jun 1 01:56:13 +0000 2015
stack: lucid64

     state     since                    cpu    memory           disk      details
#0   running   2015-06-01 10:57:57 AM   0.0%   348.9M of 512M   0 of 1G

The “state” should display “running”.

Registration as Service Broker

As different with a typical application, the application needs to be recognized as a service broker by the Cloud Foundry environment in order to check its operability.

The summary of procedures for this section is as follows:

  • 1) Registering as Service Broker
  • 2) Publish to Marketplace

Registering as Service Broker

First, we register the application on Cloud Foundry as a service broker.

$ cf create-service-broker postgresql-cf-service-broker user xxxxxxxx http://postgresql-cf-service-broker.10.244.0.34.xip.io

Publish to Marketplace

Note: We have referred to the below document for the procedures in this section: http://docs.cloudfoundry.org/services/access-control.html.

Access to the service broker registered with create-service-broker is restricted by default. Therefore, in order to allow all users in the Cloud Foundry environment to use the services provided by this service broker, we need to allow access to the service plan as well as the service name of this service broker.

$ cf enable-service-access PostgreSQL -p "Basic PostgreSQL Plan"

Confirmation:

$ cf service-access
Getting service access as admin...
broker: postgresql-cf-service-broker
   service      plan                    access   orgs
   PostgreSQL   Basic PostgreSQL Plan   all
$ cf marketplace
Getting services from marketplace in org nota-ja / space 100 as nota-ja...
OK

service      plans                    description
PostgreSQL   Basic PostgreSQL Plan*   PostgreSQL on shared instance.

* These service plans have an associated cost. Creating a service instance will incur this cost.

TIP:  Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service.

Access has been granted as intended. There is a warning that there is an associated cost to the service plan, but this is not particularly a problem in this case, as this is a service built for a test environment.

Checking Behavior

Regarding the behavioral check of this application, from the creation of the service to binding to the application, please refer to this section and after in the previous post.

The Environment Used in this Post

(Exactly the same as the previous post.)