Accessing Openshift services remotely

In this article we will learn how to connect to services running in Openshift Paas from external clients

Out of the box Openshift uses the router component to let external clients access the services running in the Paas. The router is however limited to HTTP/HTTPS(SNI)/TLS(SNI), which covers web applications. In this article we will see how to access some services from remote clients using the simple mechanism provided by the oc port-forward command.

Let’s first create a new project (or use the default project you are in):

$ oc new-project myproject

Now we will add an application out of the available templates:

$ oc get templates -n openshift
NAME                                DESCRIPTION                                                                        PARAMETERS        OBJECTS
cakephp-mysql-example               An example CakePHP application with a MySQL database. For more information ab...   19 (4 blank)      7
dancer-mysql-example                An example Dancer application with a MySQL database. For more information abo...   18 (5 blank)      7
django-psql-example                 An example Django application with a PostgreSQL database. For more informatio...   17 (5 blank)      7
jenkins-ephemeral                   Jenkins service, without persistent storage....                                    6 (all set)       6
jenkins-persistent                  Jenkins service, with persistent storage....                                       7 (all set)       7
jenkins-pipeline-example            This example showcases the new Jenkins Pipeline integration in OpenShift, whi...   16 (4 blank)      8
logging-deployer-account-template   Template for creating the deployer account and roles needed for the aggregate...   0 (all set)       9
logging-deployer-template           Template for running the aggregated logging deployer in a pod. Requires empow...   35 (18 blank)     1
mariadb-ephemeral                   MariaDB database service, without persistent storage. For more information ab...   6 (2 generated)   2
mongodb-ephemeral                   MongoDB database service, without persistent storage. For more information ab...   8 (3 generated)   2
mysql-ephemeral                     MySQL database service, without persistent storage. For more information abou...   7 (2 generated)   2
nodejs-mongodb-example              An example Node.js application with a MongoDB database. For more information...    16 (4 blank)      7
postgresql-ephemeral                PostgreSQL database service, without persistent storage. For more information...   7 (2 generated)   2
rails-postgresql-example            An example Rails application with a PostgreSQL database. For more information...   20 (4 blank)      7

For our example, we will create a mysql database, and let the template assign some defaults:

$ oc new-app mysql-ephemeral --name=mysqldemo
--> Deploying template "openshift/mysql-ephemeral" to project myproject

     MySQL (Ephemeral)
     ---------
     MySQL database service, without persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mysql-container/blob/master/5.6/README.md.

WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing

     The following service(s) have been created in your project: mysql.

       Username: user3XH
       Password: CBDXVWcW3VFCV5aI
  Database Name: sampledb
 Connection URL: mysql://mysql:3306/

For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mysql-container/blob/master/5.6/README.md.

     * With parameters:
        * Memory Limit=512Mi
        * Namespace=openshift
        * Database Service Name=mysql
        * MySQL Connection Username=user3XH # generated
        * MySQL Connection Password=CBDXVWcW3VFCV5aI # generated
        * MySQL Database Name=sampledb
        * Version of MySQL Image=5.6

--> Creating resources ...
    service "mysql" created
    deploymentconfig "mysql" created
--> Success
    Run 'oc status' to view your app.

Ok, take note of user, password and database name and let’s move on. The mysql service should be available:

$ oc get services
NAME      CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
mysql     172.30.232.104   <none>        3306/TCP   1m

Ok, let’s expose this service through a route:

$ oc expose service mysql
route "mysql" exposed

$ oc get routes
NAME      HOST/PORT                             PATH      SERVICES   PORT      TERMINATION
mysql     mysql-myproject.192.168.1.66.xip.io             mysql      mysql     

Ok, we have created a route, however even with a route connection to the container is still limited to http. Thus, it is necessary to port-forward the route to localhost using the oc tool. Let’s see the pod name:

$ oc get pods
NAME            READY     STATUS    RESTARTS   AGE
mysql-1-2fzj2   1/1       Running   0          2m

Now let’s forward this pod through the port 3306 as follows:

$ oc port-forward mysql-1-2fzj2 3306:3306
Forwarding from 127.0.0.1:3306 -> 3306
Forwarding from [::1]:3306 -> 3306
Handling connection for 3306

Great. The shell will hang on. Now let’s try to connect from the host to the remote database, passing as argument the user and password generated by the template:

$ mysql -uuser3XH -pCBDXVWcW3VFCV5aI --protocol tcp -h localhost 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 47
Server version: 5.6.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> use sampledb;
Database changed
MySQL [sampledb]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sampledb           |
+--------------------+
2 rows in set (0.00 sec)

As you can see we managed to connect to the remote database.

Let’s see another example so that we can connect to Wildfly application server CLI or Web console. Let’s create the application at first:

oc new-app jboss/wildfly --name=wildfly
--> Found Docker image d59073d (11 days old) from Docker Hub for "jboss/wildfly"

    * An image stream will be created as "wildfly:latest" that will track this image
    * This image will be deployed in deployment config "wildfly"
    * Port 8080/tcp will be load balanced by service "wildfly"
      * Other containers can access this service through the hostname "wildfly"

--> Creating resources ...
    imagestream "wildfly" created
    deploymentconfig "wildfly" created
    service "wildfly" created
--> Success
    Run 'oc status' to view your app.

Let’s check that the service is available:

$ oc get services
NAME      CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
wildfly   172.30.55.12     <none>        8080/TCP   12s

Let’s expose the route for this service:

$ oc expose service wildfly
route "wildfly" exposed

Ok, now before port-forwarding, we will create a management user, by executing the add-user command remotely on the pod:

$ oc get pods
NAME              READY     STATUS    RESTARTS   AGE
wildfly-1-5sgcj   1/1       Running   0          1m

$ oc exec -it wildfly-1-5sgcj -- /bin/bash -c "/opt/jboss/wildfly/bin/add-user.sh -m -u admin -p admin123"
Added user 'admin' to file '/opt/jboss/wildfly/standalone/configuration/mgmt-users.properties'
Added user 'admin' to file '/opt/jboss/wildfly/domain/configuration/mgmt-users.properties'

Ok, last step will be port-forwarding the port 9990 which is used both by the CLI and the Web console:

$ oc port-forward wildfly-1-5sgcj 9990:9990

That’s it! you can check from the local jboss-cli that you are able to connect with the credentials provided:

$ ./jboss-cli.sh -c
Authenticating against security realm: ManagementRealm
Username: admin
Password: 
[standalone@localhost:9990 /] 

Much the same way, you can connect to the Web console as you can see from the following picture:

openshift connect remote host