Skip to content

Commit 1652c62

Browse files
Merge pull request stakater#1076 from stakater/csi-support-without-SHA512
Feature - Csi support without sha512
2 parents fdd2474 + 8373b1e commit 1652c62

26 files changed

Lines changed: 1942 additions & 208 deletions

README.md

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
## 🔁 What is Reloader?
1515

16-
Reloader is a Kubernetes controller that automatically triggers rollouts of workloads (like Deployments, StatefulSets, and more) whenever referenced `Secrets` or `ConfigMaps` are updated.
16+
Reloader is a Kubernetes controller that automatically triggers rollouts of workloads (like Deployments, StatefulSets, and more) whenever referenced `Secrets`, `ConfigMaps` or **optionally CSI-mounted secrets** are updated.
1717

1818
In a traditional Kubernetes setup, updating a `Secret` or `ConfigMap` does not automatically restart or redeploy your workloads. This can lead to stale configurations running in production, especially when dealing with dynamic values like credentials, feature flags, or environment configs.
1919

@@ -169,9 +169,11 @@ metadata:
169169
170170
This instructs Reloader to skip all reload logic for that resource across all workloads.
171171
172-
### 4. ⚙️ Workload-Specific Rollout Strategy
172+
### 4. ⚙️ Workload-Specific Rollout Strategy (Argo Rollouts Only)
173173
174-
By default, Reloader uses the **rollout** strategy — it updates the pod template to trigger a new rollout. This works well in most cases, but it can cause problems if you're using GitOps tools like ArgoCD, which detect this as configuration drift.
174+
Note: This is only applicable when using [Argo Rollouts](https://argoproj.github.io/argo-rollouts/). It is ignored for standard Kubernetes `Deployments`, `StatefulSets`, or `DaemonSets`. To use this feature, Argo Rollouts support must be enabled in Reloader (for example via --is-argo-rollouts=true).
175+
176+
By default, Reloader triggers the Argo Rollout controller to perform a standard rollout by updating the pod template. This works well in most cases, however, because this modifies the workload spec, GitOps tools like ArgoCD will detect this as "Configuration Drift" and mark your application as OutOfSync.
175177

176178
To avoid that, you can switch to the **restart** strategy, which simply restarts the pod without changing the pod template.
177179

@@ -192,6 +194,8 @@ metadata:
192194
1. You want a quick restart without changing the workload spec
193195
1. Your platform restricts metadata changes
194196

197+
This setting affects Argo Rollouts behavior, not Argo CD sync settings.
198+
195199
### 5. ❗ Annotation Behavior Rules & Compatibility
196200

197201
- `reloader.stakater.com/auto` and `reloader.stakater.com/search` **cannot be used together** — the `auto` annotation takes precedence.
@@ -239,6 +243,61 @@ This feature allows you to pause rollouts for a deployment for a specified durat
239243
1. ✅ Your deployment references multiple ConfigMaps or Secrets that may be updated at the same time.
240244
1. ✅ You want to minimize unnecessary rollouts and reduce downtime caused by back-to-back configuration changes.
241245

246+
### 8. 🔐 CSI Secret Provider Support
247+
248+
Reloader supports the [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/), which allows mounting secrets from external secret stores (like AWS Secrets Manager, Azure Key Vault, HashiCorp Vault) directly into pods.
249+
Unlike Kubernetes Secret objects, CSI-mounted secrets do not always trigger native Kubernetes update events. Reloader solves this by watching CSI status resources and restarting affected workloads when mounted secret versions change.
250+
251+
#### How it works
252+
253+
When secret rotation is enabled, the Secrets Store CSI Driver updates a Kubernetes resource called: `SecretProviderClassPodStatus`
254+
255+
This resource reflects the currently mounted secret versions for a pod.
256+
Reloader watches these updates and triggers a rollout when a change is detected.
257+
258+
#### Prerequisites
259+
260+
- Secrets Store CSI Driver must be installed in your cluster
261+
- Secret rotation enabled in the CSI driver.
262+
- Enable CSI integration in Reloader: `--enable-csi-integration=true`
263+
264+
#### Annotations for CSI-mounted Secrets
265+
266+
| Annotation | Description |
267+
|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
268+
| `reloader.stakater.com/auto: "true"` | Global Discovery: Automatically discovers and reloads the workload when any mounted ConfigMap or Secret is updated. |
269+
| `secretproviderclass.reloader.stakater.com/auto: 'true'` | CSI Discovery: Specifically watches for updates to all SecretProviderClasses used by the workload (CSI driver integration). |
270+
| `secretproviderclass.reloader.stakater.com/reload: "my-secretproviderclass"` | Targeted Reload: Only reloads the workload when the specifically named SecretProviderClass(es) are updated. |
271+
272+
Reloader monitors changes at the **per-secret level** by watching the `SecretProviderClassPodStatus`. Make sure each secret you want to monitor is properly defined with a `secretKey` in your `SecretProviderClass`:
273+
274+
```yaml
275+
apiVersion: secrets-store.csi.x-k8s.io/v1
276+
kind: SecretProviderClass
277+
metadata:
278+
name: vault-reloader-demo
279+
namespace: test
280+
spec:
281+
provider: vault
282+
parameters:
283+
vaultAddress: "http://vault.vault.svc:8200"
284+
vaultSkipTLSVerify: "true"
285+
roleName: "demo-role"
286+
objects: |
287+
- objectName: "password"
288+
secretPath: "secret/data/reloader-demo"
289+
secretKey: "password"
290+
```
291+
292+
***Important***: Reloader tracks changes to individual secrets (identified by `secretKey`). If your SecretProviderClass doesn't specify `secretKey` for each object, Reloader may not detect updates correctly.
293+
294+
#### Notes & Limitations
295+
296+
Reloader reacts to CSI status changes, not direct updates to external secret stores
297+
Secret rotation must be enabled in the CSI driver for updates to be detected
298+
CSI limitations (such as `subPath` mounts) still apply and may require pod restarts
299+
If secrets are synced to Kubernetes Secret objects, standard Reloader behavior applies and CSI support may not be required
300+
242301
## 🚀 Installation
243302

244303
### 1. 📦 Helm
@@ -430,7 +489,7 @@ PRs are welcome. In general, we follow the "fork-and-pull" Git workflow:
430489

431490
## Release Processes
432491

433-
_Repository GitHub releases_: As requested by the community in [issue 685](https://github.com/stakater/Reloader/issues/685), Reloader is now based on a manual release process. Releases are no longer done on every merged PR to the main branch, but manually on request.
492+
*Repository GitHub releases*: As requested by the community in [issue 685](https://github.com/stakater/Reloader/issues/685), Reloader is now based on a manual release process. Releases are no longer done on every merged PR to the main branch, but manually on request.
434493

435494
To make a GitHub release:
436495

@@ -443,7 +502,7 @@ To make a GitHub release:
443502
1. Code owners create another branch from `master` and bump the helm chart version as well as Reloader image version.
444503
- Code owners create a PR with `release/helm-chart` label, example: [PR-846](https://github.com/stakater/Reloader/pull/846)
445504

446-
_Repository git tagging_: Push to the main branch will create a merge-image and merge-tag named `merge-${{ github.event.number }}`, for example `merge-800` when pull request number 800 is merged.
505+
*Repository git tagging*: Push to the main branch will create a merge-image and merge-tag named `merge-${{ github.event.number }}`, for example `merge-800` when pull request number 800 is merged.
447506

448507
## Changelog
449508

deployments/kubernetes/chart/reloader/templates/clusterrole.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ rules:
105105
- create
106106
- get
107107
- update
108+
{{- end}}
109+
{{- if .Values.reloader.enableCSIIntegration }}
110+
- apiGroups:
111+
- "secrets-store.csi.x-k8s.io"
112+
resources:
113+
- secretproviderclasspodstatuses
114+
- secretproviderclasses
115+
verbs:
116+
- list
117+
- get
118+
- watch
108119
{{- end}}
109120
- apiGroups:
110121
- ""

deployments/kubernetes/chart/reloader/templates/deployment.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ spec:
210210
{{- . | toYaml | nindent 10 }}
211211
{{- end }}
212212
{{- end }}
213-
{{- if or (.Values.reloader.logFormat) (.Values.reloader.logLevel) (.Values.reloader.ignoreSecrets) (.Values.reloader.ignoreNamespaces) (include "reloader-namespaceSelector" .) (.Values.reloader.resourceLabelSelector) (.Values.reloader.ignoreConfigMaps) (.Values.reloader.custom_annotations) (eq .Values.reloader.isArgoRollouts true) (eq .Values.reloader.reloadOnCreate true) (eq .Values.reloader.reloadOnDelete true) (ne .Values.reloader.reloadStrategy "default") (.Values.reloader.enableHA) (.Values.reloader.autoReloadAll) (.Values.reloader.ignoreJobs) (.Values.reloader.ignoreCronJobs)}}
213+
{{- if or (.Values.reloader.logFormat) (.Values.reloader.logLevel) (.Values.reloader.ignoreSecrets) (.Values.reloader.ignoreNamespaces) (include "reloader-namespaceSelector" .) (.Values.reloader.resourceLabelSelector) (.Values.reloader.ignoreConfigMaps) (.Values.reloader.custom_annotations) (eq .Values.reloader.isArgoRollouts true) (eq .Values.reloader.reloadOnCreate true) (eq .Values.reloader.reloadOnDelete true) (ne .Values.reloader.reloadStrategy "default") (.Values.reloader.enableHA) (.Values.reloader.autoReloadAll) (.Values.reloader.ignoreJobs) (.Values.reloader.ignoreCronJobs) (.Values.reloader.enableCSIIntegration)}}
214214
args:
215215
{{- if .Values.reloader.logFormat }}
216216
- "--log-format={{ .Values.reloader.logFormat }}"
@@ -246,6 +246,9 @@ spec:
246246
- "--pprof-addr={{ .Values.reloader.pprofAddr }}"
247247
{{- end }}
248248
{{- end }}
249+
{{- if .Values.reloader.enableCSIIntegration }}
250+
- "--enable-csi-integration=true"
251+
{{- end }}
249252
{{- if .Values.reloader.custom_annotations }}
250253
{{- if .Values.reloader.custom_annotations.configmap }}
251254
- "--configmap-annotation"

deployments/kubernetes/chart/reloader/templates/role.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ rules:
9292
- create
9393
- get
9494
- update
95+
{{- end}}
96+
{{- if .Values.reloader.enableCSIIntegration }}
97+
- apiGroups:
98+
- "secrets-store.csi.x-k8s.io"
99+
resources:
100+
- secretproviderclasspodstatuses
101+
- secretproviderclasses
102+
verbs:
103+
- list
104+
- get
105+
- watch
95106
{{- end}}
96107
- apiGroups:
97108
- ""

deployments/kubernetes/chart/reloader/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ reloader:
4949
enableHA: false
5050
# Set to true to enable pprof for profiling
5151
enablePProf: false
52+
enableCSIIntegration: false
5253
# Address to start pprof server on. Default is ":6060"
5354
pprofAddr: ":6060"
5455
# Set to true if you have a pod security policy that enforces readOnlyRootFilesystem

docs/Reloader-vs-ConfigmapController.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
Reloader is inspired from [`configmapcontroller`](https://github.com/fabric8io/configmapcontroller) but there are many ways in which it differs from `configmapcontroller`. Below is the small comparison between these two controllers.
44

5-
| Reloader | ConfigMap |
6-
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7-
| Reloader can watch both `Secrets` and `ConfigMaps`. | `configmapcontroller` can only watch changes in `ConfigMaps`. It cannot detect changes in other resources like `Secrets`. |
8-
| Reloader can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` | `configmapcontroller` can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` |
9-
| Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any old functionality. | Currently there are not any unit test cases or end to end integration test cases in `configmap-controller`. It add difficulties for any additional updates in `configmap-controller` and one can not know for sure whether new changes breaks any old functionality or not. |
10-
| Reloader uses SHA1 to encode the change in `ConfigMap` or `Secret`. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is very less prone to collision. | `configmap-controller` uses `FABRICB_FOO_REVISION` environment variable to store any change in `ConfigMap` controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. |
11-
| Reloader allows you to customize your own annotation (for both `Secrets` and `ConfigMaps`) using command line flags | `configmap-controller` restricts you to only their provided annotation |
5+
| Reloader | ConfigMap |
6+
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7+
| Reloader can watch both `Secrets` and `ConfigMaps`. | `configmapcontroller` can only watch changes in `ConfigMaps`. It cannot detect changes in other resources like `Secrets`. |
8+
| Reloader can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` | `configmapcontroller` can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` |
9+
| Reloader provides both unit test cases and end to end integration test cases for future updates. So one can make sure that new changes do not break any old functionality. | Currently there are not any unit test cases or end to end integration test cases in `configmap-controller`. It adds difficulties for any additional updates in `configmap-controller` and one can not know for sure whether new changes breaks any old functionality or not. |
10+
| Reloader uses SHA1 to encode the change in `ConfigMap` or `Secret`. It then saves the SHA1 value in `STAKATER_FOO_CONFIGMAP` or `STAKATER_FOO_SECRET` environment variable depending upon where the change has happened. The use of SHA1 provides a concise 40 characters encoded value that is very less prone to collision. | `configmap-controller` uses `FABRICB_FOO_REVISION` environment variable to store any change in `ConfigMap` controller. It does not encode it or convert it in suitable hash value to avoid data pollution in deployment. |
11+
| Reloader allows you to customize your own annotation (for both `Secrets` and `ConfigMaps`) using command line flags | `configmap-controller` restricts you to only their provided annotation |

docs/Reloader-vs-k8s-trigger-controller.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Reloader and k8s-trigger-controller are both built for same purpose. So there ar
66

77
- Both controllers support change detection in `ConfigMaps` and `Secrets`
88
- Both controllers support deployment `rollout`
9-
- Both controllers use SHA1 for hashing
9+
- Reloader controller use SHA1 for hashing
1010
- Both controllers have end to end as well as unit test cases.
1111

1212
## Differences

0 commit comments

Comments
 (0)