當前位置: 妍妍網 > 碼農

Kubernetes 套用配置自動更新技巧

2024-06-26碼農

原文連結:https://bbs.huaweicloud.com/blogs/312634

背景

配置中心問題:

對於在雲原生中配置中心,例如configmap和secret物件,雖然可以進行直接更新資源物件

  • 對於參照這些有些不變的配置是可以打包到映像中的,那可變的配置呢?

  • 資訊泄漏,很容易引發安全風險,尤其是一些敏感資訊,比如密碼、金鑰等。

  • 每次配置更新後,都要重新打包一次,升級套用。映像版本過多,也給映像管理和映像中心儲存帶來很大的負擔。

  • 客製化太嚴重,可延伸能力差,且不容易復用。

  • 使用方式:

    Configmap或Secret使用有兩種方式,一種是env系統變量賦值,一種是volume掛載賦值,env寫入系統的configmap是不會熱更新的,而volume寫入的方式支持熱更新!

  • 對於env環境的,必須要捲動更新pod才能生效,也就是刪除老的pod,重新使用映像拉起新pod載入環境變量才能生效。

  • 對於volume的方式,雖然內容變了,但是需要我們的套用直接監控configmap的變動,或者一直去更新環境變量才能在這種情況下達到熱更新的目的。

  • 套用不支持熱更新,可以在業務容器中啟動一個sidercar容器,監控configmap的變動,更新配置檔,或者也捲動更新pod達到更新配置的效果。

  • 解決方案

    ConfigMap 和 Secret 是 Kubernetes 常用的保存配置數據的物件,你可以根據需要選擇合適的物件儲存數據。透過 Volume 方式掛載到 Pod 內的,kubelet 都會定期進行更新。但是透過環境變量註入到容器中,這樣無法感知到 ConfigMap 或 Secret 的內容更新。

    目前如何讓 Pod 內的業務感知到 ConfigMap 或 Secret 的變化,還是一個待解決的問題。但是我們還是有一些 Workaround 的。

    如果業務自身支持 reload 配置的話,比如nginx -s reload,可以透過 inotify 感知到檔更新,或者直接定期進行 reload(這裏可以配合我們的 readinessProbe 一起使用)。

    如果我們的業務沒有這個能力,考慮到不可變基礎設施的思想,我們是不是可以采用捲動升級的方式進行?沒錯,這是一個非常好的方法。目前有個開源工具Reloader,它就是采用這種方式,透過 watch ConfigMap 和 Secret,一旦發現物件更新,就自動觸發對 Deployment 或 StatefulSet 等工作負載物件進行捲動升級。

    reloader簡介

    reloader簡介:

    Reloader 可以觀察 ConfigMap 和 Secret 中的變化,並透過相關的 deploymentconfiggs、 deploymentconfiggs、 deploymonset 和 statefulset 對 Pods 進行捲動升級。

    reloader安裝:

    helm安裝:

    helm repo add stakater https://stakater.github.io/stakater-charts
    helm repo update
    helm install stakater/reloader

    Kustomize:

    kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes

    資源清單安裝:

    kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
    # 在此安裝在common-service 名稱空間下,
    [root@master reloader]# kubectl apply -f reloader.yaml 
    clusterrole.rbac.authorization.k8s.io/reloader-reloader-role created
    clusterrolebinding.rbac.authorization.k8s.io/reloader-reloader-role-binding created
    deployment.apps/reloader-reloader created
    serviceaccount/reloader-reloader created
    [root@master reloader]# kubectl get all -n common-service 
    NAME READY STATUS RESTARTS AGE
    pod/reloader-reloader-66d46d5885-nx64t 1/1 Running 0 15s
    NAME READY UP-TO-DATE AVAILABLE AGE
    deployment.apps/reloader-reloader 1/1 1 1 16s
    NAME DESIRED CURRENT READY AGE
    replicaset.apps/reloader-reloader-66d46d5885 1 1 1 16s

    配置忽略:

    reloader能夠配置忽略cm或者secrets資源,可以透過配置在reader deploy中的spec.template.spec.containers.args,如果兩個都忽略,那就縮小deploy為0,或者不部署reoader。

    Args Description
    –resources-to-ignore=configMaps To ignore configMaps
    –resources-to-ignore=secrets To ignore secrets

    配置:

    自動更新:

    reloader.stakater.com/search 和 reloader.stakater.com/auto 並不在一起工作。如果你在你的部署上有一個 reloader.stakater.com/auto : 「 true」的註釋,該資源物件參照的所有configmap或這secret的改變都會重新開機該資源,不管他們是否有 reloader.stakater.com/match : 「 true」的註釋。

    kind:Deployment
    metadata:
    annotations:
    reloader.stakater.com/auto:"true"
    spec:
    template: metadata:

    制定更新:

    指定一個特定的configmap或者secret,只有在我們指定的配置圖或秘密被改變時才會觸發捲動升級,這樣,它不會觸發捲動升級所有配置圖或秘密在部署,後台登入或狀態設定中使用。

    一個制定deployment資源物件,在參照的configmap或者secret種,只有 reloader.stakater.com/match: "true" 為true才會出發更新,為false或者不進行標記,該資源物件都不會監視配置的變化而重新開機。

    kind:Deployment
    metadata:
    annotations:
    reloader.stakater.com/search:"true"
    spec:
    template:

    cm配置:

    kind:ConfigMap
    metadata:
    annotations:
    reloader.stakater.com/match:"true"
    data:
    key:value

    指定cm:

    如果一個deployment掛載有多個cm或者的場景下,我們只希望更新特定一個cm後,deploy發生捲動更新,更新其他的cm,deploy不更新,這種場景可以將cm在deploy中指定為單個或著列表實作。

    例如:一個deploy有掛載nginx-cm1和nginx-cm2兩個configmap,只想nginx-cm1更新的時候deploy才發生捲動更新,此時無需在兩個cm中配置註解,只需要在deploy中寫入configmap.reloader.stakater.com/reload:nginx-cm1,其中nginx-cm1如果發生更新,deploy就會觸發捲動更新。

    如果多個cm直接用逗號隔開

    # configmap物件
    kind:Deployment
    metadata:
    annotations:
    configmap.reloader.stakater.com/reload:"nginx-cm1"
    spec:
    template: metadata:

    # secret物件
    kind:Deployment
    metadata:
    annotations:
    secret.reloader.stakater.com/reload:"foo-secret"
    spec:
    template: metadata:

    無需在cm或secret中添加註解,只需要在參照資源物件中添加註解即可。

    測試驗證

    deploy:

    apiVersion:apps/v1
    kind:Deployment
    metadata:
    annotations:
    # reloader.stakater.com/auto: "true"
    reloader.stakater.com/search:"true"
    labels:
    run:nginx
    name:nginx
    namespace:default
    spec:
    replicas:1
    selector:
    matchLabels:
    run:nginx
    template:
    metadata:
    labels:
    run:nginx
    spec:
    containers:
    -image:nginx
    name:nginx
    volumeMounts:
    # 必須匹配volumes的名稱,定義configmap
    -name:nginx-cm
    mountPath:/data/cfg
    readOnly:true
    volumes:
    # 定義邏輯卷的名稱
    -name:nginx-cm
    configMap:
    # 使用configmap資源的名稱
    name:nginx-cm
    items:
    # 使用configmap中到那個key
    -key:config.yaml
    # 使用configmap中到key對映到容器中到檔名稱
    path:config.yaml
    mode:0644

    configmap:

    apiVersion:v1
    data:
    config.yaml:|
    # project settings

    # go2cloud_api service config
    DEFAULT_CONF:
    port:8888
    # data disk api
    UNITTEST_TENCENT_ZONE:ap-chongqing-1
    kind:ConfigMap
    metadata:
    name:nginx-cm
    annotations:
    reloader.stakater.com/match:"true"

    測試:

    [root@master ns-default]# kubectl get po
    NAME READY STATUS RESTARTS AGE
    nginx-68c9bf4ff7-9gmg6 1/1 Running 0 10m
    [root@master ns-default]# kubectl get cm
    NAME DATA AGE
    nginx-cm 1 28m
    # 更新cm內容
    [root@master ns-default]# kubectl edit cm nginx-cm 
    configmap/nginx-cm edited
    # 檢視po發生了捲動更新,重新載入配置檔
    [root@master ns-default]# kubectl get po
    NAME READY STATUS RESTARTS AGE
    nginx-66c758b548-9dllm 0/1 ContainerCreating 0 4s
    nginx-68c9bf4ff7-9gmg6 1/1 Running 0 10m

    註意事項

  • reloader為全域資源物件,建議部署在一個公共服務的ns下,然後其他ns也可以正常使用reloader特性。

  • Reloader.stakater.com/auto : 如果配置configmap或者secret在 deploymentconfigmap/deployment/daemonsets/Statefulsets

  • secret.reloader.stakater.com/reload 或者 configmap.reloader.stakater.com/reload 註釋中被使用,那麽 true 只會重新載入 pod,不管使用的是 configmap 還是 secret。

  • reloader.stakater.com/search 和 reloader.stakater.com/auto 不能同時使用。如果你在你的部署上有一個 reloader.stakater.com/auto : 「 true」的註釋,那麽它總是會在你修改了 configmaps 或者使用了機密之後重新啟動,不管他們是否有 reloader.stakater.com/match : 「 true」的註釋。

  • 反思

    Reloader透過 watch ConfigMap 和 Secret,一旦發現物件更新,就自動觸發對 Deployment 或 StatefulSet 等工作負載物件進行捲動升級。

    如果我們的套用內部沒有去即時監控配置檔,利用該方式可以非常方便的實作配置的熱更新。

    參考連結

  • https://github.com/stakater/Reloader

  • 往期推薦


    點亮,伺服器三年不宕機