Kubernetes applications need configuration, whether related to authentication with parameters such as API keys, tokens, or other credentials, or general parameters such as logging configuration, environment variables, or other flags. In Kubernetes, these are usually handled with ConfigMaps or Secrets. And configuration can be updated, whether it be for credential updates or rotation, or toggling logging on or off, or updating a particular environment parameter.
Updates may take place frequently or rarely depending on the application, and there will be cases where we would like such updates to be reflected immediately within our applications. As such a Kubernetes application would not be aware of an update to the ConfigMap or Secret, until they are reloaded as part of an update by their respective replica set. To this end, we require a controller which can watch changes for ConfigMaps and Secrets, and then automatically trigger updates on the dependent applications.
Enter Stakater Reloader. Reloader is a Kubernetes Controller built for this purpose. It watches changes in ConfigMap and Secrets and then updates Deployment, StatefulSet and DaemonSet, so that the new changes are loaded.
What to watch
Reloader watches the following resources in a cluster. These resources will generally contain configuration for an application, such as to specify the environment, other settings, or credentials for accessing external services, or internal user accounts.
What to reload
Such configuration may be used by applications, however dependent applications may not necessarily be part of a Deployment type. Reloader therefore supports triggering updates to the the following Kubernetes resources:
Normally these pods will be unaware of a change in the configuration parameters, until they are reloaded as part of an update by their respective replica set. With Reloader, the update can be triggered automatically, so that the new configuration is reflected in the application.
Comparison with similar controllers
Now you may have already used a similar controller on your cluster. There are other open-source tools developed by the community that handle similar use cases as Stakater Reloader, however shortcomings in these controllers have prompted our team to develop Reloader keeping in mind flexibility, extensibility, as well as stability.
k8s-trigger-controller is a tool with the same purpose as Stakater Reloader. There are a few similarities between the two, but a couple of differences as well.
Reloader is actually inspired from ConfigMapController but there are many ways in which it differs from ConfigMapController.
The following table shows a comparison of the three and illustrates where Stakater Reloader has the edge over the other two:
How it works
Reloader will watch Secrets and ConfigMaps. Whenever there is an update in either, Reloader will then check whether any Deployment, DaemonSet or StatefulSet is dependent on it. This dependency is managed using annotations:
`configmap.reloader.stakater.com/reload` for ConfigMap and `secret.reloader.stakater.com/reload` for Secret. As an example, if a Deployment ‘deployment-resource’ is annotated with `secret.reloader.stakater.com/reload: “secret-name”`, then once the Secret with name ‘secret-name’ is updated, Reloader will look for Deployments that have the respective annotation, in this case the ‘deployment-resource’, and it will evaluate this deployment for update.
For watching multiple configurations, we can also specify a comma separated list of secret or configmap names, e.g. `configmap.reloader.stakater.com/reload:configmap1,configmap2`. Reloader will then trigger the deployment to reload if either configmap1 or configmap2 is updated.
Verifying that a reload is needed
One more step is involved in determining whether a resource needs to be updated or not. To make sure that the deployment truly needs to be updated, and that an unnecessary update is not triggered, Reloader makes sure that the containers of the Deployment, do indeed have an outdated version of the ConfigMap. This is done by embedding a SHA1 encoded hash of the ConfigMap as an environment variable of the containers. Whenever evaluating the container for update, the previous value of the environment variable in the container is compared with the newly generated value from the updated ConfigMap. If the values differ, then that signals that there is a true change in the ConfigMap, and that the Deployment should indeed be updated.
Once determined that the Deployment should be updated, Reloader calls on the Kubernetes client to update the Deployment. The client uses the Update strategy that is specified in the manifest for the respective resource to update. If an update strategy is not explicitly defined in the manifest, the default strategy is used. In Kubernetes v1.11, the default strategy for Deployments and StatefulSets is the RollingUpdate strategy; and for DeamonSets it is the OnDelete strategy.
How to deploy
Deploying Stakater Reloader to you cluster is simple and can be done using the tool’s manifest yaml, or helm chart. The yaml and helm chart are available publicly as part of the git repository, or helm repository, and do not need to be downloaded explicitly.
Reloader can be deployed using the yaml with the following command:
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
Or Reloader can be deployed using helm charts from the Stakater chart repository:
helm repo add stakater https://stakater.github.io/stakater-charts helm repo update helm install stakater/reloader
By default Reloader will watch all namespaces, however this can be restricted if needed via the RBAC authorization, using the namespaces specified in the ClusterRole and ClusterRoleBinding. These changes can either be made manually in the manifest yaml, or can be generated by a helm command.
For yaml, the file can be edited in a text editor to modify the values for the namespace properties under ClusterRole, ClusterRoleBinding and ServiceAccount.
For helm, the following command can be executed with the charts folder path of the repository as one of the arguments. This generates a yaml with the namespace modified:
helm --namespace NAMESPACE template deployments/kubernetes/chart/reloader > reloader.yaml
After these changes, the resulting yaml can be applied with kubectl:
kubectl apply -f reloader.yaml
After Reloader is deployed, we can expect to see the following kind of event statements in the logs of Reloader whenever a change is detected in the configuration, and pods updated by Reloader:
Changes Detected in secret-name of type ‘SECRET’ in namespace: test-reloader Updated deployment-resource of type Deployment in namespace: test-reloader
Stakater Reloader has significant improvements compared to other similar open-source controllers. With its support for different resource types, open-source license, and stable code base, it is a good controller to use when pods need to be automatically restarted on configuration update.
More information is available at the Github repository: https://github.com/stakater/reloader