Kubernetes ConfigMap & Secrets

Kubernetes ConfigMap is an essential tool for managing configuration data within containerized applications. It allows developers to separate configuration specifics from container images, thus making applications more portable and easier to manage. A ConfigMap stores configuration data as key-value pairs, which can be consumed by pods or used to set command-line arguments in containers. Typically defined in a YAML file, this data is organized within a specific namespace, ensuring that it is isolated and secure. The ConfigMap data is then accessed by applications through the Kubernetes API, which treats it as a ConfigMap object. This object can be modified or replaced without altering the actual container image, enabling a dynamic and flexible approach to managing configuration settings in a distributed environment.

Most of the time, we want our image to be portable. It basically means that, we should allow whoever is running the container to override the default values.

These values depend on the user who’s running the container or starting the pod. We generally pass these values using three ways.

  1. Configuration files (YAML, JSON)
  2. Command line arguments as flags
  3. Environment variables

What is ConfigMap?

ConfigMap is a Kubernetes resources that decouples configuration from pods and other Kubernetes resources.

“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.

Caution: 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.” - kubernetes.io

One thing to keep in mind while using ConfigMap is that you must create it first and then create the resource that reference to the ConfigMap otherwise the workload wouldn’t start. Also, make sure that the key you’re passing to the workload is not misspelled and exists in the ConfigMap.

Why do we need ConfigMaps?

There are many applications that need ConfigMap like when you run your Prometheus application, Prometheus looks for a Prometheus.yml file. Another example is when you run kube-bench then it looks for config file in the directory /etc/kube-bench/config.yml. Apart from these, there are multiple applications where you need to pass ConfigMap in order to give application specific configurations to your pod.

Creating ConfigMaps imperatively

To interact with a ConfigMap, users typically employ kubectl commands. For instance, kubectl get configmap is used to retrieve a list of all ConfigMaps in the current namespace, providing a quick overview of the available configurations. To delve deeper into the specifics of a ConfigMap, kubectl describe configmap [name of the configmap] is the go-to command. This command offers detailed information about a particular ConfigMap, including its data and how it's used in the cluster. The interaction with ConfigMaps through these commands is facilitated by the Kubernetes API server, which acts as the central interface for Kubernetes' management operations. Through these commands, users can efficiently manage configuration data, ensuring that the applications running on the nodes are configured correctly and consistently at runtime.

You can creating ConfigMap in your Kubernetes cluster using the imperative command. The syntax looks something like this:

kubectl create configmap <name> <data-source> 

You can create these using two flags --from-literal if you’re passing the key-value pairs while executing the kubectl command or --from-file if you’re referencing to a file that carries the key-value pairs.

One thing to note is that if you want to create multiple key-value pair using --from-literal flag, then you have to type it again & again.

kubectl create configmap demo-configmap --from-literal=NAME=ANURAG --from-literal=AGE=21

Creating ConfigMap from a file

It becomes boring if you have to repeat --from-literal many times. What we can do is that we can create a file that store all your key-value pairs in one file and use that to create ConfigMap.

$ cat config.txt 
ENV=PROD
NAME=ANURAG
SERVICE=BACKEND
$ kubectl create cm demo-cm --fromo-file config.txt 
configmap/dmeo-cm created

Now, we have created ConfigMap, and it’s time to mount that into the pod. There are two ways in which you can do that. One we can do it via the environment variables and another we can do it via volume mounts.

  1. Environment Variables
spec:
  containers:
    - name: demo-container
      image: nginx
      env:
        - name: ENV
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: ENV

Now the container will have the environment variable ENV with the value whatever is mapped to the ENV key.

  1. Volumes

All you’ve to do is to pass your ConfigMap as volume.

volumes:
    - name: <name-of-volume>
      configMap:
         name: <name-of-config-map>

After configuring the volume, you need to mount this into the container, and it looks something like this

volumeMounts:
    - name: <name-of-configmap>
         mountPath: <path>
  • Mountpath is the path where the configuration file will lie inside your container. Path is important for those services that look at configuration files at a certain location. Look at this job to understand volumes in more detail.

Example of what a ConfigMap yaml could look like:

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # property-like keys; each key maps to a simple value
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # file-like keys
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true    
Source: kubernetes.io

ConfigMaps and Kubernetes Pods

Kubernetes ConfigMap is a versatile Kubernetes object designed to store non-confidential data in key-value pairs, which can then be consumed by Kubernetes pods. A notable feature is the envFrom field in the pod spec, which allows environment variables to be imported directly from ConfigMap key-value pairs into the pods. This is typically defined within a pod.yaml file, where users can reference a ConfigMap using the configMapRef field. Additionally, ConfigMap supports a binaryData field, enabling the storage of binary content alongside the usual textual data. This is particularly useful when dealing with non-UTF8 encoded data. Kubernetes also offers a config-volume option, allowing ConfigMaps to be mounted as volumes inside pods. This method is ideal for configuring applications that expect configuration files in a file system. Another advanced feature is immutable ConfigMaps. Once set as immutable, a ConfigMap cannot be changed or deleted, ensuring consistent configuration and reducing the likelihood of accidental changes that could disrupt the running pods. These features collectively enhance the flexibility and reliability of application configuration management within Kubernetes clusters.

Creating ConfigMaps & Secrets with Devtron

  • Prerequisites for creating ConfigMaps & Secrets in Devtron is to set up your global configurations. If you've not set up your global configurations, then read how to set it up here. Post setting up, your configurations, you need to deploy your application using devtron and there in the App Configuration section you will see options for creating ConfigMaps & Secrets.
  • Devtron gives you a dashboard from where you can create your ConfigMap easily. Go to your app configuration and then create a ConfigMap.
  • You can also select the option how you want to use the ConfigMap whether as env variables or volumes.
  • If you’re selecting volumes, then you can also set the path where the volume should be mounted.

Secrets

Secrets are exactly similar to ConfigMaps and the only difference is that they are base64 encoded.  We use secrets to store data that are confidential for the organization.

If you want to decode the secret, then you can decode it easily using

echo "something-secret" | base64 -d 

Let's see this in action. We will create one secret imperatively, and later we will decode it using base64.

Most probably you’re not going to use it, and the reason is that anyone can decode your secrets.

Devtron integrates with other secret's provider like HashiCorp Vault, AWS secrets manager etc. which gives you a more robust way to store your Kubernetes secrets or application specific secrets.

  • Please note that just saving the ConfigMap & Secret will not create one, you need to run the complete CD Process again and the ConfigMap/Secrets will reflect in your cluster.

The well-maintained documentation makes installation and troubleshooting a breeze. You can reach out to the team on their dedicated discord community server for any queries.

Conclusion

In conclusion, this tutorial has explored the fundamental aspects of managing configuration data in a cloud-native environment, particularly focusing on the use of Kubernetes ConfigMaps. As we have seen, ConfigMaps are ideal for handling plain text data, such as configuration files and other non-sensitive information, which is crucial in a Docker-based container setup. However, it's important to remember that for sensitive information, other Kubernetes objects like Secrets should be used. This knowledge serves as a stepping stone for anyone venturing into the world of cloud-native applications, ensuring a solid understanding of how to manage application configurations efficiently and securely.

Do star the project if you like Devtron
Star