One of the most common types of external services is an external database. To
support an external database, an application needs:
-
An endpoint to communicate with.
-
A set of credentials and coordinates, including:
-
A user name
-
A passphrase
-
A database name
The solution for integrating with an external database includes:
-
A Service object to represent the SaaS provider as an OpenShift Origin service.
-
One or more Endpoints for the service.
-
Environment variables in the appropriate pods containing the credentials.
The following steps outline a scenario for integrating with an external MySQL
database:
-
Create an
OpenShift Origin
service to represent your external database. This is similar to creating an
internal service; the difference is in the service’s Selector field.
Internal OpenShift Origin services use the Selector field to associate pods with
services using
labels. The
EndpointsController system component synchronizes the endpoints for services
that specify selectors with the pods that match the selector. The
service
proxy and OpenShift Origin
router load-balance
requests to the service amongst the service’s endpoints.
Services that represent an external resource do not require associated pods.
Instead, leave the Selector field unset. This represents the external service,
making the EndpointsController ignore the service and allows you to specify
endpoints manually:
kind: "Service"
apiVersion: "v1"
metadata:
name: "external-mysql-service"
spec:
ports:
-
name: "mysql"
protocol: "TCP"
port: 3306
targetPort: 3306
nodePort: 0
selector: {} (1)
| 1 |
The selector field to leave blank. |
-
Next, create the required endpoints for the service. This gives the service
proxy and router the location to send traffic directed to the service:
kind: "Endpoints"
apiVersion: "v1"
metadata:
name: "external-mysql-service" (1)
subsets: (2)
-
addresses:
-
ip: "10.0.0.0" (3)
ports:
-
port: 3306 (4)
name: "mysql"
| 1 |
The name of the Service instance, as defined in the previous step. |
| 2 |
Traffic to the service will be load-balanced between the supplied
Endpoints if more than one is supplied. |
| 3 |
Endpoints IPs
cannot
be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast
(224.0.0.0/24). |
| 4 |
The port and name definition must match the port and name
value in the service defined in the previous step. |
-
Now that the service and endpoints are defined, give the appropriate pods
access to the credentials to use the service by setting environment variables in
the appropriate containers:
kind: "DeploymentConfig"
apiVersion: "v1"
metadata:
name: "my-app-deployment"
spec: (1)
strategy:
type: "Rolling"
rollingParams:
updatePeriodSeconds: 1
intervalSeconds: 1
timeoutSeconds: 120
replicas: 2
selector:
name: "frontend"
template:
metadata:
labels:
name: "frontend"
spec:
containers:
-
name: "helloworld"
image: "origin-ruby-sample"
ports:
-
containerPort: 3306
protocol: "TCP"
env:
-
name: "MYSQL_USER"
value: "${MYSQL_USER}" (2)
-
name: "MYSQL_PASSWORD"
value: "${MYSQL_PASSWORD}" (3)
-
name: "MYSQL_DATABASE"
value: "${MYSQL_DATABASE}" (4)
| 1 |
Other fields on the DeploymentConfig are omitted |
| 2 |
The user name to use with the service. |
| 3 |
The passphrase to use with the service. |
| 4 |
The database name. |
External Database Environment Variables
Using an external service in your application is similar to using an internal
service. Your application will be assigned environment variables for the service
and the additional environment variables with the credentials described in the
previous step. For example, a MySQL container receives the following environment
variables:
-
EXTERNAL_MYSQL_SERVICE_SERVICE_HOST=<ip_address>
-
EXTERNAL_MYSQL_SERVICE_SERVICE_PORT=<port_number>
-
MYSQL_USERNAME=<mysql_username>
-
MYSQL_PASSPHRASE=<mysql_passphrase>
-
MYSQL_DATABASE_NAME=<mysql_database>
The application is responsible for reading the coordinates and credentials for
the service from the environment and establishing a connection with the database
via the service.