Kubernetes - Automating ConfigMap and Secret Reloads with Reloader
Table of Contents
This post is part of our ongoing series of posts for Kubernetes. In this post, we will explore how to automate the reloading of ConfigMaps and Secrets in your Kubernetes clusters using Reloader, a powerful tool designed to streamline application configuration updates without manual intervention.
When working with applications that rely on configuration data or sensitive information stored in ConfigMaps and Secrets, manually restarting pods to apply changes can be tedious, error-prone, and disruptive to service availability. Reloader elegantly solves this problem by automatically detecting configuration changes and triggering rolling updates for the associated deployments, ensuring your applications always run with the latest configurations while maintaining high availability.
1. Setup Reloader
Let’s configure Reloader by creating cluster/default/reloader.yaml
. This declarative configuration establishes:
- A dedicated Reloader namespace
- The Stakater Helm Repository reference
- The Reloader Helm Release with appropriate configuration
---
apiVersion: v1
kind: Namespace
metadata:
name: reloader
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: stakater
namespace: reloader
spec:
interval: 30m
url: https://stakater.github.io/stakater-charts
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: reloader
namespace: reloader
spec:
releaseName: reloader
interval: 10m
chart:
spec:
chart: reloader
version: "v1.3.0"
interval: 10m
sourceRef:
kind: HelmRepository
name: stakater
namespace: reloader
values:
reloader:
deployment:
replicas: 1
resources:
requests:
cpu: "20m"
memory: "128Mi"
limits:
cpu: "100m"
memory: "128Mi"
After applying this configuration, verify that the Reloader pod is up and running:
kubectl -n reloader get pods
NAME READY STATUS RESTARTS AGE
reloader-reloader-666577c76-76gph 1/1 Running 0 56s
The output confirms that Reloader has been successfully deployed and is operational in your cluster.
2. Validate Setup with a Practical Example
To demonstrate Reloader’s capabilities in action, we’ll update the sample application we created in Kubernetes GitOps with FluxCD - Part 3 - Automated Image Updates to consume a ConfigMap value injected through an environment variable.
2.1 Define a ConfigMap
First, let’s define a ConfigMap by creating apps/sample-app/message-config.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: message-config
namespace: default
data:
message: "Message before config change"
2.2 Update Deployment Configuration
Next, we’ll modify our deployment manifest in apps/sample-app/deployment.yaml
to add the Reloader annotation and inject our configuration as an environment variable:
apiVersion: apps/v1
metadata:
name: sample-app
namespace: default
+ annotations:
+ reloader.stakater.com/auto: "true"
kind: Deployment
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
imagePullSecrets:
- name: github-registry-secret
containers:
- name: sample-app
+ env:
+ - name: MESSAGE
+ valueFrom:
+ configMapKeyRef:
+ key: message
+ name: message-config
image: ghcr.io/kiriapurv/k8s-sample-app:main-29e96d2a-1740565130 # {"$imagepolicy": "default:sample-app-main-policy"}
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "150m"
The critical addition here is the reloader.stakater.com/auto: "true"
annotation, which instructs Reloader to monitor this deployment for configuration changes.
2.3 Update Kustomization File
We need to update the apps/sample-app/kustomization.yaml
to include our new ConfigMap:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
+ - message-config.yaml
Now we can commit and push these changes to our GitOps repository, allowing FluxCD to synchronize them to our cluster. This will inject the environment variable into our application pods.
2.4 Modify Application Code
To make our application respond with the configured message, let’s update our Controller code:
package com.kiriyard;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Path("/")
public class K8SampleApplication {
private static final int VERSION = 2;
+ @ConfigProperty(name = "MESSAGE", defaultValue = "No message found")
+ private String configMessage;
+
@GET
@Produces(MediaType.TEXT_PLAIN)
public String index() {
- return "Greetings From K8S App : Version %d - Config Message: %s".formatted(VERSION, configMessage);
+ return "Greetings From K8S App : Version %d".formatted(VERSION);
}
}
After building and deploying this code update, let’s verify the application’s response:
curl https://sample-app.******
Greetings From K8S App : Version 2 - Config Message: Message before config change
Perfect! Our application is now successfully reading and displaying the message from our ConfigMap.
2.5 Test Reloader’s Automation
Now for the real test of Reloader’s functionality: let’s modify our ConfigMap and observe if the deployment automatically updates without manual intervention.
Update apps/sample-app/message-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: message-config
namespace: default
data:
- message: "Message before config change"
+ message: "Message after config change"
After committing and pushing this change to your GitOps repository, wait a moment for the synchronization to occur, then check the application’s response:
curl https://sample-app.******
Greetings From K8S App : Version 2 - Config Message: Message after config change
Success! Our deployment has been automatically updated with the new configuration value, and the application is now displaying the updated message. Reloader detected the ConfigMap change and triggered a rolling update of our deployment without any manual intervention.
3. Advanced Reloader Features
While our example demonstrated the basic functionality, Reloader offers several advanced features:
- Selective monitoring: Use annotations like
reloader.stakater.com/search: "true"
to monitor specific ConfigMaps or Secrets or specifysecret.reloader.stakater.com/reload
to reload on certain selected ConfigMap or Secret only. - Namespace monitoring: Configure Reloader: to watch specific namespaces with
reloader.namespaceSelector
helm value - Rolling update strategy customization: Control how pods are replaced during updates ( e.g.
env-vars
vsannotations
)
For more detailed information on these advanced features, refer to the Reloader documentation.
References
- Stakater Reloader - https://github.com/stakater/Reloader
- Kubernetes Documentation - https://kubernetes.io/docs/