mirror of
https://github.com/stakater/Reloader.git
synced 2026-02-14 18:09:50 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5c66bc235 | ||
|
|
9bc62e1f4e | ||
|
|
1bd5fb5620 | ||
|
|
4b233872bb | ||
|
|
569c0469fe | ||
|
|
599ceafd6b | ||
|
|
30ca4b463a | ||
|
|
e4756034ea | ||
|
|
2cc4941ffe | ||
|
|
53ca2ef340 | ||
|
|
9d38927e4a | ||
|
|
c670fb7e65 | ||
|
|
0427d58a4f | ||
|
|
1ad7a8fa76 |
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/groovy
|
||||
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.1')
|
||||
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.3')
|
||||
|
||||
def dummy
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -32,7 +32,7 @@ binary-image: builder-image
|
||||
@docker run --network host --rm "${BUILDER}" | docker build --network host -t "${REPOSITORY}" -f Dockerfile.run -
|
||||
|
||||
test:
|
||||
"$(GOCMD)" test -v ./...
|
||||
"$(GOCMD)" test -timeout 1800s -v ./...
|
||||
|
||||
stop:
|
||||
@docker stop "${BINARY}"
|
||||
|
||||
15
README.md
15
README.md
@@ -1,9 +1,5 @@
|
||||
# RELOADER
|
||||
|
||||
## WHY NAME RELOADER
|
||||
|
||||
In english language, Reloader is a thing/tool that can reload certain stuff. So referring to that meaning reloader can reload
|
||||
|
||||
## 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`
|
||||
@@ -53,10 +49,21 @@ kubectl apply -f rbac.yaml -n <namespace>
|
||||
kubectl apply -f deployment.yaml -n <namespace>
|
||||
```
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
### Monitor All namespaces
|
||||
You can monitor all namespaces in cluster by setting the `watchGlobally` flag to `true` in manifest file.
|
||||
|
||||
## Help
|
||||
|
||||
**Got a question?**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
apiVersion: v1
|
||||
name: reloader
|
||||
description: Reloader chart that runs on kubernetes
|
||||
version: 0.0.2
|
||||
version: 0.0.6
|
||||
keywords:
|
||||
- Reloader
|
||||
- kubernetes
|
||||
|
||||
@@ -18,10 +18,12 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
{{- if eq .Values.reloader.watchGlobally false }}
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- end }}
|
||||
image: "{{ .Values.reloader.image.name }}:{{ .Values.reloader.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.reloader.image.pullPolicy }}
|
||||
name: {{ template "reloader-name" . }}
|
||||
|
||||
@@ -6,6 +6,56 @@ metadata:
|
||||
{{ include "reloader-labels.chart" . | indent 4 }}
|
||||
name: {{ template "reloader-name" . }}
|
||||
---
|
||||
{{- if .Values.reloader.watchGlobally }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
{{ include "reloader-labels.stakater" . | indent 4 }}
|
||||
{{ include "reloader-labels.chart" . | indent 4 }}
|
||||
name: {{ template "reloader-name" . }}-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "extensions"
|
||||
- "apps"
|
||||
resources:
|
||||
- deployments
|
||||
- daemonsets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
{{ include "reloader-labels.stakater" . | indent 4 }}
|
||||
{{ include "reloader-labels.chart" . | indent 4 }}
|
||||
name: {{ template "reloader-name" . }}-role-binding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ template "reloader-name" . }}-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "reloader-name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- else }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
metadata:
|
||||
@@ -53,4 +103,5 @@ roleRef:
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "reloader-name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@@ -7,8 +7,9 @@ reloader:
|
||||
labels:
|
||||
provider: stakater
|
||||
group: com.stakater.platform
|
||||
version: 0.0.2
|
||||
version: 0.0.6
|
||||
image:
|
||||
name: stakater/reloader
|
||||
tag: "0.0.2"
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "0.0.6"
|
||||
pullPolicy: IfNotPresent
|
||||
watchGlobally: false
|
||||
@@ -7,8 +7,8 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.2
|
||||
chart: "reloader-0.0.2"
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
@@ -33,7 +33,7 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: "stakater/reloader:0.0.2"
|
||||
image: "stakater/reloader:0.0.6"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: reloader
|
||||
serviceAccountName: reloader
|
||||
|
||||
@@ -7,8 +7,8 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.2
|
||||
chart: "reloader-0.0.2"
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
@@ -20,12 +20,12 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.2
|
||||
chart: "reloader-0.0.2"
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role
|
||||
namespace: tools
|
||||
namespace: default
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -57,12 +57,12 @@ metadata:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.2
|
||||
chart: "reloader-0.0.2"
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role-binding
|
||||
namespace: tools
|
||||
namespace: default
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
@@ -70,4 +70,4 @@ roleRef:
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: reloader
|
||||
namespace: tools
|
||||
namespace: default
|
||||
|
||||
113
deployments/kubernetes/reloader.yaml
Normal file
113
deployments/kubernetes/reloader.yaml
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
# Source: reloader/templates/deployment.yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: "stakater/reloader:0.0.6"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: reloader
|
||||
serviceAccountName: reloader
|
||||
|
||||
---
|
||||
# Source: reloader/templates/rbac.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role
|
||||
namespace: default
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "extensions"
|
||||
- "apps"
|
||||
resources:
|
||||
- deployments
|
||||
- daemonsets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
app: reloader
|
||||
group: com.stakater.platform
|
||||
provider: stakater
|
||||
version: 0.0.6
|
||||
chart: "reloader-0.0.6"
|
||||
release: "RELEASE-NAME"
|
||||
heritage: "Tiller"
|
||||
name: reloader-role-binding
|
||||
namespace: default
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: reloader-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: reloader
|
||||
namespace: default
|
||||
@@ -11,4 +11,5 @@ reloader:
|
||||
image:
|
||||
name: {{ getenv "DOCKER_IMAGE" }}
|
||||
tag: "{{ getenv "VERSION" }}"
|
||||
pullPolicy: IfNotPresent
|
||||
pullPolicy: IfNotPresent
|
||||
watchGlobally: false
|
||||
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. |
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -257,7 +257,7 @@ func CreateConfigMap(client kubernetes.Interface, namespace string, configmapNam
|
||||
logrus.Infof("Creating configmap")
|
||||
configmapClient := client.CoreV1().ConfigMaps(namespace)
|
||||
_, err := configmapClient.Create(GetConfigmap(namespace, configmapName, data))
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return configmapClient, err
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ func CreateSecret(client kubernetes.Interface, namespace string, secretName stri
|
||||
logrus.Infof("Creating secret")
|
||||
secretClient := client.CoreV1().Secrets(namespace)
|
||||
_, err := secretClient.Create(GetSecret(namespace, secretName, data))
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return secretClient, err
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ func CreateDeployment(client kubernetes.Interface, deploymentName string, namesp
|
||||
logrus.Infof("Creating Deployment")
|
||||
deploymentClient := client.ExtensionsV1beta1().Deployments(namespace)
|
||||
deployment, err := deploymentClient.Create(GetDeployment(namespace, deploymentName))
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return deployment, err
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ func CreateDaemonSet(client kubernetes.Interface, daemonsetName string, namespac
|
||||
logrus.Infof("Creating DaemonSet")
|
||||
daemonsetClient := client.ExtensionsV1beta1().DaemonSets(namespace)
|
||||
daemonset, err := daemonsetClient.Create(GetDaemonSet(namespace, daemonsetName))
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return daemonset, err
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ func CreateStatefulSet(client kubernetes.Interface, statefulsetName string, name
|
||||
logrus.Infof("Creating StatefulSet")
|
||||
statefulsetClient := client.AppsV1beta1().StatefulSets(namespace)
|
||||
statefulset, err := statefulsetClient.Create(GetStatefulSet(namespace, statefulsetName))
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return statefulset, err
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ func CreateStatefulSet(client kubernetes.Interface, statefulsetName string, name
|
||||
func DeleteDeployment(client kubernetes.Interface, namespace string, deploymentName string) error {
|
||||
logrus.Infof("Deleting Deployment")
|
||||
deploymentError := client.ExtensionsV1beta1().Deployments(namespace).Delete(deploymentName, &metav1.DeleteOptions{})
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return deploymentError
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ func DeleteDeployment(client kubernetes.Interface, namespace string, deploymentN
|
||||
func DeleteDaemonSet(client kubernetes.Interface, namespace string, daemonsetName string) error {
|
||||
logrus.Infof("Deleting DaemonSet %s", daemonsetName)
|
||||
daemonsetError := client.ExtensionsV1beta1().DaemonSets(namespace).Delete(daemonsetName, &metav1.DeleteOptions{})
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return daemonsetError
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ func DeleteDaemonSet(client kubernetes.Interface, namespace string, daemonsetNam
|
||||
func DeleteStatefulSet(client kubernetes.Interface, namespace string, statefulsetName string) error {
|
||||
logrus.Infof("Deleting StatefulSet %s", statefulsetName)
|
||||
statefulsetError := client.AppsV1beta1().StatefulSets(namespace).Delete(statefulsetName, &metav1.DeleteOptions{})
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return statefulsetError
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ func UpdateConfigMap(configmapClient core_v1.ConfigMapInterface, namespace strin
|
||||
configmap = GetConfigmap(namespace, configmapName, data)
|
||||
}
|
||||
_, updateErr := configmapClient.Update(configmap)
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return updateErr
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func UpdateSecret(secretClient core_v1.SecretInterface, namespace string, secret
|
||||
secret = GetSecret(namespace, secretName, data)
|
||||
}
|
||||
_, updateErr := secretClient.Update(secret)
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return updateErr
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ func UpdateSecret(secretClient core_v1.SecretInterface, namespace string, secret
|
||||
func DeleteConfigMap(client kubernetes.Interface, namespace string, configmapName string) error {
|
||||
logrus.Infof("Deleting configmap %q.\n", configmapName)
|
||||
err := client.CoreV1().ConfigMaps(namespace).Delete(configmapName, &metav1.DeleteOptions{})
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ func DeleteConfigMap(client kubernetes.Interface, namespace string, configmapNam
|
||||
func DeleteSecret(client kubernetes.Interface, namespace string, secretName string) error {
|
||||
logrus.Infof("Deleting secret %q.\n", secretName)
|
||||
err := client.CoreV1().Secrets(namespace).Delete(secretName, &metav1.DeleteOptions{})
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user