---
# System prepended metadata

title: Reloader
tags: [K8S]

---

# Reloader
![image](https://hackmd.io/_uploads/SJE4A6BGkl.png)


* Reloader 會去監控 ConfigMap 跟 Secret 的變動，來重啟跟他們有相關的 DeploymentConfigs， Deployments， Daemonsets，Statefulsets 和 Rollouts 由於它是以 Kubernetes conrtroller 的形式存在，並且採用 Kubernetes API 去監控資源。
* 如果 configmap 是宣告環境變數給 pod 使用，更新 configmap 時 pod 內的環境變數並不會更新。
* 但 configmap 是宣告設定檔給 pod 掛載 volume，configmape 更新時 pod 內的設定檔會自動更新。
* Reloader 的做法事實上就是監控 ConfigMap 跟 Secret 的變動，然後自動重啟 pod。
* Reloader 只會監控 deployments/daemonsets/statefulset workload，naked pod 無法實現。



## 實作
* 安裝 Reloader
```
$ kubectl create ns reloader

$ git clone https://github.com/stakater/Reloader.git;cd Reloader/deployments/kubernetes/

$ nano kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: reloader               # 新增 namesapce
resources:
  - manifests/clusterrole.yaml
  - manifests/clusterrolebinding.yaml
  - manifests/serviceaccount.yaml
  - manifests/deployment.yaml


$ kubectl apply -k .
serviceaccount/reloader-reloader created
clusterrole.rbac.authorization.k8s.io/reloader-reloader-role unchanged
clusterrolebinding.rbac.authorization.k8s.io/reloader-reloader-role-binding configured
deployment.apps/reloader-reloader created

$ kubectl -n reloader get po
NAME                                 READY   STATUS    RESTARTS   AGE
reloader-reloader-55c5867c74-xs5f9   1/1     Running   0          32s
```

## 測試
* 產生 configmap
```
$ kubectl create configmap cm-goweb --from-literal=fruits=apples
```
* 建立 pod ，並且設定 `reloader.stakater.com/auto: "true"`
```
$ echo 'apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb
  labels:
    app: goweb
  annotations:
    reloader.stakater.com/auto: "true"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: goweb
  template:
    metadata:
      labels:
        app: goweb
    spec:
      containers:
        - name: podfbs
          image: quay.io/cloudwalker/alp.goweb:24.1
          ports:
            - containerPort: 8080
          env:
            - name: FRUITS
              valueFrom:
                configMapKeyRef:
                  key: fruits
                  name: cm-goweb' | kubectl apply -f -
```
* 驗證 pod 內的環境變數
```
$ kubectl get cm cm-goweb
NAME       DATA   AGE
cm-goweb   1      39s

$ kubectl get po
NAME                          READY   STATUS    RESTARTS   AGE
goweb-c985d559f-slztf         1/1     Running   0          14s

$ kubectl exec pod/goweb-c985d559f-slztf -- env | grep FRUITS
FRUITS=apples
```

* 修改 configmap
```
$ kubectl edit cm cm-goweb
......
apiVersion: v1
data:
  fruits: banana            # 修改
kind: ConfigMap
......
```
* reloader 的做法會產生新的 replicaset，事實上也就是重建 pod。
```
$ kubectl get po
NAME                          READY   STATUS    RESTARTS   AGE
goweb-7fb9d955cd-952tp        1/1     Running   0          4s

$ kubectl exec pod/goweb-7fb9d955cd-952tp -- env | grep FRUITS
FRUITS=banana

$ kubectl get rs
NAME                    DESIRED   CURRENT   READY   AGE
goweb-7fb9d955cd        1         1         1       37s
goweb-c985d559f         0         0         0       100s
```
* 檢查 reloader log 可以看到他偵測到 cm-goweb configmap 被更改了，並且更新 deployment。
```
$ kubectl -n reloader logs reloader-reloader-55c5867c74-xs5f9
......
time="2024-11-16T05:11:19Z" level=info msg="Changes detected in 'cm-goweb' of type 'CONFIGMAP' in namespace 'default'; updated 'goweb' of type 'Deployment' in namespace 'default'"
time="2024-11-16T05:19:50Z" level=info msg="Changes detected in 'cm-goweb' of type 'CONFIGMAP' in namespace 'default'; updated 'goweb' of type 'Deployment' in namespace 'default'"
```
## 參考
https://kubernetes.io/docs/tutorials/configuration/updating-configuration-via-a-configmap/

https://github.com/stakater/Reloader