Using the subPath Property of OpenShift Volume Mounts

Posted: February 18th, 2019 | Author: | Filed under: Technology | No Comments »

One of the methodologies of cloud native architectures is to externalize applications configurations and store them within the environment. OpenShift provides multiple mechanisms for storing configurations within the platform, which include the use of Secrets and ConfigMaps. These resources can then be exposed to applications as either environment variables or as file system volumes mounted within pods and containers. By default, volume mounts uses the standard operating system mount command to inject the external content into the container. While this implementation works well for the majority of use cases, there are situations where there is a desire to retain the contents of the existing directory and only inject a specific file instead of an entire directory. Fortunately, OpenShift and Kubernetes have a solution for this challenge using the subPath property of the container volumeMount for which this discussion will highlight.

To demonstrate how one can utilize subPath volume mounting, let’s deploy an application that can benefit from this feature. Applications commonly consume configuration files within dedicated directories, such as a conf or conf.d. One such application that leverages this paradigm is the Apache HTTP Server, better known as httpd. A variety of configuration files are spread across these two directories within the /etc/httpd folder. If custom configuration files were injected using a typical volume mount to one of these locations, key assets the application server had been expecting to find may not be available. The conf.d directory is the common location for user defined configurations. For example, one can specify that all requests that are made to specific context paths are automatically redirected to another location as shown below:

<VirtualHost *:*>
  
  Redirect permanent /redhat https://www.redhat.com/
  Redirect permanent /openshift https://www.openshift.com/
 
</VirtualHost>

In the example above, requests to the /redhat  context path are redirected to https://www.redhat.com while requests made against the /openshift context path are redirected to https://www.openshift.com. While one could configure this file to be placed in this directory at image build time, there may be a desire to customize the contents per deployed environment. This is where externalizing the configuration outside the image and injecting the contents at runtime becomes valuable. Given that this file does not contain any sensitive data, it is ideal to be stored in a ConfigMap. First, create a new file on the local file system called subpath-redirect.conf with the contents from the example above.

Now, lets use an OpenShift environment to demonstrate this use case. Login and create a new project called subpath-example:

oc new-project subpath-example

By default, OpenShift provides a ImageStream containing an Apache HTTPD server which can be deployed with a single command. Execute the following to create a new application called subpath-example:

oc new-app --image-stream=httpd --name=subpath-example

A new deployment of the httpd image will be initiated. When the new-app command is used against an ImageStream, no route to expose the application outside the cluster is created. Execute the following command to expose the service to allow for ingress traffic.

oc expose svc httpd

Locate the hostname of the application by executing the following command:

oc get route subpath-example -–template=’{{ .spec.host }}’

Copy the resulting location into a web browser which should display the default Apache welcome page.

Now, lets use the contents of the subpath-redirect.conf file previously create a new ConfigMap that can then be injected into the application.

oc create configmap subpath-example –-from-file=subpath-redirect.conf

Before mounting the ConfigMap, explore the running application by starting a remote shell session into the running container.

First, confirm the container is running by locating the name of the running pod:

oc get pods

Start the remote shell session:

oc rsh <pod_name>

List the files in the /etc/httpd/conf.d directory:

ls –l /etc/httpd/conf.d

-rwxrwxrwx. 1 root       root        366 Nov  7 12:26 README
-rwxrwxrwx. 1 root       root         63 Jan  8  2018 auth_mellon.conf
-rwxrwxrwx. 1 root       root       2966 Nov  7 12:25 autoindex.conf
-rwxrwxrwx. 1 1000150000 root       9410 Feb 14 06:33 ssl.conf
-rwxrwxrwx. 1 root       root       1252 Nov  7 12:21 userdir.conf
-rwxrwxrwx. 1 root       root        556 Nov  7 12:21 welcome.conf

As demonstrated by the above output, there are a number of user defined configurations already present within the httpd image (inside the conf.d directory) and overwriting these files by a standard volume mount could cause the container to fail to operate.

Define a new volume in the pod referencing the ConfigMap containing the contents of the Apache HTTPD configuration file along with a volumeMount to the /etc/httpd/conf.d by editing the httpd DeploymentConfig by executing oc edit dc subpath-example.

...
       terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/httpd/conf.d/subpath-reverse-proxy.conf
          name: subpath-example
          subPath: subpath-reverse-proxy.conf
      volumes:
      - configMap:
          defaultMode: 420
          name: subpath-example
        name: subpath-example
...

Notice how the subPath property of the volumeMount specifies the name of the file in within the ConfigMap (oc describe configmap subpath-example would display this name as well) along with the full mountPath to the file that will be created in the Apache configuration directory.

Save the changes which will trigger a new deployment of the application

Running oc get pods again will confirm that the new version of the application has been deployed.

Once again, obtain a remote shell to the running pod using the steps previously described.

List the files in the /etc/httpd/conf.d and notice the presence of the subpath-redirect.conf file from the ConfigMap:

-rwxrwxrwx. 1 root       root        366 Nov  7 12:26 README
-rwxrwxrwx. 1 root       root         63 Jan  8  2018 auth_mellon.conf
-rwxrwxrwx. 1 root       root       2966 Nov  7 12:25 autoindex.conf
-rwxrwxrwx. 1 1000150000 root       9410 Feb 14 06:33 ssl.conf
-rw-r--r--. 1 root       1000150000  150 Feb 14 06:33 subpath-reverse.conf
-rwxrwxrwx. 1 root       root       1252 Nov  7 12:21 userdir.conf
-rwxrwxrwx. 1 root       root        556 Nov  7 12:21 welcome.conf

Confirm the configuration has been applied to the application by navigating to the /redhat context of the application in your browser. If successful, you should be redirected to https://www.redhat.com. In addition, navigating to the /openshift context will redirect to https://www.openshift.com.

The ability to inject individual files from externally stored resources within the platform using the subPath feature of volumes expands and accelerates the delivery of applications to achieve greater business value.