Kubernetes ConfigMap: Creating, Viewing, Consuming & Managing

>In the world of traditional applications, admins could use environment variables or live input to manage application behavior at runtime. But those approaches don't work well in the realm of Kubernetes workloads – which usually run automatically, meaning they can't accept live input, and which are isolated from their host environment, making it challenging to manage settings via environment variables.

Rani Osnat
July 8, 2021

But there’s a solution: ConfigMaps. ConfigMaps make it possible to inject custom data into Kubernetes workloads at runtime, without having to embed it into container images or attempt to set it using environment variables.

Keep reading for a guide to Kubernetes ConfigMaps, including how they work, why they’re important, which risks they can present, and how to manage ConfigMaps effectively.

In this article:

What is a Kubernetes ConfigMap?

In Kubernetes, a ConfigMap is a type of native API object designed to store environment-specific configuration data and share it with Pods (which is a Kubernetes component that runs containers and typically hosts applications).

ConfigMaps store data as key-value pairs. This means you can define virtually any type of object (the key) and set a corresponding value for it using a ConfigMap.

As an example of why and how you might use a ConfigMap, imagine that an application hosted in a Kubernetes Pod needs to connect to a database. To do this, the application must know where to find the database on the network.

You can specify this information using a ConfigMap like the following:

apiVersion: v1

kind: ConfigMap

metadata:

  name: database-config

data:

  database_URL: "192.168.100.1/database"

  database_port: "3306"

This tells the application that the database is available at the URL 192.168.100.1/database, and that it operates on network port 3306.

Why are ConfigMaps important?

ConfigMaps are important because applications often need to access data that can change from one environment to another. For instance, as we mentioned above, an application might need to know where it can locate a database.

Since that data is not consistent between one application deployment and another, hard-coding it into container images wouldn’t make a lot of sense. If you did that, you’d have to rebuild your container images every time the configuration data changed.

Nor is it easy to inject custom configuration data into Kubernetes applications at runtime using approaches that work in other types of setups, like setting environment variables through the command line or using static configuration settings files. Kubernetes Pods aren’t designed to be able to connect easily to these types of resources.

With ConfigMaps, however, admins enjoy an easy, flexible way of declaring environment-specific data. They can create ConfigMaps to define application settings at runtime, and they can update ConfigMaps whenever those settings change.

How to create ConfigMaps

Like most Kubernetes resources, ConfigMaps are presented declaratively using code. To create a ConfigMap, simply define an object of the type ConfigMap and specify whichever key-value pairs you want to configure in it.

For example:

apiVersion: v1

kind: ConfigMap

metadata:

  name: some-config

data:

  value1: "some value"

  value2: "another value"

  value3: "yet another value"

The example above uses property-like keys. You can also represent key-value pairs using file-like keys, such as the following:

value1=some_value

After writing code for your ConfigMap, save it as a file. Then, use the kubectl create configmap command to create the ConfigMap by referencing the file. For example:

kubectl create configmap app-settings –from-file=app-container/settings/app.properties

This tells Kubernetes to create a ConfigMap named app-settings using the file located at app-container/settings/app.properties.

How to consume ConfigMaps

Once you’ve created a ConfigMap, you can connect it to a Pod using several different approaches. Here’s a look at the most common:

Mounting a ConfigMap as a volume

Mounting ConfigMaps as volumes is a good approach if your ConfigMaps store lots of values and you want to make them accessible to containers through their local file system. This is similar to using a local configuration file to define settings for a traditional app.

Mounting ConfigMaps as volumes also offers the advantage of applying updates automatically. If you change ConfigMap values, the changes will automatically be reflected in your Pod, without requiring it to restart.

To mount a ConfigMap as a volume for a Pod, add a spec to the Pod’s definition that identifies the ConfigMap you want to mount. For example:

spec:

  volumes:

      - name: config

            configMap:

                name: some-config

Injecting a ConfigMap as an environment variable

