• Spring boot发布到k8s并加载Configmap配置文件,实现配置热更新


    在项目开发中, 大都会为不同的运行环境编写不同的配置文件, 比如生产环境使用application-prod.yml, 开发环境使用application-dev.yml.

    在spring boot 应用部署到k8s之前, 配置文件的挂载一般都会在打jar包时包含在内, 或者把配置文件的内容保存在nacos之类的中间件中在启动应用时读取配置.

    在应用k8s之后,  配置文件可以在通过ConfigMap资源剥离出来单独部署,  本次记录spring boot框架的java应用结合k8s的ConfigMap的实现外部配置文件挂载及配置热更新的一次实践。

    一、配置自动更新,需要引入 kubernetes-config、健康检测依赖

    1、项目依赖

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <parent>
    6. <groupId>org.springframework.boot</groupId>
    7. <artifactId>spring-boot-starter-parent</artifactId>
    8. <version>2.2.7.RELEASE</version>
    9. <relativePath/> <!-- lookup parent from repository -->
    10. </parent>
    11. <groupId>com.example</groupId>
    12. <artifactId>demo-v6</artifactId>
    13. <version>0.0.1</version>
    14. <name>demo-v6</name>
    15. <description>Demo project for Spring Boot</description>
    16. <properties>
    17. <java.version>1.8</java.version>
    18. </properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.boot</groupId>
    22. <artifactId>spring-boot-starter-web</artifactId>
    23. </dependency>
    24. <dependency>
    25. <groupId>org.springframework.cloud</groupId>
    26. <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
    27. <version>1.1.8.RELEASE</version>
    28. </dependency>
    29. <!-- 用于健康监测自动刷新 -->
    30. <dependency>
    31. <groupId>org.springframework.boot</groupId>
    32. <artifactId>spring-boot-actuator</artifactId>
    33. </dependency>
    34. <dependency>
    35. <groupId>org.springframework.boot</groupId>
    36. <artifactId>spring-boot-actuator-autoconfigure</artifactId>
    37. </dependency>
    38. </dependencies>
    39. <dependencyManagement>
    40. <dependencies>
    41. <dependency>
    42. <groupId>org.springframework.cloud</groupId>
    43. <artifactId>spring-cloud-dependencies</artifactId>
    44. <version>Hoxton.RELEASE</version>
    45. <type>pom</type>
    46. <scope>import</scope>
    47. </dependency>
    48. </dependencies>
    49. </dependencyManagement>
    50. <build>
    51. <plugins>
    52. <plugin>
    53. <groupId>org.springframework.boot</groupId>
    54. <artifactId>spring-boot-maven-plugin</artifactId>
    55. </plugin>
    56. </plugins>
    57. </build>
    58. </project>

    2、使用到配置项的代码

    1. @RefreshScope
    2. @RestController
    3. public class HelloController {
    4. @Value("${name:null}")
    5. private String name;
    6. @Value("${age:0}")
    7. private int age;
    8. @GetMapping("/hello")
    9. public Object hello () {
    10. return name + ": " + age;
    11. }
    12. }

    3、Dockerfile

    1. FROM openjdk:8-jdk-alpine
    2. RUN mkdir -p /app/
    3. COPY ./demo-v6-0.0.1.jar /app/
    4. RUN touch /app/demo-v6-0.0.1.jar
    5. RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

    4、添加账号角色绑定demo-account.yaml

    1. apiVersion: v1
    2. kind: ServiceAccount
    3. metadata:
    4. name: config-reader
    5. namespace: demo
    6. ---
    7. apiVersion: rbac.authorization.k8s.io/v1
    8. kind: Role
    9. metadata:
    10. name: pod-reader
    11. namespace: demo
    12. rules:
    13. - apiGroups:
    14. - ""
    15. resources:
    16. - endpoints
    17. - pods
    18. - configmaps
    19. verbs:
    20. - list
    21. - get
    22. - watch
    23. ---
    24. apiVersion: rbac.authorization.k8s.io/v1
    25. kind: RoleBinding
    26. metadata:
    27. name: pod-reader
    28. namespace: demo
    29. roleRef:
    30. apiGroup: rbac.authorization.k8s.io
    31. kind: Role
    32. name: pod-reader
    33. subjects:
    34. - kind: ServiceAccount
    35. name: config-reader
    36. namespace: demo

    5、configmap

    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. name: demo-configmap
    5. namespace: demo
    6. labels:
    7. spring.cloud.kubernetes.config: "true"
    8. data:
    9. application.yml: |-
    10. server:
    11. port: 8989
    12. spring:
    13. application:
    14. name: demo-configmap
    15. cloud:
    16. kubernetes:
    17. config:
    18. sources:
    19. - name: demo-configmap
    20. namespace: demo
    21. reload:
    22. #自动更新配置的开关设置为打开
    23. enabled: true
    24. monitoring-config-maps: true
    25. monitoring-secrets: true
    26. mode: polling
    27. strategy: refresh
    28. management:
    29. endpoints:
    30. web:
    31. exposure:
    32. include: refresh,health
    33. endpoint:
    34. restart:
    35. enabled: true
    36. health:
    37. enabled: true
    38. info:
    39. enabled: true
    40. age: 18
    41. name: Tom

    6、后端yaml

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: demo
    5. namespace: demo
    6. labels:
    7. app: demo
    8. spec:
    9. replicas: 1
    10. selector:
    11. matchLabels:
    12. app: demo
    13. template:
    14. metadata:
    15. labels:
    16. app: demo
    17. spec:
    18. serviceAccountName: config-reader
    19. imagePullSecrets:
    20. - name: harbor-secret
    21. containers:
    22. - name: demo
    23. image: 192.168.1.6:8037/demo:0.0.1
    24. imagePullPolicy: Always
    25. command: ["java", "-jar", "/app/demo-v6-0.0.1.jar"]
    26. args: ["--spring.config.location=/app/config/application.yml", "--spring.profiles.active=dev"]
    27. ports:
    28. - containerPort: 8001
    29. volumeMounts:
    30. - name: host-time
    31. mountPath: /etc/localtime
    32. - name: demo-config
    33. mountPath: /app/config
    34. volumes:
    35. - name: host-time
    36. hostPath:
    37. path: /etc/localtime
    38. - name: demo-config
    39. configMap:
    40. name: demo-configmap
    41. ---
    42. apiVersion: v1
    43. kind: Service
    44. metadata:
    45. name: demo
    46. namespace: demo
    47. labels:
    48. app: demo
    49. spec:
    50. type: ClusterIP
    51. ports:
    52. - port: 8001
    53. targetPort: 8001
    54. selector:
    55. app: demo

    效果:

    configmap修改前:

     configmap修改后:

     二、手动触发滚动更新,无须引入任何依赖

    1、configmap

    1. apiVersion: v1
    2. kind: ConfigMap
    3. metadata:
    4. name: demo-configmap
    5. namespace: demo
    6. labels:
    7. spring.cloud.kubernetes.config: "true"
    8. data:
    9. application.yml: |-
    10. server:
    11. port: 8989
    12. spring:
    13. application:
    14. name: demo-configmap
    15. age: 18
    16. name: Tom

     2、后端yaml

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: demo
    5. namespace: demo
    6. labels:
    7. app: demo
    8. spec:
    9. replicas: 1
    10. selector:
    11. matchLabels:
    12. app: demo
    13. template:
    14. metadata:
    15. labels:
    16. app: demo
    17. spec:
    18. imagePullSecrets:
    19. - name: harbor-secret
    20. containers:
    21. - name: demo
    22. image: 192.168.1.6:8037/demo:0.0.1
    23. imagePullPolicy: Always
    24. command: ["java", "-jar", "/app/demo-v6-0.0.1.jar"]
    25. args: ["--spring.config.location=/app/config/application.yml", "--spring.profiles.active=dev"]
    26. ports:
    27. - containerPort: 8001
    28. volumeMounts:
    29. - name: host-time
    30. mountPath: /etc/localtime
    31. - name: demo-config
    32. mountPath: /app/config
    33. volumes:
    34. - name: host-time
    35. hostPath:
    36. path: /etc/localtime
    37. - name: demo-config
    38. configMap:
    39. name: demo-configmap
    40. ---
    41. apiVersion: v1
    42. kind: Service
    43. metadata:
    44. name: demo
    45. namespace: demo
    46. labels:
    47. app: demo
    48. spec:
    49. type: ClusterIP
    50. ports:
    51. - port: 8001
    52. targetPort: 8001
    53. selector:
    54. app: demo

    3、利用patch更新annotation的值,来触发pod滚动更新

    kubectl patch deployment -n demo --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20220614" }}}}}'

    三、Secret保存账号密码信息

    思路:jasypt加密 -> ENC(加密后的字符串) -> base64编码 -> Secret

    1、jasypt加密

    2、base64编码

     

     3、secret

     4、后端引用yaml

     5、修改configmap值后,发现程序中的值不会自动更新,采用手动方式触发刷新

    curl ‘ip:port/actuator/refresh’

     

     

     

  • 相关阅读:
    深度学习基础知识 Batch Normalization的用法解析
    Java代码中如何向HashMap对象中添加(Map集合对象)呢?
    CentOS 7使用RPM包安装MySQL5.7
    nginx loadbalance spring server负载均衡
    仿真模型简单介绍
    8.26 Day44---项目部署
    MySQL单表查询和多表查询
    Java私活500元,做个JavaWeb仓储管理网站(二)
    CMT2380F32模块开发19-LVD例程
    【校招VIP】前端算法考察之字符串
  • 原文地址:https://blog.csdn.net/u012843873/article/details/125179937