As we are seeing some most frequently using Kubernetes resources in last couple of posts, in this we are going to see one of the more important Kubernetes resources called configMap. We are going to see what is configMap, how to create, manage and use it within cluster.
If you are recently started using Kubernetes or just managing partially, you may get a question like how I can manage my application configuration externally or dynamically, where I can define the connection strings, external service URLs, custom configuration values for multiple environments. Where to store that? And if that possible?
The simple answer is yes, Kubernetes has resource called ConfigMaps.
In this article, lets learn about how to use ConfigMaps in Kubernetes also how to create ConfigMaps mount them in volumes, and use them as environment variables.
What is a ConfigMap in Kubernetes?
A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.
A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.
Note: ConfigMap does not provide secrecy or encryption. If the data you want to store are confidential, use a Secret rather than a ConfigMap, or use additional (third party) tools to keep your data private.
What is the use of ConfigMap?
It been always recommended to keep the configuration setting separate to make sure it can be reused wildly. As per Twelve-Factor Application it helps to maintain the config between environments as there will be changes on DB values, resources, external service and hostname, etc.
This lets you change easily configuration depending on the environment (development, QA, production and etc.) and to dynamically change configuration at runtime.
How does a ConfigMap work?
Let’s assume you have multiple environments, (even with single environment you can use, there is no limitation) and each has different configuration values. you have multiple ConfigMaps, one for each environment. ConfigMap is created and added to the Kubernetes cluster.
Last, containers in the Pod reference the ConfigMap and use its values.
Create and mount ConfigMap as volume
With Yaml configmap is easy to create and manage, This will lets you create that ConfigMap like any other Kubernetes resources using `kubectl apply -f $file.yaml`. After that, you mount the ConfigMap as a Volume in your Pod’s YAML specification.
Define the ConfigMap in a YAML file.
Create a YAML file setting the key-value pairs for your ConfigMap.
apiVersion: v1
kind: ConfigMap
metadata:
name: test-configmap
data:
# Configuration values can be set as key-value properties
database: mongodb
database_uri: mongodb://localhost:27017
# Or set as complete file contents (even JSON!)
keys: |
image.public.key=771
rsa.public.key=42
Create the ConfigMap in your Kubernetes cluster
Create the ConfigMap using the commandÂ
# kubectl apply -f config-map.yaml
Mount the ConfigMap through a Volume
Each property name in this ConfigMap becomes a new file in the mounted directory (`/etc/config`) after you mount it.
kind: Pod
apiVersion: v1
metadata:
name: pod-using-configmap
spec:
# Add the ConfigMap as a volume to the Pod
volumes:
# `name` here must match the name
# Specified in the volume mount
- name: test-configmap-volume
# Populate the volume with config map data
configMap:
# `name` here must match the name
# Specified in the ConfigMap's YAML
name: test-configmap
containers:
- name: container-configmap
image: nginx:1.20.2
# Mount the volume that contains the configuration data
# into your container filesystem
volumeMounts:
# `name` here must match the name
# from the volumes section of this pod
- name: test-configmap-volume
mountPath: /etc/config
Attach to the created Pod using `kubectl exec -it pod-using-configmap sh`. Then run `ls /etc/config` and you can see each key from the ConfigMap added as a file in the directory. You can use `cat` to look at the contents of each file and you’ll see the values from the ConfigMap.
Create a ConfigMap with Environment Variables and `envFrom`?
You can consume a ConfigMap via environment variables in a running container using the `envFrom` property.
Create the ConfigMap using the example from the previous section. Set the `envFrom` key in each container to an object containing the list of ConfigMaps you want to include.
kind: Pod
apiVersion: v1
metadata:
name: pod-env-var
spec:
containers:
- name: env-var-configmap
image: nginx:1.20.2
envFrom:
- configMapRef:
name: test-configmap
Attach to the created Pod using `kubectl exec -it pod-env-var sh`. Then run `env` and see that each key from the ConfigMap is now available as an environment variable.
Please note: ConfigMaps consumed as environment variables are not updated automatically and require a pod restart.
Creating a ConfigMap
Here is the pattern for kubectl, use this kubectl command:
# kubectl create configmap <name> <data-source>
The <name> is the name of the ConfigMap, which should be valid for use as a DNS subdomain. The <data-source> indicates the files or values from which ConfigMap data should be obtained.
You can create ConfigMaps based on one file, several files, directories, or env-files (lists of environment variables). The basename of each file is used as the key, and the contents of the file becomes the value.
ConfigMap Data Source | Example kubectl command |
Single file | kubectl create configmap app-settings –from-file=app-container/settings/app.properties |
Multiple files | kubectl create configmap app-settings –from-file=app-container/settings/app.properties–from-file=app-container/settings/backend.properties |
Env-file | kubectl create configmap app-env-file–from-env-file=app-container/settings/app-env-file.properties |
Directory | kubectl create configmap app-settings –from-file=app-container/settings/ |
You can get more information about this command usingÂ
# kubectl create configmap --help
Immutable ConfigMaps
The Kubernetes feature Immutable Secrets and ConfigMaps provides an option to set individual Secrets and ConfigMaps as immutable. For clusters that extensively use ConfigMaps (at least tens of thousands of unique ConfigMap to Pod mounts), preventing changes to their data has the following advantages:
protects you from accidental (or unwanted) updates that could cause applications outages
improves performance of your cluster by significantly reducing load on kube-apiserver, by closing watches for ConfigMaps marked as immutable.
This feature is controlled by the ImmutableEphemeralVolumes feature gate. You can create an immutable ConfigMap by setting the immutable field to true. For example:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
Once a ConfigMap is marked as immutable, it is not possible to revert this change nor to mutate the contents of the data or the binaryData field. You can only delete and recreate the ConfigMap. Because existing Pods maintain a mount point to the deleted ConfigMap, it is recommended to recreate these pods.