- Kubernetes logs: Pod logs, container logs, Docker logs, kubelet logs, and master node logs - Mon, Sep 25 2023
- Kubernetes DaemonSets - Wed, Sep 6 2023
- Static Pods in Kubernetes - Fri, Sep 1 2023
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"
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>
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>
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
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
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
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.
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>
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!
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.