👨‍💻簡介

有時候修改掛載的config檔,無法即時更新,需要重啟pod才會生效,為了解決這個問題,k8s-reloader因此而誕生,透過觀察掛載的configmap或是secret的變化自動對掛載的物件做滾動更新。

以下為在minikube環境下,透過掛載nginx-config檔並搭配reloader這個插件進行熱部署。

🔰基礎介紹

運作原理

  1. Reloader偵測所有資源變化,對有變化的資源使用SHA1計算資源的哈西值
  2. Reloader查看是否有設定相關的annotation,並查看有設定annotation資源的特殊環境變量
  3. 對有設定annotation的資源比對其哈希值,如果環境變量中哈希值不同,則更新環境變量,如果環境變量不存在,則創建一個

環境變量名稱

  • ConfigMap:STAKATER_{configmap_name}_CONFIGMAP ,比如 ConfigMap 的名稱為 foo,則生成的環境變量的名稱為:STAKATER_FOO_CONFIGMAP
  • Secret:STAKATER_{secret_name}_SECRET ,比如 Secret 的名稱為 foo,則生成的環境變量的名稱為:STAKATER_FOO_SECRET

環境變量的值

使用 SHA1 計算的 ConfigMap 或者 Secret 的哈希值。

版本需求

k8s版本需 >= 1.9

安裝方式

  1. 使用Manifests安裝
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
  1. 使用Kustomize安裝
kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
  - https://github.com/stakater/Reloader/deployments/kubernetes

namespace: reloader
  1. 使用Helm安裝
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

預設情況下,reloader會偵測所有namespace的資源,如果要針對單一namespace可使用--set reloader.watchGloballyfalse,以下範例為安裝在test namespace並只偵測test namespace底下的資源

helm install stakater/reloader --set reloader.watchGlobally=false --namespace test # For helm3 add --generate-name flag or set the release name

使用方式

  1. 自動偵測所有資源

設定reloader.stakater.com/auto: "true"

kind: Deployment
metadata:
  annotations:
    reloader.stakater.com/auto: "true"
spec:
  template:
    metadata:
  1. 限制只偵測有設定annotations的資源

deploy設定reloader.stakater.com/search: "true",configmap等資源設定reloader.stakater.com/match: "true"

kind: Deployment
metadata:
  annotations:
    reloader.stakater.com/search: "true"
spec:
  template:
---
kind: ConfigMap
metadata:
  annotations:
    reloader.stakater.com/match: "true"
data:
  key: value

reloader.stakater.com/auto與reloader.stakater.com/search不能同時使用

如果使用reloader.stakater.com/auto,則reloader.stakater.com/match不管有沒有設定都會被偵測

  1. 只偵測特定資源

資源使用,做分隔

  • Configmap
kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap"
spec:
  template:
    metadata:
  • Secret
kind: Deployment
metadata:
  annotations:
    secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
spec:
  template: 
    metadata:

🎯setup

  1. 部署reloader
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
  1. 部署nginx服務

    1. 建立以下檔案
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-map
      annotations:
    	reloader.stakater.com/match: "true"
    data:
      test.conf: |
    	server {
    	  listen       80;
    	  server_name  abc.com;
    
    	  location / {
    		  root  /usr/share/nginx/html ;
    		  index index.html index.htm;
    	  }
    	}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      annotations:
    	configmap.reloader.stakater.com/reload: "nginx-map"
    spec:
      replicas: 2
      selector:
    	matchLabels:
    	  service: http-server
      template:
    	metadata:
    	  labels:
    		service: http-server
    	spec:
    	  containers:
    	  - name: nginx
    		image: sz9751210/nginx-reloader:v1
    		imagePullPolicy: IfNotPresent
    		ports:
    		- containerPort: 80
    		volumeMounts:
    		- mountPath: /etc/nginx/conf.d # mount nginx-conf volumn to /etc/nginx/conf.d
    		  readOnly: true
    		  name: deployment-nginx-conf
    	  volumes:
    		- name: deployment-nginx-conf
    		  configMap:
    			name: nginx-map # place ConfigMap `nginx-conf` on /etc/nginx
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
    	service: http-server
      ports:
      - port: 80
    	targetPort: 80
    
    1. 部署
    kubectl apply -f k8s-reloader-demo.yaml
    
  2. 打開瀏覽器查看nginx

minikube service nginx-service --url

預設應該會顯示default page

這時候將configmap裡的index.html改成index.html1

這時候刷新頁面就會看到顯示reload page了

Reference

stakater/Reloader: A Kubernetes controller to watch changes in ConfigMap and Secrets and do rolling upgrades on Pods with their associated Deployment, StatefulSet, DaemonSet and DeploymentConfig

【k8s】使用 Reloader 实现热部署

ConfigMap Reloader — Automatically reload new data from ConfigMap/Secret to deployments | by Navratan Lal Gupta | Linux Shots | Medium