Kubernetes Config Maps
Config maps in Kubernetes are a way of decoupling your application configuration from the code itself. They are mounted into your containers as volumes and will present what is configured in the mounted path inside the pod. In this post I will go through creating a config map with some basic data in it, mount it to a pod in a deployment and exec into that pod to show you how they appear in the pod.
YAML File
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx
data:
# Key Value Properties where key is file name and value is contents of file
specialdirlocation: "/path/to/a/dir/that/matters/to/my/app"
specialfn: "somespecialfn.txt"
# creates file named .config in the mounted directory
# and adds each line below as a line in the file.
.config: |
numjobsperday=1
jobfailaction=alert
specialdirlocation: "/path/to/a/dir/that/matters/to/my/app"
specialfn: "somespecialfn.txt"
These 2 lines will present 2 files in the pods mounted directory named "specialdirlocaiton" and "specialfn" and their contents will be what is quoted after the keys.
.config: |
numjobsperday=1
jobfailaction=alert
This section will present 1 file in the pods mounted directory named ".config" which will add the raw text below as lines in the file.
Mounting the Config Map in Deployment
In your deployments YAML file you will want to create a new volume in spec.template.spec
volumes:
- name: nginx-config
configMap:
name: nginx
And then mount the volume in the container in spec.template.spec.containers
volumeMounts:
- name: nginx-config
mountPath: "/config"
readOnly: true
This will mount the volume named "nginx-config" as a read only volume to the path /config
in the container.
Deploy the Config Map and Your Deployment
Apply your config maps yaml file
$ kubectl apply -f /path/to/configmap.yaml
And apply your deployments yaml file
$ kubectl apply -f /path/to/deployment.yaml
Verify your config map and deployment is running
The config map I have described above is named nginx so I will grep for that in my command
$ kubectl get cm | grep nginx
nginx 3 2m41s
$
So that is deployed properly, now I will check my nginx deployment and pods that I have. What you will be looking for will be different unless your deployment is named nginx
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 33m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5b7f8d685b-5gwgp 1/1 Running 0 22m
So my pod and deployment is running.
View config in Pod
Launch a bash shell in one of your pods
$ kubectl exec --stdin --tty nginx-5b7f8d685b-5gwgp -- /bin/bash
root@nginx-5b7f8d685b-5gwgp:/#
nginx-5b7f8d685b-5gwgp
will be changed to whatever your pods name was listed in the kubectl get pods
command.
Now if we list all of the files in our /config directory that we told the config map to mount on
root@nginx-5b7f8d685b-5gwgp:/# ls -a /config
. .. ..2022_09_30_15_47_23.2316668112 ..data .config specialdirlocation specialfn
root@nginx-5b7f8d685b-5gwgp:/#
We have all 3 files that we defined in our config map "specialdirlocation", "specialfn", and ".config"
now if we list the contents of both specialdirlocation and specialfn with awk 1
so we will get a newline character after the file
root@nginx-5b7f8d685b-5gwgp:/# awk 1 /config/specialfn
somespecialfn.txt
root@nginx-5b7f8d685b-5gwgp:/# awk 1 /config/specialdirlocation
/path/to/a/dir/that/matters/to/my/app
root@nginx-5b7f8d685b-5gwgp:/#
Notice that the contents were exactly what we specified in the config map.
And lets take a look at the contents of our .config file.
root@nginx-5b7f8d685b-5gwgp:/# cat /config/.config
numjobsperday=1
jobfailaction=alert
root@nginx-5b7f8d685b-5gwgp:/#
We can see that the contents of the .config file is each line by line of what we specified. It is important to note that in this file a newline character is appended to every line in the file so your parser will need to account for that.
And at this point our application does not need to worry about uploading credentials to your cluster, or keeping them in a container or whatever is being done. The configuration map is a resource of the cluster in that namespace so you can just mount them in the directory on the pod that your application expects them and parse them as needed.
If you have any additional questions please leave a comment so I can clear them up.