-
Notifications
You must be signed in to change notification settings - Fork 317
docs: Document auto-restart of pods on secret rotation #1648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ewan-chalmers
wants to merge
21
commits into
kubernetes-sigs:main
Choose a base branch
from
ewan-chalmers:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+133
−1
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
06db65b
auto-restart
ewan-chalmers ea92357
auto-restart
ewan-chalmers ea08454
Merge branch 'main' of https://github.com/ewan-chalmers/csi-auto-restart
ewan-chalmers 6b943eb
Merge branch 'main' of https://github.com/ewan-chalmers/csi-auto-restart
ewan-chalmers 4d17d7a
Merge branch 'main' of https://github.com/ewan-chalmers/csi-auto-restart
ewan-chalmers c2ad53a
mermaid
ewan-chalmers 9d930b1
mermaid
ewan-chalmers d830b7f
mermaid
ewan-chalmers ed41ab2
mermaid
ewan-chalmers 62be1fb
mermaid
ewan-chalmers 251459e
mermaid
ewan-chalmers bd0c93f
mermaid
ewan-chalmers 35070d9
mermaid
ewan-chalmers ba3aa84
mermaid
ewan-chalmers dd84820
caveat
ewan-chalmers be216d3
Merge branch 'main' of https://github.com/ewan-chalmers/csi-auto-restart
ewan-chalmers ab3b512
Apply suggestions from code review
ewan-chalmers f92bf62
review comment
ewan-chalmers f85a10a
review comment
ewan-chalmers b25eeb7
review comments
ewan-chalmers 57cf852
review comments: caveat
ewan-chalmers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Auto restart of pods when secret is rotated | ||
|
||
> NOTE: This is a suggested implementation that can be used alongside the Secrets Store CSI Driver. This solution is neither supported nor tested by the Secrets Store CSI Driver project. | ||
|
||
When [auto rotation of secrets](./secret-auto-rotation.md) is enabled, workloads that depend on secrets will need to either: | ||
- watch for updates to the secrets and reload these in their runtime, or | ||
- be restarted to pick up the latest secrets when they change | ||
|
||
A solution like [Reloader](https://github.com/stakater/Reloader) can watch updates to Kubernetes Secrets or ConfigMaps and restart pods when a change is detected. However, if secret values are mounted as volumes in the pods, that solution is not suitable. | ||
|
||
Using custom resources created by the Secrets Store CSI Driver, a Kubernetes controller can detect when secrets are updated by the driver and restart the associated pods. | ||
|
||
> NOTE: The suggested implementation will result in an increase in secret store reads and secret writes (k8s mounts) by the Secrets Store CSI Driver. Each time the driver updates a mounted secret and the controller subsequently restarts the associated pod, the driver will then read and mount the secret _again_ for the newly created pod. This undesirable consequence ahould be weighed against the convenience of enabling workloads to be reloaded with updated secrets, without code changes. | ||
|
||
## SecretProviderClassPodStatus custom resource | ||
|
||
The relevant custom resource is [`SecretProviderClassPodStatus`](../concepts#secretproviderclasspodstatus). | ||
|
||
Each `SecretProviderClassPodStatus` custom resource (CR) has a one-to-one relationship with a pod that references secrets using a Secrets Store CSI Driver [SecretProviderClass](../concepts#secretproviderclass). The CR includes the pod name, namespace and other attributes. The driver manages the lifecycle of `SecretProviderClassPodStatus` which is tied to the lifecycle of the associated pod. | ||
|
||
```mermaid | ||
stateDiagram-v2 | ||
state "SecretProviderClassPodStatus\nGeneration: 1" as g1 | ||
state "SecretProviderClassPodStatus\nGeneration: n" as gn | ||
|
||
[*] --> g1: pod create with secret from csi | ||
g1 --> gn: secret updated in pod | ||
gn --> [*]: pod restart | ||
``` | ||
|
||
When the driver sets a secret value for a new pod, a `SecretProviderClassPodStatus` CR is created with the `Generation` attribute set to `1`. | ||
|
||
Whenever the driver updates the secret value, the value of the `Generation` attribute is incremented. | ||
|
||
If a pod is restarted, the CR is deleted and a new CR created with `Generation: 1`. | ||
|
||
`SecretProviderClassPodStatus` CRs persist across lifetimes of the secrets-store-csi-driver. | ||
|
||
## Outline of Controller function | ||
|
||
1. Reconcile | ||
|
||
The controller reconciles instances of the `SecretProviderClassPodStatus` CR and deletes (to restart) the associated pod if required. | ||
|
||
If a `SecretProviderClassPodStatus` has `Generation: 1`, it is linked to a newly created pod. The pod should not be restarted. | ||
|
||
If a `SecretProviderClassPodStatus` has `Generation` > 1, it is linked to a pod in which the secrets-store-csi-driver has updated a secret. The pod should be restarted (if it has opted-in for automatic restarting). | ||
|
||
1. Rolling restart | ||
|
||
On reconciling a pod which should be updated, check `metadata.ownerReferences` and walk up to a Deployment (or similar) if present. | ||
|
||
If a `Deployment` is found: | ||
|
||
- Do not restart pod | ||
- Update the Deployment to trigger a rolling restart | ||
- If the number of replicas > 1, update the Deployment once only | ||
|
||
To restart a deployment, the controller sets a timestamped annotation in the deployment | ||
|
||
``` | ||
template: | ||
metadata: | ||
annotations: | ||
my.controller/restartedAt: "2024-09-05T14:06:29Z" | ||
``` | ||
|
||
Else: delete pod. | ||
|
||
1. Opt-in to automatic pod restarting | ||
|
||
Automatic restarting of pods when secrets are updated could be an opt-in behaviour. Unless the pod declares its opt-in, it should not be restarted by the controller. | ||
|
||
The opt-in could be indicated via an optional annotation set on the pod: | ||
``` | ||
kind: pod | ||
metadata: | ||
annotations: | ||
my.controller/restartOnChange: true | ||
``` | ||
|
||
## Implementation notes | ||
|
||
The [operator-sdk](https://github.com/operator-framework/operator-sdk) can be used to scaffold an implementation project. | ||
|
||
1. Scaffolding the project | ||
|
||
``` | ||
operator-sdk init --repo=<your repo> | ||
operator-sdk create api --version v1alpha1 --kind SecretProviderClassPodStatus --resource=false --controller=true | ||
``` | ||
|
||
1. Custom resources | ||
|
||
The controller does not manage custom resources of its own. It simply watches a custom resource provided by the Secrets Store CSI Driver. | ||
|
||
1. Permissions required | ||
|
||
The controller requires RBAC permissions to operate on various k8s resources. | ||
|
||
To watch `SecretProviderClassPodStatus` | ||
``` | ||
// +kubebuilder:rbac:groups=secrets-store.csi.x-k8s.io,resources=secretproviderclasspodstatuses,verbs=get;list;watch | ||
``` | ||
|
||
To lookup and if necessary delete `Pod` | ||
``` | ||
// +kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;delete | ||
``` | ||
|
||
To lookup possible owner of `Pod` | ||
``` | ||
// +kubebuilder:rbac:groups="apps",resources=daemonsets,verbs=get;list;watch | ||
// +kubebuilder:rbac:groups="apps",resources=replicasets,verbs=get;list;watch | ||
// +kubebuilder:rbac:groups="apps",resources=statefulsets,verbs=get;list;watch | ||
// +kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch | ||
``` | ||
|
||
To lookup and if necessary trigger update of `Deployment` | ||
``` | ||
// +kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch;update | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.