Build Daily

Tinley Park · October 29, 2026
toolStakaterapplied

Reloader

Stakater Reloader is a small Kubernetes controller that watches ConfigMaps and Secrets and starts a rolling update of the Deployments, StatefulSets, DaemonSets and other workloads that use them, so changed config and rotated credentials reach running pods. Workloads opt in with annotations such as reloader.stakater.com/auto; Reloader hashes the data and writes the hash into the pod template, which makes Kubernetes roll the pods. Apache 2.0 and free; a paid Enterprise build adds signed images and support. It fits any cluster where secrets rotate or config changes outside a deploy, for example with External Secrets Operator.

Updated October 17, 2026

Reloader is a Kubernetes controller from Stakater that restarts workloads when the ConfigMaps or Secrets they use change. Kubernetes does not do this itself: a pod that reads a Secret through environment variables keeps the old value until the pod is replaced, so a rotated password or an edited feature flag can sit unused in the cluster for weeks. Reloader closes that gap with a rolling update that goes through the normal Deployment machinery.

What it is

A single Go controller, usually installed with Helm, that holds watches on ConfigMaps and Secrets and patches the workloads that reference them. It supports Deployments, StatefulSets, DaemonSets, CronJobs (it starts a Job), Argo Rollouts and OpenShift DeploymentConfigs. Optionally it also watches the Secrets Store CSI Driver's SecretProviderClassPodStatus objects, so CSI-mounted secrets can trigger a restart too.

  • Licence: Apache 2.0. Stakater sells a Reloader Enterprise build with signed, CVE-scanned images, SBOMs and SLA support; the open-source build is the same controller.
  • Release lines: v1 is the stable line, currently v1.4.22 (Helm chart 2.2.18, September 2026). The master branch that carries v1 is feature-frozen and takes only bug and security fixes. v2, rebuilt on the Operator SDK, is in beta (v2.0.0-beta.1, chart 3.0.0-beta.x) on the v2 branch, and all new features land there.
  • Compatibility: the project states Kubernetes 1.19 or later.
  • Family: a Kubernetes controller in the same small class as Kustomize's hashed ConfigMap names and Helm's checksum-annotation pattern; all three exist to turn a config change into a pod rollout.

How it works

Reloader runs an informer on ConfigMaps and Secrets (cluster-wide by default, or limited to some namespaces). When one of them changes, it computes a SHA-1 hash of the new data, then finds every workload that both references the object and opts in through an annotation. For each match it writes the hash into the workload's pod template. A changed pod template is exactly what the Deployment controller treats as a new revision, so Kubernetes performs a normal rolling update, honouring maxSurge, maxUnavailable and readiness probes.

There are two ways to write the hash, set by --reload-strategy:

  • env-vars (the default) adds an environment variable such as STAKATER_MY_SECRET_SECRET=<sha> to each container that uses the changed object.
  • annotations writes a reloader.stakater.com/last-reloaded-from annotation onto the pod template instead. The project recommends this mode for GitOps tools such as Argo CD and Flux, because it leaves the container spec alone.

The figure below shows the two common sources of a change: a rotated secret that arrives through External Secrets, and a ConfigMap edited in Git and synced by Argo CD.

How Reloader turns a changed Secret into a rollout

Step 1 of 5. A credential is rotated in OpenBao. On its next refresh, External Secrets reads the new value.

Two paths: a secret rotated in the vault, and a ConfigMap changed in Git. Both end in an ordinary rolling update.

Reloader acts only on update events by default. Create and delete events are ignored unless --reload-on-create or --reload-on-delete is set. With more than one replica, --enable-ha turns on leader election through a Kubernetes Lease, so only one replica patches workloads at a time.

When to use it

Reach for it when:

  • Secrets rotate on a schedule outside the deploy pipeline, for example through External Secrets Operator, cert-manager certificates or a Sealed Secrets update.
  • Apps read config through environment variables, which Kubernetes never refreshes in a running container.
  • Apps read config from files but do not watch those files for changes.
  • A ConfigMap is mounted with subPath, which the kubelet does not update in place.

Skip it when:

  • Every config change already ships with a new image or a new manifest revision, so pods roll anyway.
  • Config names are content-hashed (Kustomize configMapGenerator) or the Helm chart writes a checksum/config annotation; those already roll pods on change.
  • The app hot-reloads mounted files itself and a restart would only add disruption.
  • A workload must never restart without a human decision, such as a single-replica database.

At a glance

Core concepts

  • Opt-in annotation: reloader.stakater.com/auto: "true" on a workload reloads it when any ConfigMap or Secret it references changes. secret.reloader.stakater.com/auto and configmap.reloader.stakater.com/auto narrow that to one kind.
  • Named reload: secret.reloader.stakater.com/reload: "db-creds" reloads on a named object even when the pod spec does not reference it.
  • Search and match: reloader.stakater.com/search: "true" on the workload plus reloader.stakater.com/match: "true" on the ConfigMap or Secret. Only tagged objects trigger reloads.
  • Ignore: reloader.stakater.com/ignore: "true" on a ConfigMap or Secret stops it from triggering any reload.
  • Pause period: deployment.reloader.stakater.com/pause-period: "5m" holds back further rollouts after a reload, so a burst of related changes causes one restart.
  • Global opt-in: --auto-reload-all treats every workload as auto: "true" unless it sets "false".

