# Updating Configuration via a ConfigMap

Updating Configuration via a ConfigMapThis page provides a step-by-step example of updating configuration within a Pod via a ConfigMap and builds upon the Configure a Pod to Use a ConfigMap task.At the end of this tutorial, you will understand how to change the configuration for a running application.This tutorial uses the alpine and nginx images as examples.Before you beginYou need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:iximiuz LabsKillercodaKodeKloudPlay with KubernetesYou need to have the curl command-line tool for making HTTP requests from the terminal or command prompt. If you do not have curl available, you can install it. Check the documentation for your local operating system.ObjectivesUpdate configuration via a ConfigMap mounted as a VolumeUpdate environment variables of a Pod via a ConfigMapUpdate configuration via a ConfigMap in a multi-container PodUpdate configuration via a ConfigMap in a Pod possessing a Sidecar ContainerUpdate configuration via a ConfigMap mounted as a VolumeUse the kubectl create configmap command to create a ConfigMap from literal values:kubectl create configmap sport --from-literal=sport=football Below is an example of a Deployment manifest with the ConfigMap sport mounted as a volume into the Pod's only container.deployments/deployment-with-configmap-as-volume.yaml apiVersion: apps/v1 kind: Deployment metadata: name: configmap-volume labels: app.kubernetes.io/name: configmap-volume spec: replicas: 3 selector: matchLabels: app.kubernetes.io/name: configmap-volume template: metadata: labels: app.kubernetes.io/name: configmap-volume spec: containers: - name: alpine image: alpine:3 command: - /bin/sh - -c - while true; do echo "$(date) My preferred sport is $(cat /etc/config/sport)"; sleep 10; done; ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: sportCreate the Deployment:kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-volume.yaml Check the pods for this Deployment to ensure they are ready (matching by selector):kubectl get pods --selector=app.kubernetes.io/name=configmap-volume You should see an output similar to:NAME READY STATUS RESTARTS AGE configmap-volume-6b976dfdcf-qxvbm 1/1 Running 0 72s configmap-volume-6b976dfdcf-skpvm 1/1 Running 0 72s configmap-volume-6b976dfdcf-tbc6r 1/1 Running 0 72s On each node where one of these Pods is running, the kubelet fetches the data for that ConfigMap and translates it to files in a local volume. The kubelet then mounts that volume into the container, as specified in the Pod template. The code running in that container loads the information from the file and uses it to print a report to stdout. You can check this report by viewing the logs for one of the Pods in that Deployment:# Pick one Pod that belongs to the Deployment, and view its logs kubectl logs deployments/configmap-volume You should see an output similar to:Found 3 pods, using pod/configmap-volume-76d9c5678f-x5rgj Thu Jan 4 14:06:46 UTC 2024 My preferred sport is football Thu Jan 4 14:06:56 UTC 2024 My preferred sport is football Thu Jan 4 14:07:06 UTC 2024 My preferred sport is football Thu Jan 4 14:07:16 UTC 2024 My preferred sport is football Thu Jan 4 14:07:26 UTC 2024 My preferred sport is football Edit the ConfigMap:kubectl edit configmap sport In the editor that appears, change the value of key sport from football to cricket. Save your changes. The kubectl tool updates the ConfigMap accordingly (if you see an error, try again).Here's an example of how that manifest could look after you edit it:apiVersion: v1 data: sport: cricket kind: ConfigMap # You can leave the existing metadata as they are. # The values you'll see won't exactly match these. metadata: creationTimestamp: "2024-01-04T14:05:06Z" name: sport namespace: default resourceVersion: "1743935" uid: 024ee001-fe72-487e-872e-34d6464a8a23 You should see the following output:configmap/sport edited Tail (follow the latest entries in) the logs of one of the pods that belongs to this Deployment:kubectl logs deployments/configmap-volume --follow After few seconds, you should see the log output change as follows:Thu Jan 4 14:11:36 UTC 2024 My preferred sport is football Thu Jan 4 14:11:46 UTC 2024 My preferred sport is football Thu Jan 4 14:11:56 UTC 2024 My preferred sport is football Thu Jan 4 14:12:06 UTC 2024 My preferred sport is cricket Thu Jan 4 14:12:16 UTC 2024 My preferred sport is cricket When you have a ConfigMap that is mapped into a running Pod using either a configMap volume or a projected volume, and you update that ConfigMap, the running Pod sees the update almost immediately.However, your application only sees the change if it is written to either poll for changes, or watch for file updates.An application that loads its configuration once at startup will not notice a change.Note:The total delay from the moment when the ConfigMap is updated to the moment when new keys are projected to the Pod can be as long as kubelet sync period.Also check Mounted ConfigMaps are updated automatically.Update environment variables of a Pod via a ConfigMapUse the kubectl create configmap command to create a ConfigMap from literal values:kubectl create configmap fruits --from-literal=fruits=apples Below is an example of a Deployment manifest with an environment variable configured via the ConfigMap fruits.deployments/deployment-with-configmap-as-envvar.yaml apiVersion: apps/v1 kind: Deployment metadata: name: configmap-env-var labels: app.kubernetes.io/name: configmap-env-var spec: replicas: 3 selector: matchLabels: app.kubernetes.io/name: configmap-env-var template: metadata: labels: app.kubernetes.io/name: configmap-env-var spec: containers: - name: alpine image: alpine:3 env: - name: FRUITS valueFrom: configMapKeyRef: key: fruits name: fruits command: - /bin/sh - -c - while true; do echo "$(date) The basket is full of $FRUITS"; sleep 10; done; ports: - containerPort: 80Create the Deployment:kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-envvar.yaml Check the pods for this Deployment to ensure they are ready (matching by selector):kubectl get pods --selector=app.kubernetes.io/name=configmap-env-var You should see an output similar to:NAME READY STATUS RESTARTS AGE configmap-env-var-59cfc64f7d-74d7z 1/1 Running 0 46s configmap-env-var-59cfc64f7d-c4wmj 1/1 Running 0 46s configmap-env-var-59cfc64f7d-dpr98 1/1 Running 0 46s The key-value pair in the ConfigMap is configured as an environment variable in the container of the Pod. Check this by viewing the logs of one Pod that belongs to the Deployment.kubectl logs deployment/configmap-env-var You should see an output similar to:Found 3 pods, using pod/configmap-env-var-7c994f7769-l74nq Thu Jan 4 16:07:06 UTC 2024 The basket is full of apples Thu Jan 4 16:07:16 UTC 2024 The basket is full of apples Thu Jan 4 16:07:26 UTC 2024 The basket is full of apples Edit the ConfigMap:kubectl edit configmap fruits In the editor that appears, change the value of key fruits from apples to mangoes. Save your changes. The kubectl tool updates the ConfigMap accordingly (if you see an error, try again).Here's an example of how that manifest could look after you edit it:apiVersion: v1 data: fruits: mangoes kind: ConfigMap # You can leave the existing metadata as they are. # The values you'll see won't exactly match these. metadata: creationTimestamp: "2024-01-04T16:04:19Z" name: fruits namespace: default resourceVersion: "1749472" You should see the following output:configmap/fruits edited Tail the logs of the Deployment and observe the output for few seconds:# As the text explains, the output does NOT change kubectl logs deployments/configmap-env-var --follow Notice that the output remains unchanged, even though you edited the ConfigMap:Thu Jan 4 16:12:56 UTC 2024 The basket is full of apples Thu Jan 4 16:13:06 UTC 2024 The basket is full of apples Thu Jan 4 16:13:16 UTC 2024 The basket is full of apples Thu Jan 4 16:13:26 UTC 2024 The basket is full of apples Note:Although the value of the key inside the ConfigMap has changed, the environment variable in the Pod still shows the earlier value. This is because environment variables for a process running inside a Pod are not updated when the source data changes; if you wanted to force an update, you would need to have Kubernetes replace your existing Pods. The new Pods would then run with the updated information.You can trigger that replacement. Perform a rollout for the Deployment, using kubectl rollout:# Trigger the rollout kubectl rollout restart deployment configmap-env-var # Wait for the rollout to complete kubectl rollout status deployment configmap-env-var --watch=true