Kubernetes ConfigMaps provide Kubernetes Pods with configuration information. How to create and use ConfigMaps? What are Kubernetes ConfigMaps concepts? Keep reading to find out.
Introduction
As we mentioned already, ConfigMaps is a way to inject configuration data into pods containers. Why is it needed? Mainly, for separation of configuration from an app. It allows developers to develop apps on a development environment with a certain configuration (e.g. local dependencies, environment variables). Then we can deploy an app to a staging environment with a different configuration, but the same code. And so on to production. If you are familiar with you may want to jump to ConfigMaps real-world demo. For introduction to ConfigMaps keep reading.ConfigMaps
How to create ConfigMaps
You can create ConfigMaps using:
- command-line args (using
kubectl) - ConfigMap manifest
After creation, you can associate ConfigMap to pod containers. The pod and ConfigMap must be in the same namespace.
Note that pods scaled on other nodes in the cluster get the same configuration. It’s because ConfigMap is Kubernetes API object.
How to use ConfigMaps in a Pod
ConfigMaps can be injected to a pod’s containers using:
- environment variables
- Kubernetes Volumes
Of course, you can use ConfigMap inside a container by accessing Kubernetes API. In addition, container command can access it as well.
Kubernetes ConfigMaps Demo
Demo Prerequisites
Install on your machine:
minikubekubectlscaffold
ConfigMaps basic kubectl CRUD commands
As always, let’s start Kubernetes cluster using minikube:
minikube start --profile custom
Be aware that you have to run eval $(minikube -p custom docker-env) in every terminal you want to run kubectl against minikube cluster we started.
If you prefer, you can also repeat this demo on a managed Kubernetes cluster. Check out how easy it is to create Kubernetes Cluster on Linode. Get 100$ credit on Linode using this link. Linode is a cloud service provider recently purchased by Akamai. With this purchase, Akamai became a competitor in the cloud providers market.
Creating ConfigMap using kubectl out of environment file
Now, let’s create ConfigMap from .env file. We’ll use one from jenkins-monitoring repository from my GitHub.
$ kubectl create configmap jenkins-monit-env --from-env-file=.env
configmap/jenkins-monit-env created
To view ConfigMap contents run:
$ kubectl get cm jenkins-monit-env -o yaml
apiVersion: v1
data:
JENKINS_PASSWORD: admin
JENKINS_USERNAME: admin
kind: ConfigMap
metadata:
creationTimestamp: "2022-01-04T20:18:16Z"
name: jenkins-monit-env
namespace: default
resourceVersion: "16802"
uid: b19cee74-cef6-4681-a513-f871ee5c5a79
Creating ConfigMap using kubectl using manifest file
We also can create ConfigMap from manifest files similar to other Kubernetes resources like pods, deployments, services, etc…
For that purpose, copy ConfigMap contents we have just created while copying just metadata name and namespace. Modify name and save it to a file called /tmp/cm.yaml.
Its contents should like like below:
apiVersion: v1
data:
JENKINS_PASSWORD: admin
JENKINS_USERNAME: admin
kind: ConfigMap
metadata:
name: jenkins-monit
namespace: default
Now, run $ kubectl apply -f /tmp/cm.yaml and we can see another ConfigMap created.
$ kubectl apply -f /tmp/cm.yaml
configmap/jenkins-monit created
ConfigMaps real-world demo
Let’s now raise a sample app – Jenkins in Kubernetes. We’ll configure Jenkins credentials using ConfigMap. For that purpose we’ll inject Jenkins credentials as environment variables. First, clone docker_in_jenkins repository from my GitHub and cd into it. We have already seen it in Kubernetes Volumes Introduction.
Next, start minikube cluster, initialize skaffold and run the app.
minikube start --profile custom
skaffold config set --global local-cluster true
# run below in any new terminal to cause kubectl commands be configured to run against minikube cluster
eval $(minikube -p custom docker-env)
# run the app
skaffold run
Use specific ConfigMap key-value pairs in pod environment
Note that we have env-configmap.yaml manifest inside the project folder:
apiVersion: v1
data:
JENKINS_PASSWORD: admin
JENKINS_USERNAME: admin
kind: ConfigMap
metadata:
creationTimestamp: null
labels:
io.kompose.service: jenkins-env
name: env
We use this ConfigMap to configure Jenkins admin username and password. data key-value pairs become environment variables inside Jenkins container.
To see the actual ConfigMap created in our cluster run kubectl get cm env -o yaml:
apiVersion: v1
data:
JENKINS_PASSWORD: admin
JENKINS_USERNAME: admin
kind: ConfigMap
...
Where’s it used? Right. In Deployment manifest – jenkins-deployment.yaml in pod template. We inject ConfigMap values one by one:
- env:
- name: JENKINS_PASSWORD
valueFrom:
configMapKeyRef:
key: JENKINS_PASSWORD
name: env
- name: JENKINS_USERNAME
valueFrom:
configMapKeyRef:
key: JENKINS_USERNAME
name: env
Is it working? Of course! To make sure, first make Jenkins service accessible on localshost using kubectl port-forward svc/jenkins 8080:8080. Next, navigate to https://localhost:8080 and you should see Jenkins UI. Login as admin using admin password.
Moreover you can see container environment in the output of : kubectl describe deployments.apps/jenkins. You should see below output:
Environment:
JENKINS_PASSWORD: <set to the key 'JENKINS_PASSWORD' of config map 'env'> Optional: false
JENKINS_USERNAME: <set to the key 'JENKINS_USERNAME' of config map 'env'> Optional: false
Inject the whole ConfigMap to pod environment
What if our ConfigMap has a lot of configuration key-value pairs and the app needs all of them. Is there a less verbose way for injecting the whole ConfigMap instead of injecting values one by one. Of course!
Use below syntax instead:
envFrom:
- configMapRef:
name: env
Run skaffold run to update the deployment, rerun port forwarding. Next, check that you can still login to Jenkins with the same credentials.
What if we need to inject configuration as configuration files? We can use Kuberentes volumes.
Inject Kubernetes ConfigMap to pods using volumes
We have seen in Kubernetes Volumes Introduction to store containers data on Kubernetes node. Here we want to inject configuration data into containers. How to do it? We’ll inject ConfigMap data using volumes.
Let’s add new volume under volumes
- name: jenkins-credentials
configMap:
name: env
And mount it under volumeMounts
- name: jenkins-credentials
mountPath: /etc/credentials
Run skaffold run to update the deployment. Now, let’s inspect /etc/credentials inside Jenkins container.
kubectl exec -it pod/jenkins-589499fd74-gcwcp -- bash
root@jenkins-589499fd74-gcwcp:/# ls /etc/credentials/
JENKINS_PASSWORD JENKINS_USERNAME
root@jenkins-589499fd74-gcwcp:/# cat /etc/credentials/JENKINS_PASSWORD
admin
We see that each key in ConfigMap became the file name while the key’s value has become the file contents. Note, that Jenkins doesn’t use /etc/credentials path. I’m showing it for purely demo purposes. Yet, an app that needs to mount configuration and prefers to read it from a file could use this method.
Live reload of Kuberentes ConfigMap values inside the containers
Apps may want to mount ConfigMap using volumes to gain live-reload functionality of configuration. Let’s see this in action.
First modify in JENKINS_PASSWORDenv-configmap.yaml to be password instead of admin
Then update env ConfigMap using kubectl apply -f env-configmap.yaml. Use kubectl get cm env -o yaml to make sure it’s updated.
Let’s now inspect the contents of JENKINS_PASSWORD inside Jenkins container:
root@jenkins-589499fd74-gcwcp:/# cat /etc/credentials/JENKINS_PASSWORD
password
Cool! Live reload works!
You may argue that sharing sensitive information like credentials should be done in a more secure way. Right! There are Kubernetes Secrets just for that. I’ll demo them in future posts.
Finally, stop our cluster.
$ minikube stop --profile custom
Summary
That’s it about Kubernetes ConfigMaps. As always, feel free to share and comment.
Bonus:
- Become a Certified Kubernetes Administrator (CKA)!
- Become a Certified Kubernetes Application Developer (CKAD)!
- BUNDLE KUBERNETES FUNDAMENTALS & CKA CERTIFICATION (COURSE & CERTIFICATION) FOR THE BEST DEAL! $499 ONLY!
Recommended Kubernetes courses on Pluralsight:
Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)
Recommended Kubernetes books on Amazon:
