πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Configuration intermediate ⏱ 10 minutes K8s 1.28+

K8s ConfigMap Hot Reload Without Restart

Reload Kubernetes ConfigMaps without pod restarts. Volume-mounted auto-update, Reloader controller, checksum annotations.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: ConfigMaps mounted as volumes auto-update in pods (within 30-60 seconds) without restarts. ConfigMaps used as environment variables do NOT update β€” pods must be restarted. Use Reloader to trigger rolling restarts automatically when ConfigMaps change.

The Problem

You update a ConfigMap but your pods still use the old config. The behavior depends on how you consume the ConfigMap:

flowchart TB
    CM["ConfigMap Updated"] --> VOL{"How is it consumed?"}
    VOL -->|"Volume mount"| AUTO["Auto-updated<br/>in 30-60 seconds βœ…"]
    VOL -->|"envFrom / env"| STUCK["NOT updated ❌<br/>Pod restart required"]
    VOL -->|"subPath mount"| STUCK2["NOT updated ❌<br/>subPath never refreshes"]

The Solution

Method 1: Volume Mount (Automatic Refresh)

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  config.yaml: |
    log_level: info
    max_connections: 100
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: myapp:v1.0
          volumeMounts:
            - name: config
              mountPath: /etc/config    # βœ… Auto-updates!
              # Do NOT use subPath β€” it disables auto-update
      volumes:
        - name: config
          configMap:
            name: app-config
# Update ConfigMap
kubectl edit configmap app-config
# Change log_level: info β†’ log_level: debug

# Wait ~60 seconds, then verify
kubectl exec my-app-xxx -- cat /etc/config/config.yaml
# log_level: debug    ← Updated automatically!

Important: Your application must watch the file for changes (inotify, polling, or SIGHUP).

Method 2: Reloader Controller (Automatic Restart)

Stakater Reloader watches ConfigMaps/Secrets and triggers rolling restarts:

# Install Reloader
helm repo add stakater https://stakater.github.io/stakater-charts
helm install reloader stakater/reloader -n kube-system
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    reloader.stakater.com/auto: "true"    # ← Watch ALL referenced ConfigMaps/Secrets
spec:
  template:
    spec:
      containers:
        - name: app
          envFrom:
            - configMapRef:
                name: app-config          # Reloader restarts on change

Or watch specific ConfigMaps:

metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "app-config,feature-flags"
    secret.reloader.stakater.com/reload: "db-credentials"

Method 3: Checksum Annotation (Native Kubernetes)

Force rolling update when ConfigMap changes β€” no extra controller needed:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      annotations:
        # Update this hash when ConfigMap changes
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

In CI/CD without Helm:

# Compute hash and patch deployment
HASH=$(kubectl get configmap app-config -o jsonpath='{.data}' | sha256sum | cut -d' ' -f1)
kubectl patch deployment my-app -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"checksum/config\":\"$HASH\"}}}}}"

Method 4: Application-Level File Watching

Make your app react to config file changes:

# Python with watchdog
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class ConfigHandler(FileSystemEventHandler):
    def on_modified(self, event):
        if event.src_path.endswith("config.yaml"):
            print("Config changed, reloading...")
            reload_config()

observer = Observer()
observer.schedule(ConfigHandler(), "/etc/config", recursive=False)
observer.start()
// Go with fsnotify
watcher, _ := fsnotify.NewWatcher()
watcher.Add("/etc/config")

for event := range watcher.Events {
    if event.Op&fsnotify.Write == fsnotify.Write {
        log.Println("Config modified, reloading...")
        reloadConfig()
    }
}

⚠️ subPath Disables Auto-Update

# ❌ subPath β€” NEVER auto-updates
volumeMounts:
  - name: config
    mountPath: /etc/config/config.yaml
    subPath: config.yaml               # This BREAKS auto-update!

# βœ… Directory mount β€” auto-updates
volumeMounts:
  - name: config
    mountPath: /etc/config              # Whole directory, auto-updates

Comparison

MethodAuto?Restart?DelayComplexity
Volume mountβœ…No30-60sApp must watch files
Reloaderβœ…Rolling restart~secondsInstall controller
Checksum annotationManualRolling restartImmediateCI/CD integration
Environment vars❌Manual restartN/ASimplest

Common Issues

IssueCauseFix
Volume not updatingUsing `subPath`Remove subPath, mount whole directory
Env vars not updatingEnv vars never hot-reloadUse Reloader or restart pods
Long update delayKubelet sync periodDefault 60s β€” configurable but not recommended to lower
App not picking up changesApp doesn’t watch filesAdd file watcher or use SIGHUP pattern
Symlink confusionConfigMap uses symlinks internallyRead the file, not the symlink

Best Practices

  • Prefer volume mounts over env vars when hot-reload is needed
  • Never use subPath if you need auto-update
  • Install Reloader for env-var-based configs β€” simple, reliable
  • Add file watching in your application β€” most production apps support SIGHUP
  • Test config changes in staging β€” malformed config can crash apps

Key Takeaways

  • Volume-mounted ConfigMaps auto-update in 30-60 seconds β€” no restart needed
  • Environment variables from ConfigMaps NEVER auto-update β€” restart required
  • `subPath` mounts NEVER auto-update β€” avoid for dynamic configs
  • Reloader controller triggers rolling restarts on ConfigMap/Secret changes
  • Checksum annotations in Helm force restart on config changes natively
  • Your app must actively watch config files to use hot-reload
#configmap #hot-reload #configuration #reloader #rolling-update
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens