In a previous post, you learned about node selectors and node affinity in Kubernetes. In this post, we will discuss the ConfigMap resource that allows you to store data as a dictionary (using key–value pairs) outside of your containerization applications. It offers a means of storing configuration information, environment variables, command-line arguments, or other configuration data that Pods or other Kubernetes objects can use during their execution. This approach makes your applications more portable, flexible, and easier to maintain since the configuration settings are stored and maintained independently of specific Pods.

Defining a ConfigMap

You can create a ConfigMap using either an imperative or a declarative approach.

Imperative definition

The imperative command for creating a ConfigMap is shown below:

kubectl create configmap <config-map-name> <data-source>

The <data-source> can be a file, directory, or literal string. When you want to pass the key–value pairs as literal strings in the command line itself, you need to use the --from-literal option:

kubectl create configmap my-config-map --from-literal=DB_HOST=localhost

This ConfigMap object contains a single key–value pair. The key is DBHOST, and the value is localhost.

Alternatively, you could use the --from-file option to specify a file or directory. Assume we have key–value pairs stored in a text file named db-config.txt, as shown below:

DB_HOST: "mysql101.testlab.local"
DB_PORT: "3306"
In this case, you can use the following imperative command to create a ConfigMap using the _--from-file_ option:
kubectl create configmap myConfigMap --from-file=db-config.txt

However, you can also create a ConfigMap without defining a key–value pair in the file. In this case, the filename is automatically chosen as the key, and the file's content is chosen as the value in the ConfigMap. Here is an example:

kubectl create configmap my-configmap --from-file=DB_HOST –from-file=DB_PORT

This command creates a ConfigMap object named my-configmap. The ConfigMap object contains two key–value pairs. The first key is DBHOST, and the value (mysql101.testlab.local) is the content of the file named DB_HOST. The second key is DBPORT, and the value is the content of the file named DB_PORT (3306).

Declarative definition

A declarative definition means that we use a YAML file to create the ConfigMap. Here is an example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: db-configmap
data:
  DB_HOST: "mysql101.testlab.local"
  DB_PORT: "3306"
Create a simple ConfigMap in Kubernetes

Create a simple ConfigMap in Kubernetes

The screenshot shows a db-configmap.yaml file, where you can see that a ConfigMap has an apiVersion, kind, and metadata similar to other Kubernetes objects we have discussed so far. But there is a new data field instead of spec. The data field is where you define the key–value pairs for the ConfigMap. In this case, I defined the DB_HOST and DB_PORT environment variables.

If you want to store the binary data in the ConfigMap, such as a base64-encoded TLS certificate, you can use a binaryData field instead. You can use both the data and binaryData fields in the same ConfigMap, but the keys should not overlap.

Furthermore, you can use a ConfigMap object to define any configuration file on the fly, as shown below:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configmap
data:
  index.html: |
    <html>
    <h1>This page is generated by the nginx-configmap</h1>
    </html>
Create a static file on the fly with ConfigMap in Kubernetes

Create a static file on the fly with ConfigMap in Kubernetes

This YAML file creates a ConfigMap object named nginx-configmap. The ConfigMap object contains a single key–value pair. The key is index.html, and the value is a multiline string that contains an HTML snippet. The pipe character (|) is needed here to define the multiline string.

This ConfigMap essentially defines a static index.html file that will be served by the nginx container.

To apply the declarative configuration of the last example, you have to execute the following command:

kubectl apply -f nginx-configmap.yaml

This command creates an nginx-configmap for us. To view the ConfigMap, you can use the kubectl get or kubectl describe commands, as shown below:

kubectl get configmap <config-map-name>
kubectl describe cm <config-map-name>
View a ConfigMap in Kubernetes

View a ConfigMap in Kubernetes

The describe command shows detailed information of a ConfigMap, including the Data and BinaryData section. Since we didn't specify any binary data, the relevant section is empty.

Using ConfigMap in a Pod

To use a ConfigMap in a Pod, both need to be in the same Kubernetes namespace. Namespaces are a way of isolating Kubernetes resources within a single cluster. Before you create a Pod that consumes a ConfigMap, ensure that the referenced ConfigMap has already been created. Two common ways to use a ConfigMap in Kubernetes are through environment variables and volume mounts.

Environment variables

You can inject data from a ConfigMap in the form of environment variables inside the Pods or containers. This method allows you to pass application-specific configuration settings, such as database hosts or API endpoints, needed by your containerized applications.