ConfigMaps can be injected as environment variables using the envFrom field, which tells Kubernetes to turn the values inside a specified ConfigMap into environment variables that are accessible to a Pod at runtime.

To do this, include the envFrom field and the appropriate ConfigMap definition in your spec. For example:

spec:

  containers:

      - name: app

   command: ["/bin/command", "-e", "value"]

   image: some_app:latest

   envFrom:

             - configMapRef:

             name: some-config

Importantly, ConfigMap values determined as environment variables won’t automatically update if the ConfigMap changes after a container has started. You need to restart the container or Pod for changes to take effect.

Mounting a ConfigMap as a command-line argument

If you want to use values inside a ConfigMap as part of a command that runs inside a Pod, you can mount ConfigMaps as command-line arguments. To do this, write a spec section for your Pod that includes a variable and defines its value based on a ConfigMap. For example:

spec:

  containers:

- name: app

   command: ["some-app", "--example-variable", "$(VAR_VALUE)"]

   image: demo-app:latest

   env:

       - name: sample_app

         valueFrom:

               configMapKeyRef:

                   name: some-config

                   key: var_value

This tells Kubernetes that the value of the command-line argument —example-variable is specified based on the value of the key var_value which exists in the ConfigMap named some-config.

Note that like ConfigMap values that are injected using environment variables, ConfigMaps values mounted as command-line arguments aren’t automatically updated if the values change after a container or Pod has started.

Managing ConfigMaps

To determine which ConfigMaps exist in your cluster, run:

kubectl get configmaps

This will generate a list of your ConfigMaps.

To view the contents of a ConfigMap, use the command:

kubectl describe configmaps <ConfigMap name>

This will display the keys and values defined in the ConfigMap you specify as a plaintext file, with keys separated by horizontal lines. You can also pass the -o yaml option to kubectl if you want it to display the data using YAML.

Updating ConfigMaps

The easiest way to update a ConfigMap is to use the kubectl edit command. For example:

kubectl edit configmap some-config

This opens up a text editor where you can make changes to the ConfigMap named some-config.

If you mounted the ConfigMap as a volume, the values will update automatically. If you injected the ConfigMap’s values as environment variables or command-line arguments, however, you’ll need to restart the Pods for changes to take effect.

Using immutable ConfigMaps

Starting with Kubernetes version 1.19, you can configure a ConfigMap to be immutable at the time you create it. This prevents admins from modifying ConfigMap values using the built-in editor. (It could still be possible to modify a ConfigMap using an external editor, then delete and recreate the ConfigMap.)

Immutable ConfigMaps are useful in situations where a ConfigMap stores essential configuration data that should never change and you want to prevent accidental changes from disrupting application performance.

To make a ConfigMap immutable, simply add the following field when creating the ConfigMap:

immutable: true

Secrets and ConfigMaps

While ConfigMaps are a convenient way of injecting various types of configuration data into applications at runtime, there is one type of data you should never manage using ConfigMaps: Secrets, such as passwords, API keys or other access information.

While it’s technically possible to use ConfigMaps to store secrets, doing so creates Kubernetes security risks because anyone who is able to view your ConfigMap will be able to access your secrets. A better approach is to use the secrets management tooling built into Kubernetes.

Take charge of your Kubernetes clusters

As a cloud-native security solution purpose-built for protecting platforms like Kubernetes, Aqua helps keep your clusters and Pods secure, no matter how you configure them. We won’t tell you how to manage your ConfigMaps, but we will provide the visibility you need to identify and mitigate security risks across all layers of your stack.

Learn more by requesting a demo.

Rani Osnat
Rani is the SVP of Strategy at Aqua. Rani has worked in enterprise software companies more than 25 years, spanning project management, product management and marketing, including a decade as VP of marketing for innovative startups in the cyber-security and cloud arenas. Previously Rani was also a management consultant in the London office of Booz & Co. He holds an MBA from INSEAD in Fontainebleau, France. Rani is an avid wine geek, and a slightly less avid painter and electronic music composer.