Trending keywords: security, cloud, container,

What is Kubernetes ConfigMap?

SHARE:

ConfigMaps are key-value pairs of data that allow applications in Kubernetes to consume constants in the code. By storing configuration values in Kubernetes environments, ConfigMaps facilitate the config factor in the 12 Factor-App methodology, a set of best practices for building portable and resilient web applications known as the 12 Factor-App methodology. 

In this tutorial, we will take a deep dive into Kubernetes ConfigMaps. We will start with an introduction to ConfigMaps and their distinct variations. Then, we will explain how to create ConfigMaps and check their values. Finally, we’ll show you how to consume ConfigMaps in a sample Pod configuration.

For the purposes of this tutorial, we created a sample cluster using Kind.

Let’s get started.

Kubernetes ConfigMap Example

As stated above, ConfigMaps are configuration properties that follow a key-value pattern. You may have already used the files as either .env or .properties files. The following is a sample file containing some configuration properties:

app.properties
port = 3000
language = english
environments = production, development, staging

To store this configuration file in Kubernetes, you will have to create the following manifest:

config-map-example.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
 port: "3000"
 language: "english"
 environments: production, development, productionCode language: JavaScript (javascript)

The data section allows you to store different types of items. It can only hold up to 1MB of data, but you can create multiple ConfigMaps with different names if you find that too restrictive.

You will be able to store nested key-value pairs using the Literal style of defining data:

config-map-example.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  port: "3000"
  environments: production, development, production
  signup.features: |
    experimental.signup=true
    plans.available=[starter, growth, scale]Code language: JavaScript (javascript)

Then, you can reference the keys with their names:

signup.features, port, environmentsCode language: CSS (css)

Later, we’ll show you how to provide those properties within a Pod.

What Types of ConfigMaps Are Available?

Kubernetes offers different kinds of ConfigMaps depending on how you want it to handle them at runtime.

ConfigMaps can be marked as optional. If you try to reference a ConfigMap that does not exist, Kubernetes will prevent the Pod from starting normally by default. If you still want the Pod to run even though the ConfigMap does not exist, you can mark the ConfigMap as optional.

ConfigMaps can also be marked as immutable. You can use the immutable field to instruct Kubernetes to watch the ConfigMaps closely for any changes. If you try to update an immutable ConfigMap, Kubernetes will prevent that operation from happening:

config-map-example.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  port: "3000"
  environments: production, development, production
  signup.features: |
    experimental.signup=true
    plans.available=[starter, growth, scale]
immutable: trueCode language: JavaScript (javascript)

Be sure to use caution when applying the immutable flag, because you cannot change it back or make any modifications after you apply it. You will have to delete the whole object and start over again:

❯ kubectl apply -f config-map-example.yml
pod/busybox unchanged
The ConfigMap "app-config" is invalid:
* immutable: Forbidden: field is immutable when `immutable` is set
* data: Forbidden: field is immutable when `immutable` is setCode language: JavaScript (javascript)

Next, we will explore different ways to create ConfigMaps.

How to Create ConfigMaps

You can create ConfigMaps in different ways, which allows for flexibility in configuration management.

Creating ConfigMaps from Files or Directories

You can create ConfigMaps that reference either a single file or a whole directory of files. The —from-file flag allows you to provide a path to that file or directory.

If the parameter points to a file, it will use that file’s properties as key-value pairs:

$ cat .env.local
FRONTEND_URL=http://localhost:3000
WP_GRAPHQL_URL=http://localhost:10008/graphql

$ kubectl create configmap app-config --from-file=.env.local
configmap/app-config created
$ kubectl describe configmap app-config
Name:         app-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
.env.local:
----
FRONTEND_URL=http://localhost:3000
WP_GRAPHQL_URL=http://localhost:10008/graphqlCode language: JavaScript (javascript)

If the parameter points to a directory, on the other hand, it will use the name of each file as a key and the contents of each file for the value. For example, we created a new folder named example with two files: .env.local and .env.remote:

