Skip to main content

Reloader Stakater

Panduan lengkap instalasi dan penggunaan Stakater Reloader untuk automatic rolling restart pods ketika ConfigMap atau Secret berubah.

Pengenalan

Stakater Reloader adalah Kubernetes controller yang memantau perubahan pada ConfigMap dan Secret, kemudian secara otomatis melakukan rolling restart pada Deployment, StatefulSet, DaemonSet, atau DeploymentConfig yang menggunakan resource tersebut.

Mengapa Reloader Diperlukan?

Secara default, Kubernetes tidak otomatis restart pods ketika ConfigMap atau Secret yang mereka gunakan berubah. Ini dapat menyebabkan:

  • Aplikasi menggunakan konfigurasi lama
  • Inconsistency antara pods yang baru dan lama
  • Perlu manual restart untuk apply perubahan

Fitur Utama

  • Auto-reload: Otomatis restart pods saat config berubah
  • Annotation-based: Kontrol granular per resource
  • Multi-resource: Support Deployment, StatefulSet, DaemonSet, dll
  • Flexible: Bisa monitor specific ConfigMap/Secret atau semua
  • Lightweight: Resource usage minimal
  • Production-ready: Digunakan oleh banyak perusahaan

Instalasi

# Tambahkan Stakater Helm repository
helm repo add stakater https://stakater.github.io/stakater-charts
helm repo update

# Install Reloader
helm install reloader stakater/reloader \
--namespace reloader \
--create-namespace \
--set reloader.watchGlobally=true

Metode 2: Kubectl dengan Manifest

# Download dan apply manifest
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

Metode 3: Kustomize

Buat file kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: reloader

resources:
- https://github.com/stakater/Reloader/deployments/kubernetes

# Optional: customize
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: reloader-reloader
spec:
replicas: 2

Apply:

kubectl apply -k .

Verifikasi Instalasi

# Check pods
kubectl get pods -n reloader

# Check logs
kubectl logs -n reloader -l app=reloader-reloader

# Expected output:
# time="..." level=info msg="Starting Reloader"
# time="..." level=info msg="Starting Controller"

Konfigurasi

Helm Values Customization

Buat file values.yaml:

reloader:
# Monitor all namespaces
watchGlobally: true

# Ignore specific namespaces
ignoreNamespaces: "kube-system,kube-public"

# Ignore specific ConfigMaps/Secrets
ignoreConfigMaps: "kube-root-ca.crt"
ignoreSecrets: ""

# Sync interval
syncPeriod: "60s"

# Log level: info, debug, warn, error
logLevel: "info"

# Resource limits
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi

# High availability
replicaCount: 2

# Pod disruption budget
podDisruptionBudget:
enabled: true
minAvailable: 1

Install dengan custom values:

helm install reloader stakater/reloader \
--namespace reloader \
--create-namespace \
-f values.yaml

Cara Penggunaan

1. Auto Reload Semua ConfigMaps/Secrets

Tambahkan annotation reloader.stakater.com/auto: "true" pada Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.0
envFrom:
- configMapRef:
name: myapp-config
- secretRef:
name: myapp-secrets

Ketika myapp-config atau myapp-secrets berubah, Reloader akan otomatis rolling restart deployment.

2. Monitor Specific ConfigMap

Tambahkan annotation dengan nama ConfigMap spesifik:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/match: "true"
configmap.reloader.stakater.com/reload: "myapp-config,shared-config"
spec:
# ... rest of spec

3. Monitor Specific Secret

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/match: "true"
secret.reloader.stakater.com/reload: "myapp-secrets,db-credentials"
spec:
# ... rest of spec

4. Monitor Both ConfigMap dan Secret

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/match: "true"
configmap.reloader.stakater.com/reload: "myapp-config"
secret.reloader.stakater.com/reload: "myapp-secrets"
spec:
# ... rest of spec

Contoh Lengkap

Example 1: Web Application dengan ConfigMap

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
namespace: production
data:
app.conf: |
server {
listen 8080;
server_name example.com;
}
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.25-alpine
ports:
- containerPort: 8080
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: webapp-config
key: LOG_LEVEL
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: config
configMap:
name: webapp-config

Update ConfigMap:

# Edit ConfigMap
kubectl edit configmap webapp-config -n production

# Atau update via file
kubectl apply -f webapp-config.yaml

# Reloader akan detect perubahan dan restart pods
kubectl get pods -n production -w

Example 2: Database Application dengan Secret

Secret:

apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
stringData:
DB_HOST: "postgres.production.svc.cluster.local"
DB_PORT: "5432"
DB_USER: "appuser"
DB_PASSWORD: "secure-password-here"
DB_NAME: "myapp"

StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: app-backend
namespace: production
annotations:
secret.reloader.stakater.com/reload: "db-credentials"
spec:
serviceName: app-backend
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: myapp/backend:2.0.0
envFrom:
- secretRef:
name: db-credentials
ports:
- containerPort: 8080

Example 3: Multi-ConfigMap Setup

apiVersion: apps/v1
kind: Deployment
metadata:
name: microservice
namespace: staging
annotations:
configmap.reloader.stakater.com/reload: "app-config,feature-flags,env-vars"
secret.reloader.stakater.com/reload: "api-keys,db-creds"
spec:
replicas: 2
selector:
matchLabels:
app: microservice
template:
metadata:
labels:
app: microservice
spec:
containers:
- name: api
image: myapp/api:1.5.0
envFrom:
- configMapRef:
name: app-config
- configMapRef:
name: feature-flags
- configMapRef:
name: env-vars
- secretRef:
name: api-keys
- secretRef:
name: db-creds

