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).
The summary of the overall flow is as follows:
- Running a PostgreSQL instance on the Docker container
- 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 - (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.)
- cf-release (v194)
https://github.com/cloudfoundry/cf-release/tree/v194
( https://github.com/cloudfoundry/cf-release/tree/345a8b3e1ea0005a3e9fced13f0bf6fa6f7ad981 ) - bosh-lite
https://github.com/cloudfoundry/bosh-lite/tree/01db9da7b4122f7d02858d92e0fe938e91256649 - CF CLI (v6.11.3-cebadc9-2015-05-20T19:00:58+00:00)
https://github.com/cloudfoundry/cli/releases/tag/v6.11.3 - postgresql-cf-service-broker
https://github.com/cloudfoundry-community/postgresql-cf-service-broker/tree/2e550a065374ffab1a999657c3dabdaa312aa61b - Docker Image
REPOSITORY=postgres, TAG=9.4.2, ID=1636d90f0662