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.
Table of Contents
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:
- 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.
- Configuration files: ConfigMaps can also be mounted as volumes into containers, allowing applications to read configuration files directly from the volume.
- 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;
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.