前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8S Configmap和Secret热更新之Reloader

K8S Configmap和Secret热更新之Reloader

作者头像
YP小站
发布2021-08-10 15:45:24
5K0
发布2021-08-10 15:45:24
举报
文章被收录于专栏:YP小站

一 背景

1.1 配置中心问题

在云原生中配置中心,例如:ConfigmapSecret对象,虽然可以进行直接更新资源对象

  • 对于引用这些有些不变的配置是可以打包到镜像中的,那可变的配置呢?
  • 信息泄漏,很容易引发安全风险,尤其是一些敏感信息,比如密码、密钥等。
  • 每次配置更新后,都要重新打包一次,升级应用。镜像版本过多,也给镜像管理和镜像中心存储带来很大的负担。
  • 定制化太严重,可扩展能力差,且不容易复用。

1.2 使用方式

ConfigmapSecret使用有两种方式,一种是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简介

3.1 reloader简介

Reloader 可以观察 ConfigMap 和 Secret 中的变化,并通过相关的 deploymentconfiggs、 deploymentconfiggs、 deploymonset 和 statefulset 对 Pods 进行滚动升级。

3.2 reloader安装

  • helm安装
代码语言:javascript
复制
$ helm repo add stakater https://stakater.github.io/stakater-charts
$ helm repo update
$ helm install stakater/reloader
  • Kustomize
代码语言:javascript
复制
$ kubectl apply -k https://github.com/stakater/Reloader/deployments/kubernetes
  • 资源清单安装
代码语言:javascript
复制
$ kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/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


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

3.3 配置

3.3.1 自动更新

reloader.stakater.com/searchreloader.stakater.com/auto 并不在一起工作。如果你在你的部署上有一个 reloader.stakater.com/auto : "true"的注释,该资源对象引用的所有configmap或这secret的改变都会重启该资源,不管他们是否有 reloader.stakater.com/match : "true"的注释。

代码语言:javascript
复制
kind: Deployment
metadata:
  annotations:
    reloader.stakater.com/auto: "true"
spec:
  template: metadata:

3.3.2 制定更新

指定一个特定的configmap或者secret,只有在我们指定的配置图或秘密被改变时才会触发滚动升级,这样,它不会触发滚动升级所有配置图或秘密在部署,后台登录或状态设置中使用。

一个制定deployment资源对象,在引用的configmap或者secret种,只有reloader.stakater.com/match: "true"为true才会出发更新,为false或者不进行标记,该资源对象都不会监视配置的变化而重启。

代码语言:javascript
复制
kind: Deployment
metadata:
  annotations:
    reloader.stakater.com/search: "true"
spec:
  template:

cm配置

代码语言:javascript
复制
kind: ConfigMap
metadata:
  annotations:
    reloader.stakater.com/match: "true"
data:
  key: value

3.3.3 指定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直接用逗号隔开

代码语言:javascript
复制
# configmap对象
kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "nginx-cm1"
spec:
  template: metadata:
代码语言:javascript
复制
# secret对象
kind: Deployment
metadata:
  annotations:
    secret.reloader.stakater.com/reload: "foo-secret"
spec:
  template: metadata:

无需在cm或secret中添加注解,只需要在引用资源对象中添加注解即可。

四 测试

4.1 deploy

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:   
    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:       
        - name: nginx-cm
          mountPath: /data/cfg
          readOnly: true
      volumes:      
      - name: nginx-cm
        configMap:          
          name: nginx-cm
          items:          
          - key: config.yaml        
            path: config.yaml
            mode: 0644 

4.2 configmap

代码语言:javascript
复制
apiVersion: v1
data:
  config.yaml: |
    # project settings
    DEFAULT_CONF:
      port: 8888 
    UNITTEST_TENCENT_ZONE: ap-chongqing-1
kind: ConfigMap
metadata:
  name: nginx-cm
  annotations:
    reloader.stakater.com/match: "true"

4.3 测试

代码语言:javascript
复制
$ kubectl  get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-68c9bf4ff7-9gmg6   1/1     Running   0          10m

$ kubectl  get cm
NAME       DATA   AGE
nginx-cm   1      28m

# 更新cm内容

$ kubectl edit cm nginx-cm 

configmap/nginx-cm edited

# 查看po发生了滚动更新,重新加载配置文件
$ kubectl get pod

NAME                     READY   STATUS              RESTARTS   AGE
nginx-66c758b548-9dllm   0/1     ContainerCreating   0          4s
nginx-68c9bf4ff7-9gmg6   1/1     Running             0          10m

五 Reloader 使用注意事项

  • 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

  • 作者: kaliarch
  • 原文出处: https://juejin.cn/post/6897882769624727559
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 YP小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 背景
    • 1.1 配置中心问题
      • 1.2 使用方式
      • 二 解决方案
      • 三 reloader简介
        • 3.1 reloader简介
          • 3.2 reloader安装
            • 3.3 配置
              • 3.3.1 自动更新
              • 3.3.2 制定更新
              • 3.3.3 指定cm
          • 四 测试
            • 4.1 deploy
              • 4.2 configmap
                • 4.3 测试
                • 五 Reloader 使用注意事项
                • 六 反思
                • 参考链接
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档