mirror of
https://github.com/stakater/Reloader.git
synced 2026-02-14 18:09:50 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64d12a7c31 | ||
|
|
078fc034d2 | ||
|
|
a3125e876c | ||
|
|
2f56d5c05b | ||
|
|
003eaee887 | ||
|
|
3030ddebf1 | ||
|
|
aa8b415fd4 | ||
|
|
d5c66bc235 | ||
|
|
9bc62e1f4e | ||
|
|
1bd5fb5620 | ||
|
|
4b233872bb | ||
|
|
569c0469fe | ||
|
|
599ceafd6b | ||
|
|
30ca4b463a | ||
|
|
e4756034ea |
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/groovy
|
||||
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.2')
|
||||
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.3')
|
||||
|
||||
def dummy
|
||||
|
||||
|
||||
38
README.md
38
README.md
@@ -2,11 +2,11 @@
|
||||
|
||||
## Problem
|
||||
|
||||
We would like to watch if some change happens in `ConfigMap` and `Secret` objects and then perform certain upgrade on relevant `Deployment`, `Deamonset` and `Statefulset`
|
||||
We would like to watch if some change happens in `ConfigMap` and `Secret` objects and then perform rolling upgrade on relevant `Deployment`, `Deamonset` and `Statefulset`
|
||||
|
||||
## Solution
|
||||
|
||||
Reloader can watch any changes in `ConfigMap` and `Secret` objects and update or recreate Pods for their associated `Deployments`, `Deamonsets` and `Statefulsets`. In this way Pods can get the latest changes in `ConfigMap` or `Secret` objects.
|
||||
Reloader can watch changes in `ConfigMap` and `Secret` and do rolling upgrades on Pods with their associated `Deployments`, `Deamonsets` and `Statefulsets`.
|
||||
|
||||
**NOTE:** This controller has been inspired from [configmapController](https://github.com/fabric8io/configmapcontroller)
|
||||
|
||||
@@ -30,39 +30,33 @@ metadata:
|
||||
secret.reloader.stakater.com/reload: "foo"
|
||||
```
|
||||
|
||||
Then, providing `Reloader` is running, whenever you edit the `ConfigMap` or `Secret` called `foo` the Reloader will update the `Deployment` by adding the environment variable:
|
||||
|
||||
```
|
||||
STAKATER_FOO_REVISION=${reloaderRevision}
|
||||
```
|
||||
|
||||
This then triggers a rolling upgrade of your deployment's pods to use the new configuration.
|
||||
|
||||
Same procedure can be followed to perform rolling upgrade on `Deamonsets` and `Statefulsets` as well.
|
||||
|
||||
## Deploying to Kubernetes
|
||||
|
||||
You can deploy Reloader by running the following kubectl commands:
|
||||
|
||||
```bash
|
||||
kubectl apply -f rbac.yaml -n <namespace>
|
||||
kubectl apply -f deployment.yaml -n <namespace>
|
||||
```
|
||||
You can deploy Reloader by following methods:
|
||||
|
||||
### Vanilla Manifests
|
||||
|
||||
You can apply vanilla manifests by running the following command
|
||||
|
||||
```bash
|
||||
kubecl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
|
||||
```
|
||||
|
||||
### Helm Charts
|
||||
|
||||
Or alternatively if you configured `helm` on your cluster, you can deploy Reloader via helm chart located under `deployments/kubernetes/chart/reloader` folder.
|
||||
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
|
||||
|
||||
### Monitor All namespaces
|
||||
You can monitor all namespaces in cluster by setting the `watchGlobally` flag to `true` in manifest file.
|
||||
```bash
|
||||
helm repo add stakater https://stakater.github.io/stakater-charts
|
||||
|
||||
helm repo update
|
||||
|
||||
helm install stakater/reloader
|
||||
```
|
||||
|
||||
## Monitor All namespaces
|
||||
|
||||
By default Reloader gets deployed in `default` namespace and watches changes `secrets` and `configmaps` in all namespaces.
|
||||
|
||||
## Help
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
apiVersion: v1
|
||||
name: reloader
|
||||
description: Reloader chart that runs on kubernetes
|
||||
version: 0.0.3
|
||||
version: 0.0.8
|
||||
keywords:
|
||||
- Reloader
|
||||
- kubernetes
|
||||
|
||||
@@ -7,9 +7,9 @@ reloader:
|
||||
labels:
|
||||
provider: stakater
|
||||
group: com.stakater.platform
|
||||
version: 0.0.3
|
||||
version: 0.0.8
|
||||
image:
|
||||
name: stakater/reloader
|
||||
tag: "0.0.3"
|
||||
tag: "0.0.8"
|
||||
pullPolicy: IfNotPresent
|
||||
watchGlobally: false
|
||||
watchGlobally: true
|
||||
@@ -7,8 +7,8 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
@@ -29,11 +29,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: "stakater/reloader:0.0.3"
|
||||
image: "stakater/reloader:0.0.8"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: reloader
|
||||
serviceAccountName: reloader
|
||||
|
||||
@@ -7,25 +7,25 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role
|
||||
namespace: tools
|
||||
namespace: default
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -51,23 +51,23 @@ rules:
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role-binding
|
||||
namespace: tools
|
||||
namespace: default
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
kind: ClusterRole
|
||||
name: reloader-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: reloader
|
||||
namespace: tools
|
||||
namespace: default
|
||||
|
||||
@@ -7,8 +7,8 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
@@ -29,11 +29,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: "stakater/reloader:0.0.3"
|
||||
image: "stakater/reloader:0.0.8"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: reloader
|
||||
serviceAccountName: reloader
|
||||
@@ -47,25 +43,25 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role
|
||||
namespace: tools
|
||||
namespace: default
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -91,23 +87,23 @@ rules:
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.3
|
||||
chart: "reloader-0.0.3"
|
||||
version: 0.0.8
|
||||
chart: "reloader-0.0.8"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role-binding
|
||||
namespace: tools
|
||||
namespace: default
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
kind: ClusterRole
|
||||
name: reloader-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: reloader
|
||||
namespace: tools
|
||||
namespace: default
|
||||
|
||||
@@ -12,4 +12,4 @@ reloader:
|
||||
name: {{ getenv "DOCKER_IMAGE" }}
|
||||
tag: "{{ getenv "VERSION" }}"
|
||||
pullPolicy: IfNotPresent
|
||||
watchGlobally: false
|
||||
watchGlobally: true
|
||||
77
docs/How-it-works.md
Normal file
77
docs/How-it-works.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# How it works?
|
||||
|
||||
Reloader watches for `ConfigMap` and `Secret` and detects if there are changes in data of these objects. After change detection reloader performs rolling upgrade on relevant Pods via associated `Deployment`, `Deamonset` and `Statefulset`.
|
||||
|
||||
## How change detection works
|
||||
|
||||
Reloader watches changes in `configmaps` and `secrets` data. As soon as it detects a change in these. It forwards these objects to an update handler which decides if and how to perform the rolling upgrade.
|
||||
|
||||
## Requirements for rolling upgrade
|
||||
|
||||
To perform rolling upgrade a `deployment`, `daemonset` or `statefulset` must have
|
||||
|
||||
- support for rolling upgrade strategy
|
||||
- specific annotation for `configmaps` or `secrets`
|
||||
|
||||
The annotation value is comma separated list of `configmaps` or `secrets`. If a change is detected in data of these `configmaps` or `secrets`, reloader will perform rolling upgrades on their associated `deployments`, `daemonsets` or `statefulsets`.
|
||||
|
||||
### Annotation for Configmap
|
||||
|
||||
For a `Deployment` called `foo` have a `ConfigMap` called `foo`. Then add this annotation to your `Deployment`
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
configmap.reloader.stakater.com/reload: "foo"
|
||||
```
|
||||
|
||||
### Annotation for Secret
|
||||
|
||||
For a `Deployment` called `foo` have a `Secret` called `foo`. Then add this annotation to your `Deployment`
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
secret.reloader.stakater.com/reload: "foo"
|
||||
```
|
||||
|
||||
Above mentioned annotation are also work for `Daemonsets` and `Statefulsets`
|
||||
|
||||
## How Rolling upgrade works?
|
||||
|
||||
When reloader detects changes in configmap. It gets two objects of configmap. First object is an old configmap object which has a state before the latest change. Second object is new configmap object which contains latest changes. Reloader compares both objects and see whether any change in data occurred or not. If reloader finds any change in new configmap object, only then, it move forward with rolling upgrade.
|
||||
|
||||
After that, reloader gets the list of all deployments, daemonsets and statefulset and looks for above mentioned annotation for configmap. If the annotation value contains the configmap name, it then looks for an environment variable which can contain the configmap or secret data change hash.
|
||||
|
||||
### Environment variable for Configmap
|
||||
|
||||
If configmap name is foo then
|
||||
|
||||
```yaml
|
||||
STAKATER_FOO_CONFIGMAP
|
||||
```
|
||||
|
||||
### Environment variable for Secret
|
||||
|
||||
If Secret name is foo then
|
||||
|
||||
```yaml
|
||||
STAKATER_FOO_SECRET
|
||||
```
|
||||
|
||||
If the environment variable is found then it gets its value and compares it with new configmap hash value. If old value in environment variable is different from new hash value then reloader updates the environment variable. If the environment variable does not exist then it creates a new environment variable with latest hash value from configmap and updates the relevant `deployment`, `daemonset` or `statefulset`
|
||||
|
||||
Note: Rolling upgrade also works in the same way for secrets.
|
||||
|
||||
### Hash value Computation
|
||||
|
||||
Reloader uses SHA1 to compute hash value. SHA1 is used because it is efficient and less prone to collision.
|
||||
|
||||
## Monitor All Namespaces
|
||||
|
||||
By default reloader deploys in default namespace and monitors changes in all namespaces. To monitor changes in a specific namespace deploy the reloader in that namespace and set the `watchGlobally` flag to `false` in values file located under `deployments/kubernetes/chart/reloader`
|
||||
And render manifest file using helm command
|
||||
```bash
|
||||
helm --namespace {replace this with namespace name} template . > reloader.yaml
|
||||
```
|
||||
The output file can then be used to deploy reloader in specific namespace.
|
||||
10
docs/Reloader-vs-ConfigmapController.md
Normal file
10
docs/Reloader-vs-ConfigmapController.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Reloader vs ConfigmapController
|
||||
|
||||
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.
|
||||
|
||||
| Configmap | Reloader |
|
||||
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ConfigmapController can only watch changes in `configmaps`. It cannot detect changes in other resources like `secrets`. | Reloader on the other hand can watch and detect changes in both `secrets` and `configmaps`. |
|
||||
| ConfigmapController can only perform rolling upgrades on `deployments`. It currently does not support rolling upgrades on `statefulsets` and `daemonsets` | Reloader on the other hand can perform rolling upgrades on `deployments` as well as on `statefulsets` and `daemonsets` |
|
||||
| Currently there are no 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 if new changes break any older functionality or not. | 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 older functionality. |
|
||||
| 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. | 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 also very less pron to collision. |
|
||||
28
docs/Reloader-vs-k8s-trigger-controller.md
Normal file
28
docs/Reloader-vs-k8s-trigger-controller.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Reloader vs k8s-trigger-controller
|
||||
|
||||
Reloader and k8s-trigger-controller are both built for same purpose. So there are quite a few similarities and differences between these.
|
||||
|
||||
## Similarities
|
||||
|
||||
- Both controllers support change detection in configmap and secrets
|
||||
- Both controllers support deployment rollout
|
||||
- Both controllers use SHA1 for hashing
|
||||
- Both controllers have end to end as well as unit test cases.
|
||||
|
||||
## Differences
|
||||
|
||||
### Support for Daemonsets and Statefulsets.
|
||||
|
||||
#### k8s-trigger-controller:
|
||||
k8s-trigger-controller only support for deployment rollout. It does not support daemonsets and statefulsets rollout.
|
||||
|
||||
#### Reloader:
|
||||
Reloader supports deployment rollout as well as daemonsets and statefulsets rollout.
|
||||
|
||||
### Hashing usage
|
||||
|
||||
#### k8s-trigger-controller:
|
||||
k8s-trigger-controller stores the hash value in an annotation `trigger.k8s.io/[secret|configMap]-NAME-last-hash`
|
||||
|
||||
#### Reloader:
|
||||
Reloader stores the hash value in an environment variable `STAKATER_NAME_[SECRET|CONFIGMAP]`
|
||||
51
docs/Verify-Reloader-Working.md
Normal file
51
docs/Verify-Reloader-Working.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Verify Reloader's Working
|
||||
|
||||
Reloader's working can be verified by two ways.
|
||||
|
||||
## Verify from logs
|
||||
|
||||
Check the logs of reloader and verify that you can see logs looks like below, if you are able to find these logs then it means reloader is working.
|
||||
|
||||
```text
|
||||
Changes Detected in test-object of type 'SECRET' in namespace: test-reloader
|
||||
|
||||
Updated test-resource of type Deployment in namespace: test-reloader
|
||||
```
|
||||
|
||||
Below are the details that explain these logs:
|
||||
|
||||
### test-object
|
||||
|
||||
`test-object` is the name of a `secret` or a `deployment` in which change has been detected.
|
||||
|
||||
### SECRET
|
||||
|
||||
`SECRET` is the type of `test-object`. It can either be `SECRET` or `CONFIGMAP`
|
||||
|
||||
### test-reloader
|
||||
|
||||
`test-reloader` is the name of namespace in which reloader has detected the change.
|
||||
|
||||
### test-resource
|
||||
|
||||
`test-resource` is the name of resource which is going to be updated
|
||||
|
||||
### Deployment
|
||||
|
||||
`Deployment` is the type of `test-resource`. It can either be a `Deployment`, `Daemonset` or `Statefulset`
|
||||
|
||||
## Verify by checking the age of Pod
|
||||
|
||||
A pod's age can tell whether reloader is working correctly or not. If you know that a change in a `secret` or `configmap` has occurred, then check the relevant Pod's age immediately. It should be newly created few moments ago.
|
||||
|
||||
### Verify from kubernetes Dashboard
|
||||
|
||||
`kubernetes dashboard` can be used to verify the working of Reloader. After a change in `secret` or `configmap`, check the relevant Pod's age from dashboard. It should be newly created few moments ago.
|
||||
|
||||
### Verify from command line
|
||||
|
||||
After a change in `secret` or `configmap`. Run the below mentioned command and verify that the pod is newly created.
|
||||
|
||||
```bash
|
||||
kubectl get pods <pod name> -n <namespace name>
|
||||
```
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
var (
|
||||
client = testutil.GetClient()
|
||||
namespace = "test-reloader"
|
||||
namespace = "test-reloader-" + testutil.RandSeq(5)
|
||||
configmapNamePrefix = "testconfigmap-reloader"
|
||||
secretNamePrefix = "testsecret-reloader"
|
||||
data = "dGVzdFNlY3JldEVuY29kaW5nRm9yUmVsb2FkZXI="
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
var (
|
||||
client = testclient.NewSimpleClientset()
|
||||
namespace = "test-handler"
|
||||
namespace = "test-handler-" + testutil.RandSeq(5)
|
||||
configmapName = "testconfigmap-handler-" + testutil.RandSeq(5)
|
||||
secretName = "testsecret-handler-" + testutil.RandSeq(5)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user