Key facts

Aspect Value
Stable release v1.4.22 (chart 2.2.18)
Next major v2 beta, Operator SDK based
Licence Apache 2.0
Image ghcr.io/stakater/reloader
Default resources requests 10m CPU / 128Mi; limits 150m / 512Mi
Default scope all namespaces (watchGlobally: true)
Default strategy env-vars
Kubernetes 1.19 or later

Reloader compared with the built-in patterns

Aspect Reloader Helm checksum annotation Kustomize configMapGenerator
Catches changes made outside the deploy (ESO, cert-manager) Yes No No
Needs a running controller Yes No No
Works with any manifest source Yes Helm charts only Kustomize only
Restarts on Secret rotation Yes Only on the next helm upgrade Only on the next build and apply
Extra RBAC in the cluster Read Secrets cluster-wide by default None None

How to integrate

Install from the Stakater chart repository:

helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update
helm install reloader stakater/reloader \
  --namespace reloader --create-namespace \
  --version 2.2.18 \
  -f reloader-values.yaml

A small values file for a GitOps cluster:

reloader:
  reloadStrategy: annotations   # leave container env alone; friendlier to Argo CD / Flux diffs
  watchGlobally: true
  ignoreNamespaces: "kube-system"
  logFormat: json
  enableHA: false               # set true and raise replicas for leader election
  readOnlyRootFileSystem: true

Opt a workload in:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  annotations:
    secret.reloader.stakater.com/auto: "true"
spec:
  template:
    spec:
      containers:
        - name: api
          image: example/api:1.0.0
          envFrom:
            - secretRef:
                name: api-env   # written by an ExternalSecret

To test, change a key in the Secret and watch kubectl rollout status deploy/api. The Reloader log records which object triggered which workload.

In the GL stack

Reloader v1.4.22 runs on the beta and prod clusters, the two clusters that host the product workloads behind paiddaily.io, sagedaily.io and the other sites.

  • Why it is there. Application secrets live in OpenBao. On each workload cluster, External Secrets Operator pulls them into Kubernetes Secrets through ExternalSecret objects. Without Reloader, a secret rotated in OpenBao would reach the Kubernetes Secret but not the running pods. Reloader closes that last step, so a rotation takes effect without a manual restart.
  • How it is wired. Reloading is annotation-driven: only Deployments that carry a Reloader annotation are rolled, and every other workload is left alone. It watches both ConfigMaps and Secrets.
  • Where it sits in delivery. Argo CD applies the manifests, including the Deployment annotations; External Secrets supplies the Secret data; Reloader turns a change in that data into a rollout.

Gotchas

  • The env-vars strategy shows up as drift. The default writes a STAKATER_* env var into the container spec, so the live object no longer matches Git. With Argo CD or Flux, use reloadStrategy: annotations or expect diffs.
  • Argo Rollouts needs its own flag. Rollouts support is off until isArgoRollouts: true. The reloader.stakater.com/rollout-strategy: "restart" annotation deletes pods instead of patching the template, which avoids drift for Rollouts only.
  • auto and search do not combine. If both are set on one workload, auto wins.
  • Changes during downtime. Reloader reacts to watch events. syncAfterRestart handles add events after a Reloader restart, and only when reloadOnCreate is also true. After an outage of Reloader, check that recent rotations were applied.
  • One ignored type only. --resources-to-ignore accepts configmaps or secrets, not both. To disable Reloader, scale it to zero.
  • Rollout rules still apply. A StatefulSet with updateStrategy: OnDelete will not roll when its template changes, and a Deployment with one replica and maxUnavailable: 1 will have a short outage.
  • CSI secrets need secretKey. For Secrets Store CSI integration, rotation must be on in the driver, Reloader needs --enable-csi-integration=true, and each object in the SecretProviderClass needs a secretKey or updates may be missed.
  • A burst of changes means a burst of rollouts. Several Secrets updated together can roll a workload several times. Use the pause-period annotation on Deployments that read many objects.

Risks

  • RBAC reach. In global mode Reloader can list and watch every Secret in the cluster and patch workloads in every namespace. Scope it with watchGlobally: false, reloader.namespaces or namespaceSelector where that matters, and keep the image pinned.
  • Release-line transition. v1 is feature-frozen and v2 is still in beta. v1 will receive fixes, but new features go to v2 only, and a v1-to-v2 move will need a chart major bump (2.x to 3.x) and a values review.
  • Single-vendor project. Stakater maintains it and also sells the Enterprise build. The project is widely used (the README cites more than 24 billion image pulls), but its roadmap follows one company.
  • Lock-in is low. The annotations are the only coupling. Removing Reloader leaves workloads intact; they simply stop rolling on config change.

Alternatives

  • Helm checksum/config annotation: a hash of the rendered ConfigMap in the pod template; pick it when all config comes from the chart and rotations always go through helm upgrade.
  • Kustomize configMapGenerator / secretGenerator: content-hashed object names; pick it when Kustomize builds every config change.
  • App-side file watching: mount config as a volume and reload in-process; pick it when restarts are costly and the app or framework supports hot reload.
  • Manual kubectl rollout restart: pick it when rotations are rare and a human already runs them.

Related