$ kubectl create configmap app-config --from-file=example
configmap/app-config created
$ kubectl describe configmap app-config
Name:         app-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
.env.local:
----
FRONTEND_URL=http://localhost:3000
WP_GRAPHQL_URL=http://localhost:10008/graphql


.env.remote:
----
FRONTEND_URL=http://headless.example.com
WP_GRAPHQL_URL=http://example.com/graphqlCode language: HTML, XML (xml)

Creating ConfigMaps from the Command Line

You can create ConfigMaps straight from the command line. The –from-literal flag allows you to enter one or more key-value pairs. You will have to provide the same –from-literal flag for each pair: 

$ kubectl create configmap app-config --from-literal=port=3000 
--from-literal=environments=production,development,stagingCode language: JavaScript (javascript)

How to List All ConfigMaps in Kubernetes

Once you have stored some ConfigMaps in Kubernetes, you can list them using the get configmaps command:

$ kubectl get configmaps
NAME               DATA   AGE
app-config         2      19h
kube-root-ca.crt   1      43hCode language: JavaScript (javascript)

This command only shows you the names of your ConfigMaps. If you want to inspect their contents, you will need to use describe:

$ kubectl describe configmap app-config

How to Consume the Keys of a ConfigMap

There are two primary ways to provide ConfigMap data to Pods:

Providing ConfigMaps as Environment Variables

You can mount a Pod manifest and specify an env key-value pair taken from the ConfigMap data. You will have to use the special configMapKeyRef field and specify two parameters: the name of the ConfigMap and the key taken from that ConfigMap:

pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: PORT
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: port
        - name: ENVIRONMENTS
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: environments
  restartPolicy: NeverCode language: JavaScript (javascript)

If you’d rather load the whole ConfigMap object, you can use the envFrom field instead:

…
envFrom:
        - configMapRef:
            name: app-config

Once you’ve deployed the Pod, you can inspect the logs to check that the env variables loaded correctly:

$ kubectl logs busybox
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=busybox
SHLVL=1
HOME=/root
PORT=3000
ENVIRONMENTS=production, development, production
…Code language: PHP (php)

Mounting ConfigMaps via Volumes

ConfigMaps can also be consumed via volumes. First, you need to mount a volume with that ConfigMap. Then, use the volumeMounts field in your Pod container spec to make each key available as a file:

pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "cat /etc/config/*" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: app-config
  restartPolicy: NeverCode language: JavaScript (javascript)

When you inspect the contents of the log for this Pod, you will see all of the key-value pairs for the ConfigMap. Each key-value pair of the app-config will reside in its own file, so you can use the cat /etc/config/* command to display the contents of the files listed in that volume:

$ kubectl logs busybox
production, development, productionenglish3000experimental.signup=false
plans.available=[starter, growth, scale]Code language: JavaScript (javascript)

Where Are Kubernetes ConfigMaps Stored?

Kubernetes stores API objects like ConfigMaps and Secrets within the etcd cluster. Etcd is essentially the brain of Kubernetes, since it stores all of the key-value objects that Kubernetes requires to orchestrate the containers.

The problem with using etcd, though, is that it limits the size of the data that can be stored. For key values, it imposes a limit of 1MB (which is the upper limit of etcd).

If you were to try to exceed that limit, you would receive the following error message:

$ kubectl apply -f config-map-example.yml

Resource: "/v1, Resource=configmaps", GroupVersionKind: "/v1, Kind=ConfigMap"
Name: "app-config", Namespace: "default"
for: "config-map-example.yml": Request entity too large: limit is 3145728Code language: JavaScript (javascript)

Next Steps

This wraps up our deep-dive tutorial on Kubernetes ConfigMaps and how to use them in practice. If you liked our content, you can subscribe to read more upcoming tutorials from Sysdig related to Kubernetes, cloud security, and open source technologies.