Skip to content

A Kubernetes controller to watch changes in ConfigMap and Secrets and do rolling upgrades on Pods with their associated Deployment, StatefulSet, DaemonSet and DeploymentConfig – [✩Star] if you're using it!

License

Notifications You must be signed in to change notification settings

stakater/Reloader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Repository files navigation

Reloader-logoReloader

Go Report Card Go Doc Release GitHub tag Docker Pulls Docker Stars license Get started with Stakater

Problem

We would like to watch if some change happens inConfigMapand/orSecret;then perform a rolling upgrade on relevantDeploymentConfig,Deployment,Daemonset,StatefulsetandRollout

Solution

Reloader can watch changes inConfigMapandSecretand do rolling upgrades on Pods with their associatedDeploymentConfigs,Deployments,DaemonsetsStatefulsetsandRollouts.

Enterprise Version

Reloader is available in two different versions:

  1. Open Source Version
  2. Enterprise Version, which includes:
    • SLA (Service Level Agreement) for support and unique requests
    • Slack support
    • Certified images

Contact[email protected]for info about Reloader Enterprise.

Compatibility

Reloader is compatible with Kubernetes >= 1.19

How to use Reloader

You have aDeploymentcalledfooand aConfigMapand/or aSecreteither mounted as a volume or defined as a environment variable. TheConfigMapandSecretcan be named whatever, but for the sake of this example, lets refer to theConfigMapasfoo-configmapand the secret asfoo-secret.

Add the annotation to the main metadata of yourDeployment.By default this would bereloader.stakater.com/auto.

kind:Deployment
metadata:
name:foo
annotations:
reloader.stakater.com/auto:"true"
spec:
template:
metadata:

This will discover deploymentconfigs/deployments/daemonsets/statefulset/rollouts automatically wherefoo-configmaporfoo-secretis being used either via environment variable or from volume mount. And it will perform rolling upgrade on related pods whenfoo-configmaporfoo-secretare updated.

You can filter it by the type of monitored resource and use typed versions ofautoannotation. If you want to discover changes only in mountedSecrets and ignore changes inConfigMaps, addsecret.reloader.stakater.com/autoannotation instead. Analogously, you can useconfigmap.reloader.stakater.com/autoannotation to look for changes in mountedConfigMap,changes in any of mountedSecrets will not trigger a rolling upgrade on related pods.

You can also restrict this discovery to onlyConfigMaporSecretobjects that are tagged with a special annotation. To take advantage of that, annotate your deploymentconfigs/deployments/daemonsets/statefulset/rollouts like this:

kind:Deployment
metadata:
annotations:
reloader.stakater.com/search:"true"
spec:
template:

and Reloader will trigger the rolling upgrade upon modification of any ConfigMaporSecretannotated like this:

kind:ConfigMap
metadata:
annotations:
reloader.stakater.com/match:"true"
data:
key:value

provided the secret/configmap is being used in an environment variable, or a volume mount.

Please note thatreloader.stakater.com/searchand reloader.stakater.com/autodo not work together. If you have the reloader.stakater.com/auto: "true"annotation on your deployment, then it will always restart upon a change in configmaps or secrets it uses, regardless of whether they have thereloader.stakater.com/match: "true"annotation or not.

Similarly,reloader.stakater.com/autoand its typed version (secret.reloader.stakater.com/autoorconfigmap.reloader.stakater.com/auto) do not work together. If you have both annotations in your deployment, then only one of them needs to be true to trigger the restart. For example, having bothreloader.stakater.com/auto: "true"andsecret.reloader.stakater.com/auto: "false"or bothreloader.stakater.com/auto: "false"andsecret.reloader.stakater.com/auto: "true"will restart upon a change in a secret it uses.

We can also specify a specific configmap or secret which would trigger rolling upgrade only upon change in our specified configmap or secret, this way, it will not trigger rolling upgrade upon changes in all configmaps or secrets used in adeploymentconfig,deployment,daemonset,statefulsetorrollout. To do this either set the auto annotation to"false"(reloader.stakater.com/auto: "false") or remove it altogether, and use annotations forConfigmaporSecret.