Advanced Usage

Ignore Specific Resources

Jika Anda ingin Reloader tidak memonitor resource tertentu:

apiVersion: apps/v1
kind: Deployment
metadata:
name: no-reload-app
annotations:
reloader.stakater.com/reload: "false"
spec:
# ... spec

Custom Reload Strategy

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/auto: "true"
# Tambahkan delay sebelum reload (dalam detik)
reloader.stakater.com/reload-delay: "30"
spec:
# ... spec

Search by Regex (Advanced)

Monitor ConfigMaps/Secrets dengan pattern:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
configmap.reloader.stakater.com/reload: "app-.*" # Semua ConfigMap yang dimulai dengan "app-"
spec:
# ... spec

Monitoring dan Troubleshooting

Check Reloader Status

# Lihat logs
kubectl logs -n reloader -l app=reloader-reloader --tail=100 -f

# Check events
kubectl get events -n reloader --sort-by='.lastTimestamp'

Debug Mode

Enable debug logging:

helm upgrade reloader stakater/reloader \
--namespace reloader \
--set reloader.logLevel=debug \
--reuse-values

Common Issues

Issue 1: Pods tidak restart setelah ConfigMap berubah

Penyebab:

  • Annotation salah atau tidak ada
  • Reloader tidak running
  • RBAC permissions kurang

Solusi:

# 1. Check annotation
kubectl get deployment myapp -o yaml | grep reloader

# 2. Check Reloader pods
kubectl get pods -n reloader

# 3. Check RBAC
kubectl auth can-i list configmaps --as=system:serviceaccount:reloader:reloader-reloader

Issue 2: Restart terlalu sering

Penyebab: ConfigMap/Secret berubah terlalu sering

Solusi: Implementasikan reload delay atau gunakan specific matching:

annotations:
configmap.reloader.stakater.com/reload: "production-config" # Specific, bukan auto

Issue 3: Performance Impact

Solusi: Limit namespaces yang dimonitor:

# values.yaml
reloader:
watchGlobally: false
namespaceSelector: "monitoring=enabled"

Label namespace yang ingin dimonitor:

kubectl label namespace production monitoring=enabled
kubectl label namespace staging monitoring=enabled

Metrics dan Monitoring

Reloader expose Prometheus metrics:

apiVersion: v1
kind: Service
metadata:
name: reloader-metrics
namespace: reloader
labels:
app: reloader
spec:
ports:
- name: metrics
port: 8080
targetPort: 8080
selector:
app: reloader-reloader

ServiceMonitor (jika menggunakan Prometheus Operator):

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: reloader
namespace: reloader
spec:
selector:
matchLabels:
app: reloader
endpoints:
- port: metrics
interval: 30s

Key Metrics:

  • reloader_reload_executed_total: Total reload yang dieksekusi
  • reloader_reload_errors_total: Total reload errors
  • reloader_items_monitored: Jumlah resource yang dimonitor

Best Practices

1. Use Specific Matching

Jangan (terlalu broad):

annotations:
reloader.stakater.com/auto: "true"

Gunakan (specific):

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

2. Label Your ConfigMaps/Secrets

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
labels:
app: myapp
managed-by: terraform
reloader: enabled
data:
# ... config

3. Version Your ConfigMaps

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-v2 # Versioning
labels:
app: myapp
version: "v2"
data:
# ... config

Update deployment untuk switch version:

envFrom:
- configMapRef:
name: app-config-v2 # Update version

4. Use ConfigMap/Secret Checksums

Alternative approach tanpa Reloader (manual):

spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

5. Implement Health Checks

Pastikan aplikasi Anda memiliki readiness/liveness probes:

spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

6. Set Resource Limits

# Deployment yang menggunakan Reloader
spec:
template:
spec:
containers:
- name: app
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi

7. PodDisruptionBudget

Untuk mencegah downtime saat reload:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp

Integration dengan CI/CD

GitOps Workflow

# .gitea/workflows/deploy.yml
name: Deploy Application
on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Update ConfigMap
run: |
kubectl apply -f k8s/configmap.yaml
# Reloader akan otomatis restart pods

- name: Wait for rollout
run: |
kubectl rollout status deployment/myapp -n production

Helm Chart Integration

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
annotations:
{{- if .Values.reloader.enabled }}
reloader.stakater.com/auto: "true"
{{- end }}
spec:
# ... rest of template
# values.yaml
reloader:
enabled: true
watchConfigMaps: true
watchSecrets: true

Uninstall

# Helm
helm uninstall reloader -n reloader

# Kubectl
kubectl delete -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

# Delete namespace
kubectl delete namespace reloader

Kesimpulan

Stakater Reloader adalah tool essential untuk automasi deployment di Kubernetes. Dengan Reloader, Anda tidak perlu lagi manual restart pods setiap kali ConfigMap atau Secret berubah.

Kapan Menggunakan Reloader?

Gunakan jika:

  • Sering update configuration
  • Butuh automatic restart
  • Ingin simplify operational workflow

Pertimbangkan alternatif jika:

  • Hanya update config jarang
  • Prefer immutable deployments
  • Concern tentang unexpected restarts

Alternatif

  • Immutable ConfigMaps: Buat ConfigMap baru dengan version, update Deployment
  • ConfigMap Reload in-app: Aplikasi watch dan reload config sendiri
  • Helm hooks: Restart via Helm upgrade hooks

Resources