聊聊springcloud如何与k8s configMap整合实现配置动态刷新

前言

配置中心在微服务的服务治理场景基本上是属于标配,常见可以用来做配置中心有nacos、apollo、zookeeper、springcloud config、consul、etcd、redis、disconf、dimond、xxl-conf等。这些组件的特点都是需要安装,如果大家的部署环境中有用到k8s,且不需要用到太多配置中心的特殊功能,比如灰度发布、权限管理、发布审核、操作审计啥的,仅仅只是用来统一配置,以及实现配置的热更新,那今天讲主角configMap会是一个挺不错的选择

configMap简介

ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时,Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。

具体详细介绍可以查看官网

kubernetes.io/zh-cn/docs/...

configMap如何实现热更新

注: 假设大家对configMap已经有一定了解,如果对configMap,可以去了解一下,再来看本文

1、k8s configmap在哪些场景会自动实现热更新

a、 以挂载Volume 方式使用的 ConfigMap 数据会自动更新。更新时间大约10s左右

2、k8s configmap在哪些场景不会自动实现热更新

a、 以环境变量(ENV)方式使用的 ConfigMap ,Kubernetes不会做自动热更新:

b、 如果使用ConfigMap的subPath挂载为Container的Volume,Kubernetes不会做自动热更新

3、热更新验证示例

jimmysong.io/kubernetes-...

上面讲的是configmap自带的热更新,算是一个小科普,跟本文的主线关系不大,接下来上主菜

springcloud如何与configmap整合实现动态刷新

注: 本示例springcloud版本为Hoxton.SR3

示例前置准备

1、示例configMap

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: lybgeek-properties
  namespace: lybgeek
data:
  lybgeek.properties: |
    test = k8s-config-666

2、准备示例需要的controller

java 复制代码
    @RestController
    @RequestMapping("config")
    @RefreshScope
    class ConfigTestController{

        @Value("${test:local}")
        private String test;

        @GetMapping("test")
        public String test(){
            return test;
        }
    }

正文

1、在项目中pom中引入相关GAV

xml 复制代码
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-actuator</artifactId>
</dependency>

2、在项目中src/main/resource创建bootstrap.yml或者application.yml文件,填入如下内容

yaml 复制代码
spring:
  cloud:
    kubernetes:
      config:
        name: ${LYBGEEK_CONFIG_MAP:lybgeek-properties}
        namespace: ${LYBGEEK_CONFIG_MAP_NAMESPACE:nisbos}
      reload:
        # 打开刷新功能
        enabled: ${LYBGEEK_CONFIG_MAP_RELOAD_ENABLED:true}
        # 监控configMap变化
        monitoring-config-maps: ${LYBGEEK_CONFIG_MONITOR:true}
        # 监控secrets变化
        monitoring-secrets: ${LYBGEEK_SECRETS_MONITOR:true}
        # 加载策略,有三种,
        # refresh:只重新加载用@ConfigurationProperties或@RefreshScope注释的配置bean。此重新加载级别利用了Spring Cloud Context的刷新功能。
        # restart_context:整个Spring ApplicationContext被优雅地重新启动。使用新配置重新创建bean。为了使重启上下文功能正常工作,您必须启用并公开restart端点
        # shutdown:关闭Spring ApplicationContext以激活容器的重新启动。使用此级别时,请确保所有非守护进程线程的生命周期都绑定到ApplicationContext,并且已配置复制控制器或副本集以重新启动pod。
        strategy: ${LYBGEEK_CONFIG_RELOAD_STRATEGY:restart_context}
        # 模式:event(默认):通过使用Kubernetes API(web套接字)来监视configMap或secrets中的更改。任何事件都会对配置进行重新检查,如果发生更改,还会重新加载。需要服务帐户上的视图角色才能侦听配置映射更改。secrets需要更高级别的角色(如编辑)(默认情况下,不监控secrets)。
       # 轮询:定期根据configMap和secrets重新创建配置,以查看其是否已更改。您可以使用spring.cloud.kubernetes.reload.period属性配置轮询周期,默认为15秒。它需要与受监控的属性源具有相同的角色。这意味着,例如,对文件装载的秘密源使用轮询不需要特定的权限。
        mode: ${LYBGEEK_CONFIG_RELOAD_MODE:polling}
        # 调成500毫秒
        period: ${LYBGEEK_CONFIG_POLLING:500}



management:
  endpoint:
    restart:
      enabled: true
  endpoints:
    web:
      exposure:
        include: restart

核心配置属性介绍

