Mount ConfigMap as file in existing directory - K8s

We have already explored basics of Kubernetes ConfigMap. In this tutorial I will concentrate on a scenario wherein you have to mount a file into your Pod's container into an existing directory.

 

Our Requirement

  • We have a multi-container pod with a main nginx application and one sidecar container with busybox image.
  • We have an application based configuration file i.e. db-app.conf which must be added under /etc.
  • This file also should be shared across all the containers inside the Pod.
  • Now since /etc directory is already present so we must not overwrite this volume and we just need to place our conf file db-app.conf inside /var/log

 

Pre-requisites

This article assumes that you already have

Advertisement

 

Create ConfigMap

There can be two possible scenarios to create your ConfigMap.

  1. You already have dp-app.conf file with some content and you want to create ConfigMap using existing file.
  2. You want to create this file with some content inside ConfigMap

I will cover ConfigMap examples for all these scenarios, you can choose either based on your requirement:

 

Scenario-1: Create ConfigMap with existing file using kubectl input arguments

In this scenario we will use kubectl input arguments to create a configmap using an existing file. This is the content of my db-app.conf configuration file:

~]# cat db-app.conf
## This is dummy configuration file ##
 conf {
    user: ADMIN
    pwd: PASSWORD
    dir: /home
   }

We will name our configmap as scenario-1-cm, to create the configmap use following command:

 ~]# kubectl create configmap scnario-1-cm --from-file /root/db-app.conf
configmap/scnario-1-cm created

Check the status:

~]# kubectl get cm
NAME            DATA   AGE
scenario-1-cm   1      4s

You can get the details of the data included in the configmap using kubectl get command:

Advertisement

Mount ConfigMap as file in existing directory - K8s

Here you can see that the content of my db-app.conf has been added as data into the ConfigMap.

 

Scenario-2: Create ConfigMap manually using existing file (applicable with helm)

In this scenario we will create ConfigMap using YAML file by directly referring the exiting db-app.conf file. You should use this only if you are using helm charts to deploy your Pod.

With Helm charts we can use templates to fetch the files inside the ConfigMap or Secrets. Following is an example:

~]# cat scenario-2.cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: scenario-2-cm
data:
  db-app.conf: |-
    {{ .Files.Get "db-app.conf" | indent 4 }}

 

Scenario-3: Create file and deploy as ConfigMap manually

In this scenario we will create the file inside ConfigMap YAML file. Here is my YAML file with the data content:

~]# cat scenario-3.cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: scenario-3-cm
data:
  db-app.conf: |-
    ## This is dummy configuration file ##
      conf {
        user: ADMIN
        pwd: PASSWORD
        dir: /home
        }

Let us create this ConfigMap:

~]# kubectl create -f scenario-3.cm.yaml
configmap/scenario-3-cm created

If you check this ConfigMap in detail then you will see that the data output is same as Scenario-1 where we had create CM using file as an input.

Mount ConfigMap as file in existing directory - K8s

Now that our ConfigMap is in place, we can create our multi-container pod to share this configuration file across all the containers inside /etc path.

 

Create Pod and mount configmap as file in existing directory (path)

I will use the scenario-1-cm in this example but you can use any other ConfigMap based on your preference. Here is my YAML file to create multi-container pod:

Advertisement
~]# cat multi-container-pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod-1
spec:
  containers:
  ## Main Container
  - image: nginx
    name: application
    volumeMounts:
    - name: db-conf
      mountPath: /etc/db-app.conf # This should be your final destination
      subPath: db-app.conf  # The name of the file to be placed inside /etc, the filename used here and in mountPath should be same.

  ## Sidecar Container
  - name: sidecar
    image: busybox
    args:
     - /bin/sh
     - -c
     - sleep 36000
    volumeMounts:
    - name: db-conf
      mountPath: /etc/db-app.conf # This should be your final destination
      subPath: db-app.conf # The name of the file to be placed inside /etc, the filename used here and in mountPath should be same.
  # Define the volumes to be used by these containers
  volumes:
  - name: db-conf # To access this volume, this name must be used inside volumeMounts of the container
    configMap:
       name: scenario-2-cm # Name of the configMap
       items:
         - key: db-app.conf  # Name of the item we had used inside our ConfigMap (under data:)
           path: db-app.conf # Name of the file to be placed inside /etc

I have added enough comments to help you understand the important of each field which is required to mount ConfigMap as file into an existing directory.

Let us create this Pod:

~]# kubectl create -f multi-container-pod-1.yaml
pod/multi-container-pod-1 created

Check the status of the Pod, it should be in Running state:

~]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
multi-container-pod-1           2/2     Running   0          88s

So both of our containers are in Running state.

 

Verify ConfigMap mount path

Let us connect to both the containers and make sure that our application configuration file is mounted:

[root@controller ~]# kubectl exec -it multi-container-pod-1 -c application -- bash
root@multi-container-pod-1:/# ls -l /etc/
total 316
-rw-r--r-- 1 root root    2981 May 11 00:00 adduser.conf
drwxr-xr-x 2 root root    4096 May 11 00:00 alternatives
drwxr-xr-x 2 root root    4096 May 11 00:00 cron.daily
-rw-r--r-- 1 root root      47 Jun 13 08:53 db-app.conf
-rw-r--r-- 1 root root    2969 Feb 26  2019 debconf.conf
-rw-r--r-- 1 root root       5 Mar 19 23:44 debian_version

[root@controller ~]# kubectl exec -it multi-container-pod-1 -c sidecar -- sh
/ # ls -l /etc/
total 36
-rw-r--r--    1 root     root            47 Jun 13 08:53 db-app.conf
-rw-rw-r--    1 root     root           306 Jun  6 21:21 group
-rw-r--r--    1 root     root            22 Jun 13 08:53 hostname
-rw-r--r--    1 root     root           217 Jun 13 08:53 hosts

So our file db-app.conf is mounted successfully along with all other files and /etc is not overwritten so all good.

 

Further Readings

What's the best way to share/mount one file into a pod?
Kubernetes configMap - only one file

 

Summary

In this tutorial we explored Kubernetes ConfigMaps, which are maps of configuration properties that may be used in Kubernetes object definitions such as pods, replication controllers, and also to set environment variables and command arguments. We learned to mount ConfigMap as file into an existing directory inside Pod container. This file can be shared across all the containers inside a Pod and can be useful in multi-container pods.

Advertisement

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment