Skip to content

Commit 1be5b10

Browse files
authored
Merge pull request #7098 from layer5io/leecalcote/blog/configmaps
Blog: k8s configmaps
2 parents 944056f + 8f7cec1 commit 1be5b10

File tree

3 files changed

+184
-1
lines changed

3 files changed

+184
-1
lines changed
293 KB
Loading
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
title: "How can you tell what kind of Kubernetes Configmap you have?"
3+
subtitle: "Understanding when changes are reloaded"
4+
date: 2025-11-03 10:30:05 -0530
5+
author: Lee Calcote
6+
thumbnail: ./image.png
7+
darkthumbnail: ./image.png
8+
category: "Kubernetes"
9+
tags:
10+
- devops
11+
- kubernetes
12+
type: Blog
13+
resource: true
14+
published: true
15+
---
16+
17+
import { BlogWrapper } from "../../Blog.style.js";
18+
import { Link } from "gatsby";
19+
20+
<BlogWrapper>
21+
22+
A common point of confusion when working with Kubernetes is understanding how `ConfigMap` updates are handled. You’ve pushed a change to your ConfigMap, but your application isn't seeing the new values. What's going on?
23+
24+
The answer depends entirely on **how your application consumes the ConfigMap**. There isn't a "type" of ConfigMap object itself, but rather two distinct *methods of consumption* by a Pod, and each has drastically different behavior regarding updates.
25+
26+
To tell what "kind" you have, you need to look at your Pod or Deployment's YAML definition.
27+
28+
## How to Check Your Pod's ConfigMap Consumption
29+
30+
You can find out how a Pod is using a ConfigMap by inspecting its YAML definition. 🧐 Run this command to get the running YAML for a specific pod:
31+
32+
```bash
33+
kubectl get pod <your-pod-name> -o yaml
34+
```
35+
36+
Now, look for two key sections in the `spec.containers` list:
37+
38+
1. **Environment Variables:** Look for `env` or `envFrom`.
39+
2. **Mounted Volumes:** Look for `volumeMounts` and the corresponding `volumes` section at the Pod spec level.
40+
41+
Let's break down what each one means for reloading.
42+
43+
## 1. Consumed as Environment Variables
44+
45+
This is when your Pod's YAML injects ConfigMap data directly as environment variables for the container.
46+
47+
### How to Identify It
48+
49+
In your Pod spec, you'll see blocks like this:
50+
51+
```yaml
52+
# ...
53+
spec:
54+
containers:
55+
- name: my-app-container
56+
image: my-app
57+
env: # <-- Look here
58+
- name: MY_CONFIG_KEY
59+
valueFrom: # <-- Or here
60+
configMapKeyRef:
61+
name: my-special-config
62+
key: some.config.key
63+
envFrom: # <-- Or here
64+
- configMapRef:
65+
name: my-special-config
66+
# ...
67+
```
68+
69+
If you see `env` or `envFrom` pointing to a `configMapKeyRef` or `configMapRef`, your application is consuming the ConfigMap as environment variables.
70+
71+
### Reload Behavior: 🛑 No Hot-Reload
72+
73+
This is the most critical difference: **Changes to a ConfigMap are NOT reflected in running Pods that use them as environment variables.**
74+
75+
Environment variables are set by the container runtime *only when the container is created*. They are immutable for the life of that running process.
76+
77+
**How to Apply Changes:** To make the application see the new ConfigMap values, you **must restart the Pod**. The simplest way to do this for a `Deployment` is with a rolling restart:
78+
79+
```bash
80+
kubectl rollout restart deployment <your-deployment-name>
81+
```
82+
83+
When the new Pods are created, they will read the *updated* ConfigMap data and set the new environment variables.
84+
85+
86+
## 2. Consumed as a Mounted Volume
87+
88+
This method mounts your ConfigMap as one or more files inside your Pod's filesystem. Your application is programmed to read its configuration from these files (e.g., `/app/config/settings.properties`).
89+
90+
### How to Identify It
91+
92+
You'll see two corresponding sections in your Pod spec:
93+
94+
1. `spec.containers.volumeMounts`: This tells the container where to mount the volume.
95+
2. `spec.volumes`: This defines the volume itself and links it to the ConfigMap.
96+
97+
98+
```yaml
99+
# ...
100+
spec:
101+
containers:
102+
- name: my-app-container
103+
image: my-app
104+
volumeMounts: # <-- Look here
105+
- name: config-volume
106+
mountPath: /etc/config
107+
volumes: # <-- And here
108+
- name: config-volume
109+
configMap:
110+
name: my-special-config
111+
# ...
112+
```
113+
114+
If you see this `volumes` and `volumeMounts` pairing, your application is consuming the ConfigMap as files.
115+
116+
### Reload Behavior: ✅ Automatic... With a Catch
117+
118+
This method **does support hot-reloading**, but with two important caveats:
119+
120+
1. **There is a delay.** When you update the ConfigMap object, the `kubelet` on the node is responsible for updating the mounted files. This is not instantaneous. It relies on a periodic sync cycle, and the total delay can be **60 to 90 seconds (or even longer)** before the files at `mountPath` are actually updated.
121+
122+
2. **Your application must support it.** Kubernetes *only* updates the files on disk. It does **not** send a signal (like `SIGHUP`) to the process or restart the container. Your application must be built to:
123+
124+
* Watch the configuration files for changes (using a library like `fsnotify`).
125+
* Periodically re-read the configuration files on its own timer.
126+
127+
If your application only reads its config files on startup, it will behave just like the environment variable method: **it will not see the changes until it is restarted.**
128+
129+
130+
## ConfigMap Reload Behavior Summary
131+
132+
Here’s a simple table to remember the differences:
133+
134+
| Consumption Method | How to Identify in Pod YAML | Are Changes Updated in Running Pod? | How Are Changes Seen? |
135+
| :--- | :--- | :--- | :--- |
136+
| **Environment Variables** | `spec.containers.env` `spec.containers.envFrom` | **No**| Pod must be **restarted**. |
137+
| **Mounted Volume** | `spec.containers.volumeMounts` `spec.volumes` | **Yes** ✅ (with delay) | Kubelet updates files. **Application must be coded** to reload the updated file. |
138+
139+
### What If I Need Automatic Restarts?
140+
141+
If you are using the volume mount method but your application doesn't support live reloading, you can use a "reloader" tool. A popular open-source controller like [**Stakater's Reloader**](https://github.com/stakater/Reloader) can watch for ConfigMap changes and automatically trigger a rolling restart of any Deployment that uses it. This gives you the best of both worlds: configuration in files and automatic updates for apps that can't reload on their own.
142+
143+
<br />
144+
<hr />
145+
<br />
146+
147+
## Skip the CLI. Power up with Kanvas
148+
149+
Alternatively, you can skip the YAML editing and make these changes visually. That is, if you're managing your Kubernetes cluster using Kanvas. Let's break down how to use it to manage your resources, like a `ConfigMap`.
150+
151+
## 🤔 What is Kanvas Designer?
152+
153+
[Layer5's Kanvas](https://layer5.io/kanvas) is a powerful tool for designing, deploying, and managing your Kubernetes and Cloud infrastructure and workloads from a visual interface. Instead of writing hundreds of lines of YAML by hand, you build a **Design**. This design is a visual representation of your components (`Deployment`, `Service`, `ConfigMap`, etc.) and their relationships.
154+
155+
## 🎨 How to Update a ConfigMap in Kanvas Designer
156+
157+
Updating a `ConfigMap` through the Designer follows this "design-first" workflow. You don't just "edit" the live resource in the cluster; you **update your design** and then **(re-)deploy it**.
158+
159+
Here is the step-by-step process:
160+
161+
1. **Open Kanvas Designer:** Log in to your Kanvas UI and navigate to Designer mode (the default mode).
162+
163+
2. **Load Your Design:** Open the design file that contains the `ConfigMap` you want to edit. If you don't have a design yet, you can import your existing `ConfigMap` from your cluster directly onto the canvas.
164+
165+
3. **Find the ConfigMap Component:** On the visual canvas, find the block representing your `ConfigMap`. It will have the Kubernetes icon and the "ConfigMap" kind.
166+
167+
4. **Edit the Configuration:** Click on the component. A configuration panel will slide out, often with a 'Configure' tab or an editor icon. This will show you the key/value pairs for that *specific* `ConfigMap` resource.
168+
169+
5. **Deploy the Design:** Changes are automatically saved in your design as you make them. Use the **Deploy** button to send your entire design to your target Kubernetes or Cloud environment. Kanvas will calculate the difference (a "diff") and apply the updated `ConfigMap` manifest to your cluster. This action is the equivalent of running `kubectl` server-side apply using your design.
170+
171+
172+
## 🛑 The Most Important Part: Reload Behavior
173+
174+
This is critical: **Using Kanvas Designer to update a ConfigMap does NOT change how your application reloads it.**
175+
176+
Deploying from Kanvas is just a friendly, visual way to run `kubectl apply`. The rules we discussed in our previous post about ConfigMap behavior still apply completely:
177+
178+
* **If your Pod consumes the ConfigMap as Environment Variables:** Your running Pods **will not** see the change. You must still restart them (e.g., `kubectl rollout restart deployment ...`).
179+
* **If your Pod consumes the ConfigMap as a Mounted Volume:** The files inside the Pod **will** be updated (after the kubelet sync delay), but your application *still* needs to be smart enough to re-read that file from disk.
180+
181+
Kanvas Designer simplifies the *applying* of the change and helps you visually manage your application's state, but it doesn't change the fundamental Kubernetes behavior of *how* that change is consumed by your workloads.
182+
183+
</BlogWrapper>

src/sections/Projects/Sistent/components/icons/guidance.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import { navigate } from "gatsby";
33
import { useLocation } from "@reach/router";
44
import { Row } from "../../../../../reusecore/Layout";
5-
import { SistentThemeProvider, KubernetesIcon, DesignIcon, PublishIcon } from "@sistent/sistent";
5+
import { SistentThemeProvider } from "@sistent/sistent";
66
import { SistentLayout } from "../../sistent-layout";
77
import TabButton from "../../../../../reusecore/Button";
88
import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode";

0 commit comments

Comments
 (0)