K8s基于Reloader的ConfigMap/Secret热更新

背景

K8s中部署的工作负载使用ConfigMapSecret时,存在两种方式:

  • 环境变量 Env 方式挂载
  • 文件方式挂载

当更新ConfigMapSecret时,挂载到Pod中的数据存在两种情况:

  • Env 方式挂载的环境变量不会同步更新
  • 文件方式挂载的数据会同步更新(存在秒级延时)

大部分场景下,在更新了ConfigMapSecret中的信息后,都希望Pod内业务能读取到最新的值。通常都会手动去滚动更新一下Pod,重新读取环境变量或文件内容。当前社区已经有对应的开源工具Reloader实现了ConfigMap/Secret更新时自动触发Pod的滚动更新。

Reloader介绍

Reloader 通过watch ConfigMapSecret 中的变化,对 DeploymentDaemonSetStatefulSet 等负载的 Pod 进行滚动升级。

兼容性

Reloader 兼容的 K8s 版本为>=1.9。

常用配置

以下使用Deployment举例:

  • Deployment 中使用的所有 ConfigMap 和 Secret 变动都会触发 Pod 滚动更新
    在Deployment 的metadata.annotations中添加reloader.stakater.com/auto: "true"
    kind: Deployment
    metadata:
      annotations:
        reloader.stakater.com/auto: "true"
    spec:
      template:
    
  • Deployment 中的部分 ConfigMap 和 Secret 变动会触发 Pod 滚动更新
    在Deployment 的metadata.annotations中添加reloader.stakater.com/search: "true"
    kind: Deployment
    metadata:
      annotations:
        reloader.stakater.com/search: "true"
    spec:
      template:
    
    同时在需要触发 Pod 更新的 ConfigMap 或 Secret 中的metadata.annotations中添加reloader.stakater.com/match: "true"
    kind: ConfigMap
    metadata:
      annotations:
        reloader.stakater.com/match: "true"
    data:
      key: value
    
  • Deployment 中指定 ConfigMap 或 Secret 的变动触发 Pod 滚动更新
    在Deployment 的metadata.annotations中添加configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap",指定这些 ConfigMap 才会触发 Pod 的更新。多个 ConfigMap 使用逗号分隔
    kind: Deployment
    metadata:
      annotations:
        configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
    spec:
      template: 
        metadata:
    
    在Deployment 的metadata.annotations中添加secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret",指定这些 Secret 才会触发 Pod 的更新。多个 Secret 使用逗号分隔
    kind: Deployment
    metadata:
      annotations:
        secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
    spec:
      template: 
        metadata:
    

其他配置

  • 忽略 ConfigMap 或 Secret 变动(全局
    在 Reloader deployment的spec.template.spec.container.args中添加参数:

    参数 描述
    --resources-to-ignore=configMaps 忽略 configMaps 变动
    --resources-to-ignore=secrets 忽略 secrets 变动

    --resources-to-ignore参数只支持忽略一种资源,若要同时忽略 configMaps 和 secrets 的变动,则只需要把 Reloader 副本数降为0。

  • 忽略 Namespace 中的变动
    在 Reloader deployment的spec.template.spec.container.args中配置参数--namespaces-to-ignore={namespace}

  • 覆盖默认相关annotation

    参数 描述
    --auto-annotation 覆盖默认的annotation reloader.stakater.com/auto
    --auto-search-annotation 覆盖默认的annotation reloader.stakater.com/search
    --search-match-annotation 覆盖默认的annotation reloader.stakater.com/match
    --configmap-annotation 覆盖默认的annotation configmap.reloader.stakater.com/reload
    --secret-annotation 覆盖默认的annotation secret.reloader.stakater.com/reload

更多信息参考:https://github.com/stakater/Reloader

实战验证

测试环境准备

  • 创建namespace
    输入命令,创建一个namespace,名为ns1
kubectl create ns ns1
  • 安装reloader
    输入如下命令,安装reloader相关deployment。
$ kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
  • 创建configmap
    使用kubectl apply -f cm.yaml命令创建configmap。cm.yaml文件内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-config-file
  namespace: ns1
  annotations:
#    reloader.stakater.com/match: "true"
data:
  info.yaml: |
    user=aliens
    age=22
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-config-env
  namespace: ns1
  annotations:
#    reloader.stakater.com/match: "true"
data:
  COUNTRY: china
  CITY: beijing
  • 创建deployment
    使用kubectl apply -f nginx-deploy.yaml命令创建configmap。nginx-deploy.yaml文件内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: ns1
  annotations:
#    configmap.reloader.stakater.com/reload: "test-config-file"
#    reloader.stakater.com/search: "true"
     reloader.stakater.com/auto: "true"
spec:
  selector: 
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        env:
          # Define the environment variable
          - name: COUNTRY
            valueFrom:
              configMapKeyRef:
                name: test-config-env
                key: COUNTRY
          - name: CITY
            valueFrom:
              configMapKeyRef:
                name: test-config-env
                key: CITY
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
          readOnly: true
      volumes:
      - name: foo
        configMap:
          name: test-config-file

Reloader功能验证

  1. 更新configmap(以文件方式挂载)
    使用命令kubectl -nns1 edit cm test-config-file编辑configmap,设置user的值为ted。查看pod已经滚动更新。
➜ kubectl edit cm -nns1 test-config-file
configmap/test-config-file edited
➜ kubectl get pods -nns1
NAME                     READY   STATUS              RESTARTS   AGE
nginx-5dff48f5dd-m528h   0/1     ContainerCreating   0          6s
nginx-6f455f8cd5-9h7pp   1/1     Running             0          34m

查看新启动pod中configmap所挂载的文件内容,发现user的值已经变为ted

➜ kubectl exec -it nginx-5dff48f5dd-m528h  -nns1 -- cat /etc/foo/info.yaml
user=ted
age=22
  1. 更新configmap(以环境变量方式注入)
    使用命令kubectl -nns1edit cm test-config-env编辑configmap,设置CITY的值为shenzhen。查看pod已经滚动更新。
➜ kubectl edit cm -nns1 test-config-env
configmap/test-config-env edited
➜ kubectl get pods -nns1
NAME                     READY   STATUS              RESTARTS   AGE
nginx-5b4cb86669-9cv6k   0/1     ContainerCreating   0          6s
nginx-5dff48f5dd-m528h   1/1     Running             0          9m35s

查看新启动pod中configmap所注入的环境变量,发现CITY的值已经变为shenzhen

➜ kubectl exec -it nginx-5b4cb86669-9cv6k -nns1 -- env|grep CITY
CITY=shenzhen

注意事项

  • Reloader自动触发滚动更新,可能会导致业务中断。使用该功能时需要评估pod滚动更新对业务带来的影响。
  • reloader.stakater.com/auto的优先级高于reloader.stakater.com/search
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343