When you update a ConfigMap or Secret in Kubernetes, running pods don’t automatically pick up the changes unless the application explicitly re-reads the files or the pod is restarted. This is one of the most common pain points for Kubernetes administrators managing configuration-driven workloads. Manual pod restarts work for a handful of deployments, but they don’t scale across dozens of microservices. That’s where ConfigMap auto-reload tools come in — Kubernetes controllers that watch for configuration changes and trigger rolling updates automatically.

In this guide, we compare three popular solutions for automatic pod restarts when ConfigMaps or Secrets change: Stakater Reloader (the most widely adopted), configmap-reloader (a lightweight alternative), and Kubernetes ConfigMap Watcher (a custom controller approach). We’ll cover deployment options, feature comparisons, and provide ready-to-use Docker Compose and Kubernetes manifests.

Understanding ConfigMap Reload in Kubernetes

Kubernetes mounts ConfigMaps and Secrets into pods as files or environment variables. When the underlying ConfigMap changes:

  • Environment variables: Pods never receive updated values — a restart is required
  • File mounts: Pods see the updated files within seconds (Kubernetes syncs projected volumes), but the running application may not re-read them without a restart

This means any configuration change that needs to propagate to running services requires a pod restart. Doing this manually is error-prone and slow. Auto-reload tools solve this by watching the Kubernetes API for ConfigMap/Secret changes and automatically annotating the associated Deployments, StatefulSets, or DaemonSets to trigger a rolling restart.

Comparison: ConfigMap Auto-Reload Tools

FeatureStakater Reloaderconfigmap-reloaderK8s ConfigMap Watcher
GitHub Stars10,000+500+Community projects
Last UpdatedActive (2026)ActiveVaries by project
Watch ConfigMapsYesYesYes
Watch SecretsYesYesConfigMaps only
Rolling RestartYes (annotation-based)Yes (sidecar restart)Custom logic
Deployment TypeKubernetes ControllerSidecar containerCustom controller
Resource Usage~30m CPU / 50Mi RAM~5m CPU / 10Mi RAMDepends on implementation
Helm ChartAvailableManual YAML onlyNone
Namespace ScopeCluster-wide or single namespacePer-deploymentPer-controller
Multiple WorkloadsDeployment, StatefulSet, DaemonSet, DeploymentConfigDeployment onlyConfigurable
Annotations Requiredreloader.stakater.com/auto: "true"Built into sidecarCustom annotation

Stakater Reloader

Stakater Reloader is the most popular and feature-complete solution. It runs as a Kubernetes controller that watches all ConfigMaps and Secrets cluster-wide (or within specified namespaces) and triggers rolling restarts on associated workloads.

How It Works

Reloader watches the Kubernetes API for changes to ConfigMaps and Secrets. When a change is detected, it looks for workloads with the reloader.stakater.com/auto annotation set to "true" and adds or updates a checksum annotation, which triggers a rolling restart.

Installation via Helm

1
2
3
helm repo add stakater https://stakater.github.io/charts
helm repo update
helm install reloader stakater/reloader --namespace reloader --create-namespace

Kubernetes Deployment (without Helm)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reloader
  namespace: reloader
  labels:
    app: reloader
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reloader
  template:
    metadata:
      labels:
        app: reloader
    spec:
      serviceAccountName: reloader
      containers:
      - name: reloader
        image: ghcr.io/stakater/reloader:latest
        args:
        - --namespace=
        - --configmap-annotation=reloader.stakater.com/auto
        - --secret-annotation=reloader.stakater.com/auto
        ports:
        - containerPort: 9090
        resources:
          limits:
            cpu: 100m
            memory: 128Mi
          requests:
            cpu: 30m
            memory: 50Mi

Usage — Annotate Your Workloads

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    reloader.stakater.com/auto: "true"
    # Optional: watch specific ConfigMaps/Secrets
    reloader.stakater.com/search: "true"
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        envFrom:
        - configMapRef:
            name: app-config

Watching Specific ConfigMaps

To watch only specific ConfigMaps instead of all of them:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    reloader.stakater.com/search: "true"
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  annotations:
    reloader.stakater.com/match: "true"
data:
  config.yaml: |
    key: value

configmap-reloader (Sidecar Approach)

configmap-reloader takes a different approach — instead of a cluster-wide controller, it runs as a sidecar container alongside your application. The sidecar watches the mounted ConfigMap files and sends a signal (SIGHUP) to the main process to reload configuration.

How It Works

The sidecar container shares the same ConfigMap volume mount as the main application. It uses Kubernetes file system notifications (inotify) to detect changes and then sends a SIGHUP signal to PID 1 (or a specified PID) in the main container.

Docker Compose for Testing

For local testing with a simulated sidecar pattern:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: "3.8"
services:
  app:
    image: nginx:alpine
    volumes:
    - ./config:/etc/nginx/conf.d:ro
    ports:
    - "8080:80"
    restart: unless-stopped

  configmap-reloader:
    image: jimmidyson/configmap-reloader:latest
    volumes:
    - ./config:/etc/nginx/conf.d:ro
    environment:
    - NAMESPACE=default
    - POD_NAME=app
    command: ["--volume-dir=/etc/nginx/conf.d", "--webhook-url=http://localhost:8080/-/reload"]

Kubernetes Sidecar Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-with-reloader
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: myapp:latest
        volumeMounts:
        - name: config-volume
          mountPath: /etc/app/config
          readOnly: true
      - name: configmap-reloader
        image: jimmidyson/configmap-reloader:latest
        args:
        - --volume-dir=/etc/app/config
        - --webhook-url=http://localhost:8080/-/reload
        volumeMounts:
        - name: config-volume
          mountPath: /etc/app/config
          readOnly: true
      volumes:
      - name: config-volume
        configMap:
          name: app-config

