Step-by-Step Guide to Using ConfigMaps in Kubernetes

|
Published:
|
|
Step-by-Step Guide to Using ConfigMaps in Kubernetes

This tutorial provides a step-by-step guide to using ConfigMaps in Kubernetes. ConfigMaps in Kubernetes are a powerful tool for managing configuration data separately from application code. They allow you to decouple configuration settings such as environment variables, command-line arguments, or configuration files from your containerized applications. In this guide, we’ll explore how to create, manage, and use ConfigMaps effectively in your Kubernetes deployments.

How to Use ConfigMaps in Kubernetes Deployments/Pods

What is a ConfigMap in Kubernetes?

ConfigMap is Kubernetes API object that is used, unlike secrets, to store and manage non-sensitive configuration data in key-value pairs. ConfigMap provides a way to decouple configuration artifacts from the application code thus making containerized applications portable. In short, it provides a way to inject configurations into Pods without modifying the container image or source code directly.

ConfigMap is often used to store configuration parameters such as:

  1. Environment variables: You can inject ConfigMap data into a container as environment variables, which allows you to configure how the application behaves without changing its container image.
  2. Configuration files: ConfigMaps can also be mounted as volumes into containers, allowing applications to read configuration files directly from the volume.
  3. Command Line arguments: ConfigMaps can also store command-line arguments that can be passed to containers in Kubernetes. This is particularly useful when applications need to start with specific runtime options or flags.

ConfigMaps are useful when you want to:

  • Centralize configuration: Instead of embedding configuration directly into application code, container images or Kubernetes manifests, ConfigMaps provide a centralized way to manage configuration data.
  • Override configuration: You can update ConfigMaps independently of the application code, which makes it easier to change configurations without rebuilding or redeploying the containers.

Are you getting started with Kubernetes and you need a book that offers a beginner-friendly approach to mastering Kubernetes architecture and core concepts such as Pods, Deployments, Services, StatefulSets, Ingress, ConfigMaps, and more? Look no further, The Kubernetes Book: 2024 Edition by Nigel Poulton is the best bet.

Creating a ConfigMap in Kubernetes

Kubernetes offers multiple ways to create ConfigMaps, imperatively using kubectl create configmap command or declaratively using the manifest file.

The name of a ConfigMap must be a valid DNS subdomain name. It must consist of lower case alphanumeric characters, ‘-‘ or ‘.’, and must start and end with an alphanumeric character (e.g. ‘example.com’).

Regex used for validation is:

'[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'

Therefore, configmaps with underscore on their names will fail to create, for example.

You can specify the respective namespace for the ConfigMaps (-n|–namespace <namespace>) when creating them imperatively or specify it in the manifest yaml file.

Creating ConfigMaps from Literal Values

You can create a ConfigMap using literal key-value pairs with kubectl create configmap.

kubectl create configmap database-host --from-literal=db_host=mariadb --from-literal=db_port=3306

The command creates a Kubernetes ConfigMap called database-host with two key-value pairs:

  • db_host: mariadb
  • db_port: 3306

Creating ConfigMap from a File

You can create a ConfigMap from a file by passing the –from-file option to the kubectl create configmap command.

cat database-host
db_host: mariadb
db_port: 3306

Hence;

kubectl create configmap database-host --from-file=./database-host -n apps

This will create the configmap in the apps namespace.

Creating a ConfigMap from a Directory

When you have multiple files that you want to store as different keys in a configmap, you can put them under a specific directory and create them right from the directory. When creating a configmap in Kubernetes based on a directory, each file whose basename (filename without the path) corresponds to a valid key in the directory will be packaged into the configmap.

Let’s say you have a directory named database-host with the following files:

  • db_host containing db host name
  • db_port containing port number
tree database-host
database-host/
├── db_host
└── db_port

1 directory, 2 files

To create a Kubernetes ConfigMap named datbase-host from this directory, where each file becomes a key-value pair in the ConfigMap:

kubectl create configmap database-host --from-file=database-host -n apps

Creating ConfigMap from an Environment Variables File

This allows you to store multiple environment variables in a single file.

Create a text file that contains your environment variables in the format KEY=VALUE, each on a new line:

cat  database-host
DB_HOST=mariadb
DB_PORT=3306

Then use kubectl create configmap with the --from-env-file option followed by the path to your environment file:

kubectl create configmap database-host --from-env-file=database-host -n apps

Create a ConfigMap from a YAML manifest file

Here is the sample YAML file to create a ConfigMap named database-host with the DB_HOST and DB_PORT values:

cat database-host.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: database-host
  namespace: apps
data:
  DB_HOST: mariadb
  DB_PORT: "3306"

