What is ConfigMap in Kubernetes
A ConfigMap is a dictionary of configuration settings. This dictionary can contain settings for a single pod, multiple pods, or even the entire cluster, depending on what level it is applied. ConfigMaps are useful for storing and sharing non-sensitive, plain configuration data.
Comparison with Direct Environment Variable Definition
Although it's possible to define environment variables directly within Pod or Deployment manifests, this approach has limitations. For instance, any changes to these variables would require editing the manifest files and potentially redeploying the application. Moreover, the reuse of these variables across different applications or environments is not straightforward.
Benefits of Using ConfigMap
ConfigMaps offer several benefits over defining environment variables directly within manifests. Firstly, they allow you to manage application configuration outside of your Pod templates, improving reuse and reducing complexity. Secondly, ConfigMaps are dynamic, meaning you can modify them without needing to restart the Pods or redeploy the applications that use them. Lastly, they allow for greater separation of configuration from the application code, following the twelve-factor application principles.
Launching Minikube
Minikube is a convenient tool that allows you to run a single-node Kubernetes cluster on your local machine. This can be particularly useful for testing and development purposes.
To start Minikube, you simply need to use the minikube start
command:
$ minikube start
This command will initialize a new virtual machine on your computer, and will install a single-node Kubernetes cluster inside this VM. After executing this command, you can use the kubectl
command line tool to interact with the cluster.
Defining Environment Variables without ConfigMap
Before introducing ConfigMaps, it's important to understand how we would traditionally define environment variables within our Kubernetes resources.
Command to Generate YAML with Environment Variable
Let's say we want to create a new Pod with an environment variable TEST_ENV
set to Hello_World
. We would typically run the kubectl run
command with the --env
option to do this:
$ kubectl run \
--env TEST_ENV=Hello_World \
--port 8080 \
--image bhargavshah86/kube-test:v0.1 \
--restart Never \
--dry-run \
-o yaml \
helloworld > pod_env.yaml
This command generates a YAML configuration for the Pod and saves it to a file named pod_env.yaml
.
Understanding the Generated YAML Structure
If you open the pod_env.yaml
file, you'll see a section where the TEST_ENV
environment variable is defined:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld
name: helloworld
spec:
containers:
- env:
- name: TEST_ENV
value: Hello_World
image: bhargavshah86/kube-test:v0.1
name: helloworld
ports:
- containerPort: 8080
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
Under the spec.containers.env
field, you can see the TEST_ENV
environment variable with the assigned value Hello_World
. This is how Kubernetes directly defines environment variables in a Pod without using a ConfigMap.
Transition to Using ConfigMap for Environment Variables
Although environment variables can be defined directly within Pod manifests, it's more flexible and reusable to manage them through ConfigMap.
Definition of ConfigMap in YAML
The first step in using ConfigMap is to define it. For this, you can use the kubectl create configmap command with the --from-literal
option to define the ConfigMap in YAML format:
$ kubectl create configmap my-config \
--from-literal=TEST_ENV=Hello_World \
--dry-run \
-o yaml > configmap.yaml
This command will create a ConfigMap named my-config
and store the environment variable TEST_ENV
with the value Hello_World
.
Understanding ConfigMap YAML Structure
If you open the configmap.yaml
file, you'll see the ConfigMap structure:
apiVersion: v1
data:
TEST_ENV: Hello_World
kind: ConfigMap
metadata:
creationTimestamp: null
name: my-config
Here, under the data field, the key-value pair for TEST_ENV
is stored.
Creating ConfigMap from YAML
Once the ConfigMap is defined in a YAML file, you can create the ConfigMap in your Kubernetes cluster with the kubectl apply
command:
$ kubectl apply -f configmap.yaml
configmap/my-config created
To verify the creation, list all the ConfigMaps:
$ kubectl get configmap
NAME DATA AGE
kube-root-ca.crt 1 4m9s
my-config 1 5s
Checking the ConfigMap Details
You can describe the ConfigMap to see its details:
$ kubectl describe configmap my-config
Name: my-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
TEST_ENV:
----
Hello_World
BinaryData
====
Events: <none>
Defining Environment Variables in Pod Manifest with ConfigMap Reference
In the Pod manifest, you can refer to the ConfigMap for defining the environment variable:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld-configmap-env
name: helloworld-configmap-env
spec:
containers:
- env:
- name: TEST_ENV
valueFrom:
configMapKeyRef:
name: my-config
key: TEST_ENV
image: bhargavshah86/kube-test:v0.1
name: helloworld-configmap-env
ports:
- containerPort: 8080
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
After defining the Pod manifest with the ConfigMap reference, create the Pod:
$ kubectl apply -f pod_configmap_env.yaml
You can then verify that the environment variable within the Pod is correctly set:
$ kubectl exec -it helloworld-configmap-env env
HOME=/root
PKG_RELEASE=1
NJS_VERSION=0.3.1
NGINX_VERSION=1.16.0
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.96.0.1
TEST_ENV=Hello_World
TERM=xterm
HOSTNAME=helloworld-configmap-env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
This command will print all the environment variables, and you should see TEST_ENV=Hello_World
amongst the output.
Mounting ConfigMap as Volume in the Container
In addition to being used for setting environment variables, ConfigMap can also be used to store data that is then mounted as a volume in a container. This can be useful for configuration files, secrets, and other data that needs to be accessible within a container.
Overview of ConfigMap Volume Mounting
The data stored in a ConfigMap can be written to files and then mounted as a volume within a Pod. This is useful when you need to share non-sensitive data between containers.
Defining ConfigMap as Volume in Pod Manifest
To use a ConfigMap as a volume, you need to reference the ConfigMap in the volumes
section of the Pod manifest and specify where to mount the volume in the volumeMounts
section:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld-configmap-volume
name: helloworld-configmap-volume
spec:
containers:
- image: bhargavshah86/kube-test:v0.1
name: helloworld-configmap-volume
ports:
- containerPort: 8080
resources: {}
volumeMounts:
- name: my-config-volume
mountPath: /my-config/TEST_ENV
volumes:
- name: my-config-volume
configMap:
name: my-config
items:
- key: TEST_ENV
path: keys
status: {}
In this example, the ConfigMap named my-config
is used as a volume named my-config-volume
and is mounted at the path /my-config/TEST_ENV
in the container.
Creating and Verifying the Pod with ConfigMap Volume
After defining the Pod manifest with the ConfigMap volume, create the Pod:
$ kubectl apply -f pod_configmap_volume.yaml
You can then verify that the volume has been correctly mounted by executing a shell within the Pod and checking the file system:
$ kubectl exec -it helloworld-configmap-volume sh
Once you're inside the Pod's shell, navigate to the mounted directory and verify that the TEST_ENV
key from the ConfigMap has been written to a file:
/usr/share/nginx/html # cat /my-config/TEST_ENV/keys
Hello_World
This will show the contents of the keys file, which should be Hello_World
, the value associated with the TEST_ENV
key in the my-config
ConfigMap.