Home

Awesome

Reloader-logo Reloader

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 in ConfigMap and/or Secret; then perform a rolling upgrade on relevant DeploymentConfig, Deployment, Daemonset, Statefulset and Rollout

Solution

Reloader can watch changes in ConfigMap and Secret and do rolling upgrades on Pods with their associated DeploymentConfigs, Deployments, Daemonsets Statefulsets and Rollouts.

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 sales@stakater.com for info about Reloader Enterprise.

Compatibility

Reloader is compatible with Kubernetes >= 1.19

How to use Reloader

You have a Deployment called foo and a ConfigMap and/or a Secret either mounted as a volume or defined as a environment variable. The ConfigMap and Secret can be named whatever, but for the sake of this example, lets refer to the ConfigMap as foo-configmap and the secret as foo-secret.

Add the annotation to the main metadata of your Deployment. By default this would be reloader.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 where foo-configmap or foo-secret is being used either via environment variable or from volume mount. And it will perform rolling upgrade on related pods when foo-configmap or foo-secretare updated.

You can filter it by the type of monitored resource and use typed versions of auto annotation. If you want to discover changes only in mounted Secrets and ignore changes in ConfigMaps, add secret.reloader.stakater.com/auto annotation instead. Analogously, you can use configmap.reloader.stakater.com/auto annotation to look for changes in mounted ConfigMap, changes in any of mounted Secrets will not trigger a rolling upgrade on related pods.

You can also restrict this discovery to only ConfigMap or Secret objects 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 ConfigMap or Secret annotated 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 that reloader.stakater.com/search and reloader.stakater.com/auto do 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 the reloader.stakater.com/match: "true" annotation or not.

