2022-06-29

Kubernetes ConfigMap

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:

bash
$ 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:

bash
$ 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:

bash
$ 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:

configmap.yaml
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:

bash
$ kubectl apply -f configmap.yaml

configmap/my-config created

To verify the creation, list all the ConfigMaps:

bash
$ 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:

bash
$ 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:

pod_configmap_env.yaml
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:

bash
$ kubectl apply -f pod_configmap_env.yaml

You can then verify that the environment variable within the Pod is correctly set:

bash
$ 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:

pod_configmap_volume.yaml
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:

bash
$ 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:

bash
$ 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:

bash
/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.

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!