Reloader Cheat Sheet
Overview
Reloader is a Kubernetes controller that watches for changes in ConfigMaps and Secrets, then triggers rolling upgrades on associated Deployments, StatefulSets, DaemonSets, and DeploymentConfigs. When configuration data changes, Kubernetes does not automatically restart pods — Reloader solves this by detecting changes and initiating rolling updates to pick up new values.
Reloader works by adding annotations to workloads that reference the ConfigMaps or Secrets they depend on. When those resources change, Reloader updates the pod template hash to trigger a rolling restart, ensuring applications always run with the latest configuration.
Installation
Helm
# Add Helm repo
helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update
# Install
helm install reloader stakater/reloader \
--namespace reloader \
--create-namespace
# Install with custom values
helm install reloader stakater/reloader \
--namespace reloader \
--create-namespace \
--set reloader.watchGlobally=true \
--set reloader.logFormat=json
kubectl
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
Verify
kubectl get pods -n reloader
kubectl logs -n reloader deployment/reloader-reloader -f
Core Usage
Auto-Reload All ConfigMaps/Secrets
# Add annotation to Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
reloader.stakater.com/auto: "true"
spec:
template:
spec:
containers:
- name: my-app
image: my-app:latest
envFrom:
- configMapRef:
name: my-app-config
- secretRef:
name: my-app-secrets
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: my-app-config
Specific ConfigMap/Secret Reload
# Watch specific ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
configmap.reloader.stakater.com/reload: "my-app-config"
spec:
# ...
# Watch specific Secret
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
secret.reloader.stakater.com/reload: "my-app-secrets"
spec:
# ...
# Watch multiple resources
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
configmap.reloader.stakater.com/reload: "app-config,shared-config"
secret.reloader.stakater.com/reload: "db-creds,api-keys"
spec:
# ...
Configuration
Helm Values
# values.yaml
reloader:
watchGlobally: true
logFormat: json # json or ""
ignoreSecrets: false
ignoreConfigMaps: false
deployment:
resources:
requests:
cpu: 10m
memory: 128Mi
limits:
cpu: 100m
memory: 256Mi
# Only watch specific namespaces
namespaceSelector: "reloader-enabled=true"
# Ignore specific namespaces
ignoreNamespaces: "kube-system,kube-public"
# Resource label selector
resourceLabelSelector: "app.kubernetes.io/managed-by=helm"
Workload Types
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
reloader.stakater.com/auto: "true"
# ...
# StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
reloader.stakater.com/auto: "true"
# ...
# DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
reloader.stakater.com/auto: "true"
# ...
Reload Strategy
# Default: rolling update via env annotation change
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
reloader.stakater.com/auto: "true"
# Optional: custom search match annotation
reloader.stakater.com/search: "true"
Advanced Usage
Namespace-Scoped Watching
# Install Reloader to watch only specific namespaces
helm install reloader stakater/reloader \
--namespace reloader \
--create-namespace \
--set reloader.watchGlobally=false \
--set reloader.namespaceSelector="reloader-enabled=true"
# Label namespaces that should be watched
kubectl label namespace production reloader-enabled=true
kubectl label namespace staging reloader-enabled=true
Search Annotation Pattern
# Instead of listing specific configmaps/secrets,
# Reloader can search for all referenced resources
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
reloader.stakater.com/search: "true"
spec:
template:
spec:
containers:
- name: my-app
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
# Reloader automatically detects app-config and app-secrets
Preventing Reloads
# Opt out specific ConfigMap from triggering reloads
apiVersion: v1
kind: ConfigMap
metadata:
name: static-config
annotations:
reloader.stakater.com/match: "false"
Complete Example
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
location / {
proxy_pass http://backend:8080;
}
}
---
# Deployment with Reloader
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
annotations:
configmap.reloader.stakater.com/reload: "nginx-config"
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: nginx-config
# Update ConfigMap — Reloader automatically restarts pods
kubectl edit configmap nginx-config
# or
kubectl create configmap nginx-config --from-file=nginx.conf -o yaml --dry-run=client | kubectl apply -f -
Troubleshooting
| Issue | Solution |
|---|---|
| Pods not restarting | Check annotations are correct; verify Reloader is running |
| Too many restarts | Use specific resource annotations instead of auto: "true" |
| Reloader not watching namespace | Check watchGlobally setting or namespace labels |
| Secret changes not detected | Ensure ignoreSecrets is not set to true |
| Rolling update too aggressive | Configure deployment maxUnavailable and maxSurge |
| Reloader OOM | Increase memory limits in Helm values |
# Check Reloader logs
kubectl logs -n reloader deployment/reloader-reloader -f
# Verify annotation
kubectl get deployment my-app -o jsonpath='{.metadata.annotations}'
# Check if pod template was updated
kubectl get deployment my-app -o jsonpath='{.spec.template.metadata.annotations}'
# Manual rollout restart (without Reloader)
kubectl rollout restart deployment/my-app
# Check Reloader version
kubectl get deployment -n reloader reloader-reloader -o jsonpath='{.spec.template.spec.containers[0].image}'