Similarly, reloader.stakater.com/auto and its typed version (secret.reloader.stakater.com/auto or configmap.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 both reloader.stakater.com/auto: "true" and secret.reloader.stakater.com/auto: "false" or both reloader.stakater.com/auto: "false" and secret.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 a deploymentconfig, deployment, daemonset, statefulset or rollout. To do this either set the auto annotation to "false" (reloader.stakater.com/auto: "false") or remove it altogether, and use annotations for Configmap or Secret.

It's also possible to enable auto reloading for all resources, by setting the --auto-reload-all flag. 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 a Deployment called foo have a ConfigMap called foo-configmap. Then add this annotation to main metadata of your Deployment

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 a Deployment called foo have a Secret called foo-secret. Then add this annotation to main metadata of your Deployment

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

Reload Strategies

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

Deploying to Kubernetes

You can deploy Reloader by following methods:

Vanilla Manifests

You can apply vanilla manifests by changing RELEASE-NAME placeholder 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 in default namespace and watches changes secrets and configmaps in 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 resources secrets and configmaps by passing the following arguments (spec.template.spec.containers.args) to its container:

ArgumentDescription
--resources-to-ignore=configMapsTo ignore configMaps
--resources-to-ignore=secretsTo 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 to 0.

Reloader can be configured to only watch secrets/configmaps with one or more labels using the --resource-label-selector parameter. 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 the Kubernetes Docs.

Note: The old : delimited key value mappings are deprecated and if provided will be translated to key=value. Likewise, if a wildcard value is provided (e.g. key:*) it will be translated to the standalone key which 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-selector parameter. 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 the Kubernetes Docs.

Note: The old : delimited key value mappings are deprecated and if provided will be translated to key=value. Likewise, if a wildcard value is provided (e.g. key:*) it will be translated to the standalone key which 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 in default namespace and watches changes secrets and configmaps in all namespaces.

Kustomize

You can write your own kustomization.yaml using 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. Follow this guide, 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 --namespace test --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

ParameterDescriptionTypeDefault
global.imagePullSecretsReference to one or more secrets to be used when pulling imagesarray[]

Common Parameters

ParameterDescriptionTypeDefault
nameOverridereplace the name of the chartstring""
fullnameOverridereplace the generated namestring""

Core Reloader Parameters

ParameterDescriptionTypeDefault
reloader.autoReloadAllbooleanfalse
reloader.isArgoRolloutsEnable Argo Rollouts. Valid value are either true or falsebooleanfalse
reloader.isOpenshiftEnable OpenShift DeploymentConfigs. Valid value are either true or falsebooleanfalse
reloader.ignoreSecretsTo ignore secrets. Valid value are either true or false. Either ignoreSecrets or ignoreConfigMaps can be ignored, not both at the same timebooleanfalse
reloader.ignoreConfigMapsTo ignore configMaps. Valid value are either true or falsebooleanfalse
reloader.reloadOnCreateEnable reload on create events. Valid value are either true or falsebooleanfalse
reloader.reloadOnDeleteEnable reload on delete events. Valid value are either true or falsebooleanfalse
reloader.syncAfterRestartEnable sync after Reloader restarts for Add events, works only when reloadOnCreate is true. Valid value are either true or falsebooleanfalse
reloader.reloadStrategyStrategy to trigger resource restart, set to either default, env-vars or annotationsenumerationdefault
reloader.ignoreNamespacesList of comma separated namespaces to ignore, if multiple are provided, they are combined with the AND operatorstring""
reloader.namespaceSelectorList of comma separated namespaces to select, if multiple are provided, they are combined with the AND operatorstring""
reloader.resourceLabelSelectorList of comma separated label selectors, if multiple are provided they are combined with the AND operatorstring""
reloader.logFormatSet type of log format. Value could be either json or ""string""
reloader.watchGloballyAllow Reloader to watch in all namespaces (true) or just in a single namespace (false)booleantrue
reloader.enableHAEnable leadership election allowing you to run multiple replicasbooleanfalse
reloader.readOnlyRootFileSystemEnforce readOnlyRootFilesystembooleanfalse
reloader.legacy.rbacbooleanfalse
reloader.matchLabelsPod labels to matchmap{}
reloader.enableMetricsByNamespaceExpose an additional Prometheus counter of reloads by namespace (this metric may have high cardinality in clusters with many namespaces)booleanfalse

Deployment Reloader Parameters

ParameterDescriptionTypeDefault
reloader.deployment.replicasNumber of replicas, if you wish to run multiple replicas set reloader.enableHA = trueint1
reloader.deployment.revisionHistoryLimitLimit the number of revisions retained in the revision historyint2
reloader.deployment.nodeSelectorScheduling pod to a specific node based on set labelsmap{}
reloader.deployment.affinitySet affinity rules on podmap{}
reloader.deployment.securityContextSet pod security contextmap{}
reloader.deployment.containerSecurityContextSet container security contextmap{}
reloader.deployment.tolerationsA list of tolerations to be applied to the deploymentarray[]
reloader.deployment.topologySpreadConstraintsTopology spread constraints for pod assignmentarray[]
reloader.deployment.annotationsSet deployment annotationsmap{}
reloader.deployment.labelsSet deployment labels, default to stakater settingsarraysee values.yaml
reloader.deployment.imageSet container image name, tag and policyarraysee values.yaml
reloader.deployment.envSupport for extra environment variablesarray[]
reloader.deployment.livenessProbeSet liveness probe timeout valuesmap{}
reloader.deployment.readinessProbeSet readiness probe timeout valuesmap{}
reloader.deployment.resourcesSet container requests and limits (e.g. CPU or memory)map{}
reloader.deployment.pod.annotationsSet annotations for podmap{}
reloader.deployment.priorityClassNameSet priority class for pod in clusterstring""

Other Reloader Parameters

ParameterDescriptionTypeDefault
reloader.servicemap{}
reloader.rbac.enabledSpecifies whether a role based access control should be createdbooleantrue
reloader.serviceAccount.createSpecifies whether a ServiceAccount should be createdbooleantrue
reloader.custom_annotationsAdd custom annotationsmap{}
reloader.serviceMonitor.enabledEnable to scrape Reloader's Prometheus metrics (legacy)booleanfalse
reloader.podMonitor.enabledEnable to scrape Reloader's Prometheus metricsbooleanfalse
reloader.podDisruptionBudget.enabledLimit the number of pods of a replicated applicationbooleanfalse
reloader.netpol.enabledbooleanfalse
reloader.volumeMountsMount volumearray[]
reloader.volumesAdd volume to a podarray[]
reloader.webhookUrlAdd webhook to Reloaderstring""

Additional Remarks

Help

Documentation

You can find more documentation here

Have a question?

File a GitHub issue.

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 the issue tracker to report any bugs or file feature requests.

Developing

  1. Deploy Reloader.
  2. Run okteto up to activate your development container.
  3. make build
  4. ./Reloader

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

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. Submit a Pull request so 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 in issue 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 still work 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 the Stakater 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 closed Pull Requests.

License

Apache2 © Stakater

About

Reloader is maintained by Stakater. Like it? Please let us know at hello@stakater.com

See our other projects or contact us in case of professional services and queries on hello@stakater.com

Acknowledgements