Apply the ConfigMap using:

kubectl apply -f database-host.yaml

A sample configuration;

cat web-page.html
apiVersion: v1
kind: ConfigMap
metadata:
  name: web-page
  namespace: apps
data:
  index.html: |
    <!DOCTYPE html>
    <html>
    <head>
      <title>Welcome to my website</title>
    </head>
    <body>
      <h1>Hello, Kubernetes!</h1>
      <p>This is an updated message.</p>
    </body>
    </html>

Viewing and Describing ConfigMaps

Listing Available ConfigMaps in Kubernetes Cluster

List all ConfigMaps in the default namespace of the cluster:

kubectl get configmaps

List all ConfigMaps in a specific namespace in the cluster:

kubectl get configmaps [-n|--namespace] <namespace>

For example;

kubectl get configmaps -n apps

List all ConfigMaps in the all namespaces of the cluster:

kubectl get configmaps [-A|--all-namespaces]

Sample output;

NAMESPACE          NAME                                                   DATA   AGE
apps               database-host                                          2      13h
apps               html-page                                              1      23d
apps               kube-root-ca.crt                                       1      23d
apps               nginx-config                                           1      3d3h
calico-apiserver   kube-root-ca.crt                                       1      23d
calico-system      active-operator                                        1      23d
calico-system      cni-config                                             1      23d
calico-system      kube-root-ca.crt                                       1      23d
calico-system      tigera-ca-bundle                                       2      23d
default            kube-root-ca.crt                                       1      23d
kube-node-lease    kube-root-ca.crt                                       1      23d
kube-public        cluster-info                                           1      23d
kube-public        kube-root-ca.crt                                       1      23d
kube-system        coredns                                                1      23d
kube-system        extension-apiserver-authentication                     6      23d
kube-system        kube-apiserver-legacy-service-account-token-tracking   1      23d
kube-system        kube-proxy                                             2      23d
kube-system        kube-root-ca.crt                                       1      23d
kube-system        kubeadm-config                                         1      23d
kube-system        kubelet-config                                         1      23d
rm                 kube-root-ca.crt                                       1      21d
tigera-operator    kube-root-ca.crt                                       1      23d

To display the ConfigMap in specific output, for example, in yaml format, pass the -o|–output= option to kubectl get command.

kubectl get configmap database-host -n apps -o yaml

Read more on kubectl get –help to learn more on different command line options to use.

Show More Details About ConfigMaps

You can use the kubectl describe configmap command to show more details of a ConfigMap.

kubectl describe configmap <configmap-name> [-n|--namespace <namespace>]

For example, to show more details about a ConfigMap, kube-root-ca.crt, in the default namespace;

kubectl describe configmap kube-root-ca.crt
Name:         kube-root-ca.crt
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/description:
                Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubern...

Data
====
ca.crt:
----
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIIFgTDp0Lsj6IwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE
AxMKa3ViZXJuZXRlczAeFw0yNDA2MTYxNzA1MzdaFw0zNDA2MTQxNzEwMzdaMBUx
EzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCz5W7a15BtNoLfNBAGWZQIXa1sCYR8KRLkNb4HohbvfRtLJbh4+Dq6jycB
eacNgKV03Pv7LsnBjYVboiYsYfo2CIcKDxkPueHcCFhaizqbN4643AxFDh2YoODy
imqV0IlPNs6WfLpZl8CWCMsPg1Wf5ebAloPozncUmAFxreTFSRnhXXHtVrG6v55F
PxU7Y2VHIGRhJ6EkamKWKOWwlwU916z51+pW0IobQb1RzDmu0AYD9bLZ8ANjqC7I
AgBOKSUeN3wMP3/ZO5eO1F37AFnkegECrdubfCB4C5oDbeB6yJYOPBWd8rpU0KtW
KnLhPm+p4hqlj0ns+tp/GdsNghdTAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSyzdSJXP3ttEm6Ppf3K9FUQIe5tTAV
BgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQCVkHwwTwkg
vVGLmQJUnHdNUgPGnphxyXKaDFnXCCOZ+Gz+j6c2Apg4Xq2VUq1yQaiiUisg5hVq
MaoSRO13gmnCnp6aLChH3wyywV2GHQFBIae+mfwhYr+8dV9qqj/ntCMbXkda0x+D
DxDK5ecfa5JoVDQa+do6MHy0Jp0+LlhwUnzw9owXqSajsfwDn+GrpQFRHswggS61
TbtjICDpMJ0xQkG5rMP3nikGXvl1CTDGWM1R6FfGI/Rls5M+5WvVTOh0YtVPzKMm
BdBKrQt21kXVV9/UFugSQt7l+8FggjZR1/0n3IaGIA1ldXkpPDbhLdu45GFHb0lK
ghpt9pOKoQHp
-----END CERTIFICATE-----