Pros and Cons

Advantages:

  • No cluster-wide permissions needed
  • Per-deployment isolation — one broken sidecar doesn’t affect others
  • Lower overall resource usage for small clusters
  • Works with applications that support SIGHUP-based reload

Disadvantages:

  • Requires application to support signal-based reload
  • Adds a sidecar to every pod that needs reloading
  • No support for environment variable updates (requires restart, not reload)
  • Manual configuration per deployment

K8s ConfigMap Watcher (Custom Controller)

Several projects implement custom controllers that watch ConfigMap changes and trigger rolling restarts. The most common pattern uses the Kubernetes client-go informer framework to watch for ConfigMap events, then finds pods referencing the changed ConfigMap and triggers a restart.

Building a Simple ConfigMap Watcher

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
    "fmt"
    "time"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/cache"
)

func main() {
    clientset, _ := kubernetes.NewForConfig(config)
    factory := informers.NewSharedInformerFactory(clientset, 30*time.Second)
    
    informer := factory.Core().V1().ConfigMaps().Informer()
    
    informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        UpdateFunc: func(oldObj, newObj interface{}) {
            oldCM := oldObj.(*corev1.ConfigMap)
            newCM := newObj.(*corev1.ConfigMap)
            
            if oldCM.ResourceVersion != newCM.ResourceVersion {
                fmt.Printf("ConfigMap %s updated, triggering reload
", newCM.Name)
                // Find and restart associated pods
                triggerRollingRestart(clientset, newCM)
            }
        },
    })
    
    stopCh := make(chan struct{})
    factory.Start(stopCh)
    <-stopCh
}

Docker Compose for Local Development

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
version: "3.8"
services:
  configmap-watcher:
    image: golang:1.22-alpine
    working_dir: /app
    volumes:
    - ./watcher:/app
    - ${HOME}/.kube/config:/root/.kube/config:ro
    command: ["go", "run", "main.go"]
    environment:
    - KUBECONFIG=/root/.kube/config

Why Use ConfigMap Auto-Reload?

Managing configuration changes in Kubernetes is one of the most common operational challenges. Without auto-reload tools, teams face several problems:

Configuration drift — When a ConfigMap is updated, some pods may continue running with stale configuration until they’re manually restarted. This creates inconsistent behavior across replicas, making debugging difficult.

Operational overhead — In a cluster with dozens of microservices, each reading from multiple ConfigMaps and Secrets, manually tracking which pods need restarting after a configuration change becomes a full-time job.

Deployment safety — Automated rolling restarts are safer than manual kubectl delete pod commands. Rolling restarts respect pod disruption budgets, maintain service availability, and follow the defined update strategy.

GitOps integration — When using GitOps tools like ArgoCD or Flux, configuration changes are applied declaratively. Auto-reload tools bridge the gap between declarative ConfigMap updates and the imperative pod restarts needed to apply them.

For related Kubernetes configuration management topics, see our Kubernetes Secrets Management guide and Kubernetes Automated Update & Restart tools. If you’re managing resource allocation, our Kubernetes Resource Optimization comparison covers VPA and Goldilocks.

Choosing the Right ConfigMap Reload Tool

ScenarioRecommended Tool
Production Kubernetes cluster with 10+ workloadsStakater Reloader
Small cluster, minimal permissionsconfigmap-reloader (sidecar)
Applications that support SIGHUP reloadconfigmap-reloader (sidecar)
Environment variable-based configurationStakater Reloader (requires restart)
Custom reload logic neededCustom ConfigMap Watcher
Helm-based deploymentsStakater Reloader (official chart)

For most production Kubernetes environments, Stakater Reloader is the best choice due to its active maintenance, Helm chart availability, cluster-wide operation, and support for both ConfigMaps and Secrets. The sidecar approach works well for small deployments or when cluster-wide RBAC permissions aren’t available.

FAQ

Do pods automatically pick up ConfigMap changes?

No, not fully. For file-mounted ConfigMaps, Kubernetes syncs the updated files to the pod within 1-2 minutes, but the application must explicitly re-read the files. For environment variable-based ConfigMaps, pods never receive updated values — a restart is always required.

What happens if Reloader restarts pods during a ConfigMap update?

Reloader triggers a rolling restart, which respects the Deployment’s update strategy. By default, Kubernetes ensures at least one pod is always running during the restart, maintaining service availability.

Can Stakater Reloader watch Secrets as well as ConfigMaps?

Yes. Reloader watches both ConfigMaps and Secrets. The same annotation (reloader.stakater.com/auto: "true") triggers restarts for changes to either resource type.

Does configmap-reloader work with StatefulSets?

The sidecar approach works with any workload type that supports multiple containers, including StatefulSets and DaemonSets. However, each pod needs the sidecar configured individually.

Is there a performance impact of running Reloader?

Stakater Reloader uses approximately 30m CPU and 50Mi RAM. For a typical cluster, this is negligible. The sidecar approach uses even less per-pod (~5m CPU, ~10Mi RAM) but adds a container to every pod that needs reloading.

How do I exclude specific ConfigMaps from triggering restarts?

With Stakater Reloader, use the reloader.stakater.com/auto: "false" annotation on specific ConfigMaps, or configure the --resources-to-ignore flag. Alternatively, scope Reloader to specific namespaces using the --namespace flag.