It's also possible to enable auto reloading for all resources, by setting the--auto-reload-allflag. In this case, all resources that do not have the auto annotation (or its typed version) set to"false",will be reloaded automatically when their ConfigMaps or Secrets are updated. Notice that setting the auto annotation to an undefined value counts as false as-well.

Configmap

To perform rolling upgrade when change happens only on specific configmaps use below annotation.

For aDeploymentcalledfoohave aConfigMapcalledfoo-configmap.Then add this annotation to main metadata of yourDeployment

kind:Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload:"foo-configmap"
spec:
template:
metadata:

Use comma separated list to define multiple configmaps.

kind:Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload:"foo-configmap,bar-configmap,baz-configmap"
spec:
template:
metadata:

Secret

To perform rolling upgrade when change happens only on specific secrets use below annotation.

For aDeploymentcalledfoohave aSecretcalledfoo-secret.Then add this annotation to main metadata of yourDeployment

kind:Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload:"foo-secret"
spec:
template:
metadata:

Use comma separated list to define multiple secrets.

kind:Deployment
metadata:
annotations:
secret.reloader.stakater.com/reload:"foo-secret,bar-secret,baz-secret"
spec:
template:
metadata:

NOTES

  • Reloader also supportssealed-secrets.Hereare the steps to use sealed-secrets with Reloader.
  • ForrolloutsReloader simply triggers a change is up to you how you configure therolloutstrategy.
  • reloader.stakater.com/auto: "true"will only reload the pod, if the configmap or secret is used (as a volume mount or as an env) inDeploymentConfigs/Deployment/Daemonsets/Statefulsets
  • secret.reloader.stakater.com/reloadorconfigmap.reloader.stakater.com/reloadannotation will reload the pod upon changes in specified configmap or secret, irrespective of the usage of configmap or secret.
  • you may override the auto annotation with the--auto-annotationflag
  • you may override the secret typed auto annotation with the--secret-auto-annotationflag
  • you may override the configmap typed auto annotation with the--configmap-auto-annotationflag
  • you may override the search annotation with the--auto-search-annotationflag and the match annotation with the--search-match-annotationflag
  • you may override the configmap annotation with the--configmap-annotationflag
  • you may override the secret annotation with the--secret-annotationflag
  • you may want to prevent watching certain namespaces with the--namespaces-to-ignoreflag
  • you may want to watch only a set of namespaces with certain labels by using the--namespace-selectorflag
  • you may want to watch only a set of secrets/configmaps with certain labels by using the--resource-label-selectorflag
  • you may want to prevent watching certain resources with the--resources-to-ignoreflag
  • you can configure logging in JSON format with the--log-format=jsonoption
  • you can configure the "reload strategy" with the--reload-strategy=<strategy-name>option (details below)

Reload Strategies

Reloader supports multiple "reload" strategies for performing rolling upgrades to resources. The following list describes them:

  • env-vars:When a trackedconfigMap/secretis updated, this strategy attaches a Reloader specific environment variable to any containers referencing the changedconfigMaporsecreton the owning resource (e.g.,Deployment,StatefulSet,etc.). This strategy can be specified with the--reload-strategy=env-varsargument. Note: This is the default reload strategy.
  • annotations:When a trackedconfigMap/secretis updated, this strategy attaches areloader.stakater.com/last-reloaded-frompod template annotation on the owning resource (e.g.,Deployment,StatefulSet,etc.). This strategy is useful when using resource syncing tools like ArgoCD, since it will not cause these tools to detect configuration drift after a resource is reloaded. Note: Since the attached pod template annotation only tracks the last reload source, this strategy will reload any tracked resource should itsconfigMaporsecretbe deleted and recreated. This strategy can be specified with the--reload-strategy=annotationsargument.

Deploying to Kubernetes

You can deploy Reloader by following methods:

Vanilla Manifests

