Chapter 16. Integrating External Services
16.1. Overview
Many OpenShift Container Platform applications use external resources, such as external databases, or an external SaaS endpoint. These external resources can be modeled as native OpenShift Container Platform services, so that applications can work with them as they would any other internal service.
16.2. External MySQL Database
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 Container Platform 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:
16.2.1. Step 1: Define a Service
You can define a service either by providing an IP address and endpoints, or by providing a Fully qualified domain name (FQDN).
16.2.1.1. Using an IP address and Endpoints
Create an OpenShift Container Platform 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 Container Platform services use the
Selector
field to associate pods with services using labels. TheEndpointsController
system component synchronizes the endpoints for services that specify selectors with the pods that match the selector. The service proxy and OpenShift Container Platform 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 theEndpointsController
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 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"
- 2
- The name of the
Service
instance, as defined in the previous step. - 3
- Traffic to the service will be load-balanced between the supplied
Endpoints
if more than one is supplied. - 4
- 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).
- The
port
andname
definition must match theport
andname
value in the service defined in the previous step.
16.2.1.2. Using FQDN
Use an ExternalName
service without defining any ports or endpoints.
kind: "Service"
apiVersion: "v1"
metadata:
name: "external-mysql-service"
spec:
type: ExternalName
externalName: example.domain.name
selector: {} 1
- 1
- The
selector
field to leave blank.
16.2.2. Step 2: Consume a Service
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 2 intervalSeconds: 1 3 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}" 4 - name: "MYSQL_PASSWORD" value: "${MYSQL_PASSWORD}" 5 - name: "MYSQL_DATABASE" value: "${MYSQL_DATABASE}" 6
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_PASSWORD=<mysql_password>
-
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.
16.3. External SaaS Provider
A common type of external service is an external SaaS endpoint. To support an external SaaS provider, an application needs:
- An endpoint to communicate with
A set of credentials, such as:
- An API key
- A user name
- A passphrase
The following steps outline a scenario for integrating with an external SaaS provider:
16.3.1. Using an IP address and Endpoints
Create an OpenShift Container Platform service to represent the external service. This is similar to creating an internal service; however the difference is in the service’s
Selector
field.Internal OpenShift Container Platform services use the
Selector
field to associate pods with services using labels. A system component calledEndpointsController
synchronizes the endpoints for services that specify selectors with the pods that match the selector. The service proxy and OpenShift Container Platform router load-balance requests to the service amongst the service’s endpoints.Services that represents an external resource do not require that pods be associated with it. Instead, leave the
Selector
field unset. This makes theEndpointsController
ignore the service and allows you to specify endpoints manually:kind: "Service" apiVersion: "v1" metadata: name: "example-external-service" spec: ports: - name: "mysql" protocol: "TCP" port: 3306 targetPort: 3306 nodePort: 0 selector: {} 1
- 1 1
- The
selector
field to leave blank.Next, create endpoints for the service containing the information about where to send traffic directed to the service proxy and the router:
kind: "Endpoints" apiVersion: "v1" metadata: name: "example-external-service" 1 subsets: 2 - addresses: - ip: "10.10.1.1" ports: - name: "mysql" port: 3306
- 2
- The name of the
Service
instance. - 3
- Traffic to the service is load-balanced between the
subsets
supplied here.Now that the service and endpoints are defined, give pods 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: timeoutSeconds: 120 replicas: 1 selector: name: "frontend" template: metadata: labels: name: "frontend" spec: containers: - name: "helloworld" image: "openshift/openshift/origin-ruby-sample" ports: - containerPort: 3306 protocol: "TCP" env: - name: "SAAS_API_KEY" 2 value: "<SaaS service API key>" - name: "SAAS_USERNAME" 3 value: "<SaaS service user>" - name: "SAAS_PASSPHRASE" 4 value: "<SaaS service passphrase>"
- 4
- Other fields on the
DeploymentConfig
are omitted. SAAS_API_KEY
: The API key to use with the service.SAAS_USERNAME
: The user name to use with the service.SAAS_PASSPHRASE
: The passphrase to use with the service.
16.3.2. Using FQDN
Use an ExternalName
service without defining any ports or endpoints.
kind: "Service"
apiVersion: "v1"
metadata:
name: "external-mysql-service"
spec:
type: ExternalName
externalName: example.domain.name
selector: {} 1
- 1
- The
selector
field to leave blank.
External SaaS Provider Environment Variables
Similarly, when using an internal service, your application is assigned environment variables for the service and the additional environment variables with the credentials described in the above steps. In the above example, the container receives the following environment variables:
-
EXAMPLE_EXTERNAL_SERVICE_SERVICE_HOST=<ip_address>
-
EXAMPLE_EXTERNAL_SERVICE_SERVICE_PORT=<port_number>
-
SAAS_API_KEY=<saas_api_key>
-
SAAS_USERNAME=<saas_username>
-
SAAS_PASSPHRASE=<saas_passphrase>
The application reads the coordinates and credentials for the service from the environment and establishes a connection with the service.