First, create a ConfigMap named db-configmap using the YAML from the previous section:

apiVersion: v1
kind: ConfigMap
metadata:
  name: db-configmap
data:
  DB_HOST: "mysql101.testlab.local"
  DB_PORT: "3306"

Next, create the ConfigMap:

kubectl apply -f db-configmap.yaml

Then, take a look at the ConfigMap:

kubectl describe cm db-configmap
Create and view a ConfigMap in Kubernetes

Create and view a ConfigMap in Kubernetes

You can see that db-configmap has been created with the DBHOST and DBPORT keys.

Now, let's create a Pod with the help of this configuration file:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
      envFrom:
        - configMapRef:
            name: db-configmap 
		optional: false
Pod configuration file to inject environment variables from a ConfigMap in Kubernetes

Pod configuration file to inject environment variables from a ConfigMap in Kubernetes

Here, I defined a Pod with a single container called nginx-container. The envFrom keyword essentially allows us to inject environment variables into a container from a ConfigMap.

I then used configMapRef to reference our ConfigMap by its name (db-configmap), so that all the key–value pairs become accessible to the container.

Notice that the optional flag is currently set to false (default). This means a Pod will fail to run if the referenced ConfigMap doesn't exist. If you want your Pod to run without ConfigMap, you can set the optional flag to true.

Now, let's create the Pod and see if we can find the environment variables that are defined in the ConfigMap.

kubectl apply -f nginx-pod.yaml
kubectl exec nginx-pod -it -- printenv
Create a Pod and view the environment variables in Kubernetes

Create a Pod and view the environment variables in Kubernetes

The kubectl exec command allowed us to run the printenv command in the Pod to list the environment variables. Here, we can see the DB_HOST and DB_PORT environment variables that we injected using a ConfigMap. Running the kubectl describe command also shows that the environment variables are loaded from a ConfigMap.

Run the kubectl describe command on a Pod

Run the kubectl describe command on a Pod

Volume mounts

Another way of using ConfigMaps with a Pod is through volume mounts. Doing so allows you to keep your configuration data separate from the container image and makes it easier to update the configuration when necessary without modifying the Pod specification or the application code.

To understand how to use a ConfigMap as a volume mount, we use a ConfigMap named nginx-configmap, which we discussed above:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configmap
data:
  index.html: |
    <html>
    <h1>This page is generated by the nginx-configmap</h1>
    </html>

Next, we create the ConfigMap:

kubectl apply -f nginx-configmap.yaml

Take a look at the Pod configuration below:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  volumes:
    - name: nginx-config-vol
      configMap:
        name: nginx-configmap
  containers:
    - name: nginx-container
      image: nginx
      volumeMounts:
        - name: nginx-config-vol
          mountPath: /usr/share/nginx/html

Here, I defined a Pod with a single container named nginx-pod, and a volume that is sourced from the ConfigMap named nginx-configmap, which contains a static HTML file to be served by the nginx web server.

Under the container, I mounted the volume at /usr/share/nginx/html with the mountPath keyword. In a nutshell, we mounted the ConfigMap as a volume that contains a static HTML file created by the ngnix-configmap.

Now, we apply our configuration:

kubectl apply -f nginx-pod.yaml

The next command retrieves information about the pods in the Kubernetes cluster, including data such as the nodes where the pods are running and their IP addresses.

kubectl get pods -o wide

With the help of the curl command, we test whether our static index.html file is served by the nginx container:

curl  http://<pod-ip-address>
Create a Pod and verify the nginx response

Create a Pod and verify the nginx response

If you run the kubectl describe command on the new Pod, you will notice a volume that is populated by the ConfigMap and the mounted path under the container itself.

Subscribe to 4sysops newsletter!

Running the kubectl describe command to view detailed information about a Pod

Running the kubectl describe command to view detailed information about a Pod

Conclusion

You just learned how to create and use a ConfigMap in Kubernetes. Note that I demonstrated the use of ConfigMap in Pods just to keep things simple. However, in a production environment, you can apply the same idea of using ConfigMaps with Kubernetes Deployments. Remember that ConfigMaps store your data in clear text, so it is not intended for storing sensitive information such as passwords or tokens. To store such sensitive information, you need to use Secrets in Kubernetes. Furthermore, ConfigMaps are not meant to store settings that are larger than 1 MB. If you intend to store configuration settings larger than 1 MB, you might need to use some alternate option, such as a database or a persistent volume.

0 Comments

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account