You can apply vanilla manifests by changingRELEASE-NAMEplaceholder provided in manifest with a proper value and apply it by running the command given below:

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

By default, Reloader gets deployed indefaultnamespace and watches changessecretsandconfigmapsin all namespaces. Additionally, in the default Reloader deployment, the following resource limits and requests are set:

resources:
limits:
cpu:150m
memory:512Mi
requests:
cpu:10m
memory:128Mi

Reloader can be configured to ignore the resourcessecretsandconfigmapsby passing the following arguments (spec.template.spec.containers.args) to its container:

Argument Description
--resources-to-ignore=configMaps To ignore configMaps
--resources-to-ignore=secrets To ignore secrets

Note:At one time only one of these resource can be ignored, trying to do it will cause error in Reloader. Workaround for ignoring both resources is by scaling down the Reloader pods to0.

Reloader can be configured to only watch secrets/configmaps with one or more labels using the--resource-label-selectorparameter. Supported operators are!, in, notin, ==, =,!=,if no operator is found the 'exists' operator is inferred (i.e. key only). Additional examples of these selectors can be found in theKubernetes Docs.

Note:The old:delimited key value mappings are deprecated and if provided will be translated tokey=value.Likewise, if a wildcard value is provided (e.g.key:*) it will be translated to the standalonekeywhich checks for key existence.

These selectors can be combined, for example with:

--resource-label-selector=reloader=enabled,key-exists,another-label in (value1,value2,value3)

Only configmaps or secrets labeled like the following will be watched:

kind:ConfigMap
apiVersion:v1
metadata:
labels:
reloader:enabled
key-exists:yes
another-label:value1

Reloader can be configured to only watch namespaces labeled with one or more labels using the--namespace-selectorparameter. Supported operators are!, in, notin, ==, =,!=,if no operator is found the 'exists' operator is inferred (i.e. key only). Additional examples of these selectors can be found in theKubernetes Docs.

Note:The old:delimited key value mappings are deprecated and if provided will be translated tokey=value.Likewise, if a wildcard value is provided (e.g.key:*) it will be translated to the standalonekeywhich checks for key existence.

These selectors can be combined, for example with:

--namespace-selector=reloader=enabled,test=true

Only namespaces labeled as below would be watched and eligible for reloads:

kind:Namespace
apiVersion:v1
metadata:
labels:
reloader:enabled
test:true

Vanilla Kustomize

You can also apply the vanilla manifests by running the following command

kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes

Similarly to vanilla manifests get deployed indefaultnamespace and watches changessecretsandconfigmapsin all namespaces.

Kustomize

You can write your ownkustomization.yamlusing ours as a 'base' and write patches to tweak the configuration.

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

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

namespace:reloader

Helm Charts

Alternatively if you have configured helm on your cluster, you can add Reloader to helm from our public chart repository and deploy it via helm using below-mentioned commands. Followthisguide, in case you have trouble migrating Reloader from Helm2 to Helm3.

Installation

helm repo add stakater https://stakater.github.io/stakater-charts

helm repo update

helm install stakater/reloader#For helm3 add --generate-name flag or set the release name

helm install {{RELEASE_NAME}} stakater/reloader -n {{NAMESPACE}} --set reloader.watchGlobally=false#By default, Reloader watches in all namespaces. To watch in single namespace, set watchGlobally=false

helm install stakater/reloader --set reloader.watchGlobally=false --namespacetest--generate-name#Install Reloader in `test` namespace which will only watch `Deployments`, `Daemonsets` `Statefulsets` and `Rollouts` in `test` namespace.

Uninstalling

helm uninstall {{RELEASE_NAME}} -n {{NAMESPACE}}

Parameters

Global Parameters

Parameter Description Type Default
global.imagePullSecrets Reference to one or more secrets to be used when pulling images array []

Common Parameters

Parameter Description Type Default
nameOverride replace the name of the chart string ""
fullnameOverride replace the generated name string ""

Core Reloader Parameters