BinaryData
====

Events:  <none>

Using ConfigMaps in Kubernetes Pods

You can configure Kubernetes Pods to use ConfigMaps via volumes or environment variables.

Mounting ConfigMaps as Volumes

You can mount ConfigMaps as volumes inside Pods.

To demonstrate this, let create a basic Nginx deployment that mounts the html page as a config map!

Prepare Nginx web page. Here is our sample page.

cat index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            padding: 50px;
        }
        h1 {
            color: #009688;
        }
        p {
            color: #607d8b;
        }
        .container {
            margin-top: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .kube-logo {
            width: 150px;
            height: 150px;
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <h1>Welcome to our Kubernetes Cluster!</h1>
    <p>Our cluster is running smoothly and efficiently.</p>
    <div class="container">
        <img class="kube-logo" src="https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png" alt="Kubernetes Logo">
        <p>Kubernetes orchestrates our applications with ease, ensuring high availability and scalability.</p>
    </div>
    <p>Feel free to explore and innovate!</p>
</body>
</html>

Now, based on the configuration file, let’s create a web page ConfigMap;

kubectl create configmap web-page --from-file=./index.html -n apps

This is how configmap will be set as;

kubectl get configmaps web-page -n apps -o yaml
apiVersion: v1
data:
  index.html: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            body {
                font-family: Arial, sans-serif;
                text-align: center;
                padding: 50px;
            }
            h1 {
                color: #009688;
            }
            p {
                color: #607d8b;
            }
            .container {
                margin-top: 30px;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .kube-logo {
                width: 150px;
                height: 150px;
                margin-right: 20px;
            }
        </style>
    </head>
    <body>
        <h1>Welcome to our Kubernetes Cluster!</h1>
        <p>Our cluster is running smoothly and efficiently.</p>
        <div class="container">
            <img class="kube-logo" src="https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png" alt="Kubernetes Logo">
            <p>Kubernetes orchestrates our applications with ease, ensuring high availability and scalability.</p>
        </div>
        <p>Feel free to explore and innovate!</p>
    </body>
    </html>
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-11T17:48:07Z"
  name: web-page
  namespace: apps
  resourceVersion: "5523425"
  uid: c404b62a-bae2-4122-ac3e-7ab3c87d3510

Next, create an Nginx deployment manifest file and define how to mount the web page configmap as a volume.

cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  namespace: apps
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-web-page
          mountPath: /usr/share/nginx/html
          readOnly: true
      volumes:
      - name: nginx-web-page
        configMap:
          name: web-page

In summary, this configuration allow Nginx app Pods to mount a ConfigMap named web-page as a volume at /usr/share/nginx/html, allowing the nginx container to serve content from the index.html file stored in the ConfigMap.

Apply the configuration;

kubectl apply -f nginx.yaml

Check the Pods;

kubectl get pods  -n apps -l app=nginx
NAME                         READY   STATUS    RESTARTS   AGE
nginx-app-7598db6dbf-svxhm   1/1     Running   0          22s

Let’s try to access the page;

kubectl exec -it nginx-app-7598db6dbf-svxhm -n apps -- curl localhost

Sample output;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            padding: 50px;
        }
        h1 {
            color: #009688;
        }
        p {
            color: #607d8b;
        }
        .container {
            margin-top: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .kube-logo {
            width: 150px;
            height: 150px;
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <h1>Welcome to our Kubernetes Cluster!</h1>
    <p>Our cluster is running smoothly and efficiently.</p>
    <div class="container">
        <img class="kube-logo" src="https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png" alt="Kubernetes Logo">
        <p>Kubernetes orchestrates our applications with ease, ensuring high availability and scalability.</p>
    </div>
    <p>Feel free to explore and innovate!</p>
</body>
</html>

You can expose the Deployment to test it outside Kubernetes cluster.

kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort --namespace=apps

Check the services to retrieve the port to access your pods externally;

kubectl get service -n apps
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-app   NodePort   10.109.64.134           80:32239/TCP   1m

You can access the app via port 32239 via the worker nodes IP;

Using ConfigMaps in Kubernetes Pods

And that is it!

Using ConfigMaps as Environment Variables

You can use ConfigMaps as environment variables value.

cat mariadb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb-deployment
  namespace: apps
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
      - name: mariadb
        image: mariadb:latest
        ports:
        - containerPort: 3306
        env:
        - name: MARIADB_ROOT_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: db-root-pwd
              key: db-pwd

Apply and confirm the credentials.

kubectl apply -f mariadb.yaml

After that, check the pods;

kubectl get pods -l app=mariadb -n apps
NAME                                  READY   STATUS    RESTARTS   AGE
mariadb-deployment-776dcbcbcc-68vsk   1/1     Running   0          1m
mariadb-deployment-776dcbcbcc-wg7mv   1/1     Running   0          1m

Check the availability of the password within the Pods;

kubectl exec -it mariadb-deployment-776dcbcbcc-68vsk -n apps -- env | grep MARIADB_ROOT_PASSWORD

Sample output

MARIADB_ROOT_PASSWORD=p@ssw0rd

Confirm that the login to MariaDB as root user and defined password works.

kubectl exec -it mariadb-deployment-776dcbcbcc-68vsk -n apps -- mariadb -u root -p

If the password is correct, then you should drop into MariaDB!

Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 11.4.2-MariaDB-ubu2404 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Updating Kubernetes ConfigMaps

Updating a ConfigMap in Kubernetes can be approached in a few different ways:

Update ConfigMap Using kubectl apply or edit

Using kubectl apply or kubectl edit commands allows you to update a ConfigMap directly from the command line or by editing a YAML file.

kubectl apply command updates a ConfigMap by applying a new configuration defined in a YAML file. It merges changes into the existing ConfigMap.

For example, if you have updated your ConfigMap manifest file, then apply the changes;

kubectl apply -f updated-configmap.yaml

kubectl edit command opens the current ConfigMap in your default text editor, allowing you to modify it interactively. After saving your changes and exiting the editor, Kubernetes applies the updated configuration.

kubectl edit configmap <configmap_name> -n <namespace>

Directly with kubectl replace or patch

You can also update a ConfigMap directly with kubectl replace or kubectl patch commands.

kubectl replace command replaces the current ConfigMap with the one defined in a YAML file.

kubectl replace -f updated-configmap.yaml

Use caution as it overrides the existing ConfigMap completely.

kubectl patch command applies changes to a ConfigMap without replacing the entire object. It’s useful for making small modifications or additions.

kubectl patch configmap <configmap_name> -n <namespace> --patch "$(cat patch.yaml)"

Sample patch.yaml file;

cat patch.yaml
data:
  index.html: |
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            body {
                font-family: Arial, sans-serif;
                text-align: center;
                padding: 50px;
            }
            h1 {
                color: #009688;
            }
            p {
                color: #607d8b;
            }
            .container {
                margin-top: 30px;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .kube-logo {
                width: 150px;
                height: 150px;
                margin-right: 20px;
            }
        </style>
    </head>
    <body>
        <h1>Welcome to our Kubernetes Cluster!</h1>
        <p>Our cluster is running smoothly and efficiently.</p>
        <div class="container">
            <img class="kube-logo" src="https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png" alt="Kubernetes Logo">
            <p>Kubernetes orchestrates our applications with ease, ensuring high availability and scalability.</p>
        </div>
        <p>Feel free to explore and innovate!</p>
    </body>
    </html>

Deleting ConfigMaps in Kubernetes

Before deleting a ConfigMap, understand the impact on applications using it. ConfigMaps provide configuration data to Pods, so deleting a ConfigMap without considering its usage can cause application failures or downtime.

Delete a Specific ConfigMap by Name

To delete a specific ConfigMap by its name:

kubectl delete configmap <configmap_name> -n <namespace>

Replace <configmap_name> with the name of the ConfigMap you want to delete and <namespace> with the namespace where the ConfigMap resides.

Delete All ConfigMaps in a Namespace

To delete all ConfigMaps within a namespace, you can use:

kubectl delete configmap --all -n <namespace>

Delete ConfigMaps Using Manifest File

If the ConfigMap was created using a manifest file (yaml or json), you can delete it by applying the same manifest file with the delete action:

kubectl delete -f config-manifest.yaml

Ensure that config-manifest.yaml contains the correct definition of the ConfigMap you want to delete.

Conclusion

ConfigMaps in Kubernetes are essential for managing configuration data separately from application code,, hence providing flexibility in managing containerized environments.

In this blog post, we’ve explored the foundational concepts of ConfigMaps, from creation methods such as literal values, files, to YAML manifests. We’ve also delved into practical usage scenarios, including mounting ConfigMaps as volumes and using them as environment variables within Pods, updating and deleting ConfigMaps.

For further information, check the documentation, Kubernetes ConfigMaps page.

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
Kifarunix
Linux Certified Engineer, with a passion for open-source technology and a strong understanding of Linux systems. With experience in system administration, troubleshooting, and automation, I am skilled in maintaining and optimizing Linux infrastructure.

Leave a Comment