a、spring.cloud.kubernetes.config.name configMap名字,默认是spring.application.name b、spring.cloud.kubernetes.config.namespace k8s命名空间 c、spring.cloud.kubernetes.reload.enabled=true 开启加载 d、spring.cloud.kubernetes.reload.strategy 加载支持的策略

  • refresh:只重新加载用@ConfigurationProperties或@RefreshScope注释的配置bean。此重新加载级别利用了Spring Cloud Context的刷新功能。
  • restart_context:整个Spring ApplicationContext被优雅地重新启动。使用新配置重新创建bean。为了使重启上下文功能正常工作,您必须启用并公开restart端点
  • shutdown:关闭Spring ApplicationContext以激活容器的重新启动。使用此级别时,请确保所有非守护进程线程的生命周期都绑定到ApplicationContext,并且已配置复制控制器或副本集以重新启动pod。

e、spring.cloud.kubernetes.reload.mode 加载支持的模式

  • event(默认):通过使用Kubernetes API(web套接字)来监视configMap或secrets中的更改。任何事件都会对配置进行重新检查,如果发生更改,还会重新加载。需要服务帐户上的视图角色才能侦听配置映射更改。secrets需要更高级别的角色(如编辑)(默认情况下,不监控secrets)。
  • 轮询:定期根据configMap和secrets重新创建配置,以查看其是否已更改。您可以使用spring.cloud.kubernetes.reload.period属性配置轮询周期,默认为15秒。它需要与受监控的属性源具有相同的角色。这意味着,例如,对文件装载的秘密源使用轮询不需要特定的权限。

3、测试

先浏览器访问我们准备好的controller

将configmap的内容改为

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: lybgeek-properties
  namespace: lybgeek
data:
  lybgeek.properties: |
    test = k8s-config-999

我们观察下业务打印出来的日志

出现restarted,然后我们再访问我们controller 原先的k8s-config-666已经改成k8s-config-999,说明配置热更新生效

在实验的过程中可能会出现

java 复制代码
User "system:serviceaccount:lybgeek:default" cannot get resource "configmaps" in API group "" in the namespace "lybgeek".

那是因为system:serviceaccount:lybgeek:default没有拉取configMap的权限,因此我们将相应的权限给补上即可。

a、 创建ClusterRole

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: lybgeek
  name: configmap-test
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - get

b、 system:serviceaccount:lybgeek:default与创建好的ClusterRole(configmap-test)绑定

java 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata
  name: configmap-test-clusterrolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: configmap-test
subjects:
- kind: ServiceAccount
  name: default
  namespace: lybgeek

总结

本文介绍springcloud如何与k8s configMap整合实现配置动态刷新,其实是借助spring-cloud-kubernetes的能力,详细介绍可以查看官网 docs.spring.io/spring-clou... 官网也有提供了示例 github.com/spring-clou...

在官网有一个警告 就是该功能在2020.0版本之后,该功能已经被弃用了,改为使用Spring Cloud Kubernates Configuration Watcher。如果大家项目的k8s版本是 >= 1.9,使用Reloader来做配置热更新也是一个不错选择,对这个组件感兴趣的朋友可以查看官网 github.com/stakater/Re...

有网友也提供configMap热更新的其他方案,详情可以查看如下链接 cctoctofx.netlify.app/post/cloud-...

相关推荐
重生之我是Java开发战士8 小时前
【Spring Cloud】Nacos注册中心
后端·spring·spring cloud
码外生活16 小时前
🎥 手搓一套直播高并发环境!一个后端小白从 0 到 1 的搭建笔记
后端·spring cloud
行百里er3 天前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
spring boot·spring cloud·监控
陈皮波比茶3 天前
SpringCloudAlibaba
java·spring cloud·微服务
欢迎来到祖安!3 天前
企业微信 API 接口能力介绍:支持消息收发、图片发送、表情互动、联系人管理等多场景应用
java·前端·数据仓库·spring cloud·企业微信
行百里er3 天前
BlockingQueue:异步批量上报
spring boot·spring cloud·监控
wno7045 天前
Spring Cloud Hystrix Dashboard仪表盘
spring·spring cloud·hystrix
BUG指挥官5 天前
Redis已接入AI
数据库·人工智能·spring boot·redis·spring cloud
wno7045 天前
Spring Cloud Hystrix服务容错
spring·spring cloud·hystrix
苏渡苇6 天前
Spring Insight 里上报 Span 为什么用 JDK HttpClient 而不是 RestTemplate
java·后端·spring·spring cloud·springboot·性能监控