Parameter Description Type Default
reloader.autoReloadAll boolean false
reloader.isArgoRollouts Enable ArgoRollouts.Valid value are eithertrueorfalse boolean false
reloader.isOpenshift Enable OpenShift DeploymentConfigs. Valid value are eithertrueorfalse boolean false
reloader.ignoreSecrets To ignore secrets. Valid value are eithertrueorfalse.EitherignoreSecretsorignoreConfigMapscan be ignored, not both at the same time boolean false
reloader.ignoreConfigMaps To ignore configMaps. Valid value are eithertrueorfalse boolean false
reloader.reloadOnCreate Enable reload on create events. Valid value are eithertrueorfalse boolean false
reloader.reloadOnDelete Enable reload on delete events. Valid value are eithertrueorfalse boolean false
reloader.syncAfterRestart Enable sync after Reloader restarts forAddevents, works only when reloadOnCreate istrue.Valid value are eithertrueorfalse boolean false
reloader.reloadStrategy Strategy to trigger resource restart, set to eitherdefault,env-varsorannotations enumeration default
reloader.ignoreNamespaces List of comma separated namespaces to ignore, if multiple are provided, they are combined with the AND operator string ""
reloader.namespaceSelector List of comma separated namespaces to select, if multiple are provided, they are combined with the AND operator string ""
reloader.resourceLabelSelector List of comma separated label selectors, if multiple are provided they are combined with the AND operator string ""
reloader.logFormat Set type of log format. Value could be eitherjsonor"" string ""
reloader.watchGlobally Allow Reloader to watch in all namespaces (true) or just in a single namespace (false) boolean true
reloader.enableHA Enable leadership election allowing you to run multiple replicas boolean false
reloader.readOnlyRootFileSystem Enforce readOnlyRootFilesystem boolean false
reloader.legacy.rbac boolean false
reloader.matchLabels Pod labels to match map {}
reloader.enableMetricsByNamespace Expose an additional Prometheus counter of reloads by namespace (this metric may have high cardinality in clusters with many namespaces) boolean false

Deployment Reloader Parameters

Parameter Description Type Default
reloader.deployment.replicas Number of replicas, if you wish to run multiple replicas setreloader.enableHA = true int 1
reloader.deployment.revisionHistoryLimit Limit the number of revisions retained in the revision history int 2
reloader.deployment.nodeSelector Scheduling pod to a specific node based on set labels map {}
reloader.deployment.affinity Set affinity rules on pod map {}
reloader.deployment.securityContext Set pod security context map {}
reloader.deployment.containerSecurityContext Set container security context map {}
reloader.deployment.tolerations A list oftolerationsto be applied to the deployment array []
reloader.deployment.topologySpreadConstraints Topology spread constraints for pod assignment array []
reloader.deployment.annotations Set deployment annotations map {}
reloader.deployment.labels Set deployment labels, default to stakater settings array see values.yaml
reloader.deployment.image Set container image name, tag and policy array see values.yaml
reloader.deployment.env Support for extra environment variables array []
reloader.deployment.livenessProbe Set liveness probe timeout values map {}
reloader.deployment.readinessProbe Set readiness probe timeout values map {}
reloader.deployment.resources Set container requests and limits (e.g. CPU or memory) map {}
reloader.deployment.pod.annotations Set annotations for pod map {}
reloader.deployment.priorityClassName Set priority class for pod in cluster string ""

Other Reloader Parameters

Parameter Description Type Default
reloader.service map {}
reloader.rbac.enabled Specifies whether a role based access control should be created boolean true
reloader.serviceAccount.create Specifies whether a ServiceAccount should be created boolean true
reloader.custom_annotations Add custom annotations map {}
reloader.serviceMonitor.enabled Enable to scrape Reloader's Prometheus metrics (legacy) boolean false
reloader.podMonitor.enabled Enable to scrape Reloader's Prometheus metrics boolean false
reloader.podDisruptionBudget.enabled Limit the number of pods of a replicated application boolean false
reloader.netpol.enabled boolean false
reloader.volumeMounts Mount volume array []
reloader.volumes Add volume to a pod array []
reloader.webhookUrl Add webhook to Reloader string ""

Additional Remarks

  • BothnamespaceSelector&resourceLabelSelectorcan be used together. If they are then both conditions must be met for the configmap or secret to be eligible to trigger reload events. (e.g. If a configMap matchesresourceLabelSelectorbutnamespaceSelectordoes not match the namespace the configmap is in, it will be ignored).
  • At one time only one of the resourcesignoreConfigMapsorignoreSecretscan be ignored, trying to do both will cause error in helm template compilation
  • Reloading of OpenShift (DeploymentConfig) and/or ArgoRolloutshas to be enabled explicitly because it might not be always possible to use it on a cluster with restricted permissions
  • isOpenShiftRecent versions of OpenShift (tested on 4.13.3) require the specified user to be in anuidrange which is dynamically assigned by the namespace. The solution is to unset the runAsUser variable viadeployment.securityContext.runAsUser=nulland let OpenShift assign it at install
  • reloadOnCreatecontrols how Reloader handles secrets being added to the cache for the first time. IfreloadOnCreateis set to true:
    1. Configmaps/secrets being added to the cache will cause Reloader to perform a rolling update of the associated workload
    2. When applications are deployed for the first time, Reloader will perform a rolling update of the associated workload
    3. If you are running Reloader in HA mode all workloads will have a rolling update performed when a new leader is elected
  • reloadOnDeletecontrols how Reloader handles secrets being deleted. IfreloadOnDeleteis set to true:
    1. Configmaps/secrets being deleted will cause Reloader to perform a rolling update of the associated workload
  • serviceMonitorwill be removed in future releases of Reloader in favour of Pod monitor
  • IfreloadOnCreateis set to false:
    1. Updates to configmaps/secrets that occur while there is no leader will not be picked up by the new leader until a subsequent update of the configmap/secret occurs
    2. In the worst case the window in which there can be no leader is 15s as this is the LeaseDuration
  • IfreloadOnDeleteis set to false:
    1. Deleting of configmaps/secrets has no effect to pods that references these resources.
  • By default,reloadOnCreate,reloadOnDeleteandsyncAfterRestartare all set to false. All need to be enabled explicitly

Help

Documentation

You can find more documentationhere

Have a question?

File a GitHubissue.

Talk to us on Slack

Join and talk to us on Slack for discussing Reloader

Join Slack Chat

Contributing

Bug Reports & Feature Requests

Please use theissue trackerto report any bugs or file feature requests.

Developing

  1. Deploy Reloader.
  2. Runokteto upto activate your development container.
  3. make build
  4. ./Reloader

PRs are welcome. In general, we follow the "fork-and-pull" Git workflow.

  1. Forkthe repo on GitHub
  2. Clonethe project to your own machine
  3. Commitchanges to your own branch
  4. Pushyour work back up to your fork
  5. Submit aPull requestso that we can review your changes

NOTE:Be sure to merge the latest from "upstream" before making a pull request!

Release Processes

Repository GitHub releases:As requested by the community inissue 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. When a GitHub release is made, the corresponding image is built and pushed to the registry.

Repository git tagging:The Reloader repository is tagged on every push to main. The creation of a tag does not trigger anything else, it just acts as a pointer to a commit on main.

Helm chart versioning:The Reloader Helm chart release process is stillwork in progress.This page will be updated when the process is settled. As a heads-up, to address the issues that are inherent in the current process the chart will most probably be relocated to theStakater charts repository.This setup is common in open-source repositories. When a GitHub release has been manually created in this repository, an image will be built, and Renovate in the charts repository will update the Helm chart to use it.

Changelog

View our closedPull Requests.

License

Apache2 ©Stakater

About

Reloaderis maintained byStakater.Like it? Please let us know at[email protected]

Seeour other projects or contact us in case of professional services and queries on[email protected]

Acknowledgements