天天看點

Kubernetes 開發 SpringCloud (二)、使用 SpringCloud Kubernetes 元件進行動态配置

Kubernetes 開發 SpringCloud (二)、使用 SpringCloud Kubernetes 元件進行動态配置
歡迎關注我的個人部落格,關注最新動态: http://www.mydlq.club

相關博文:

  • Kubernetes 開發 SpringCloud (一)、使用SpringCloud Kubernetes元件進行服務發現
  • Kubernetes 開發 SpringCloud (二)、使用 SpringCloud Kubernetes 元件進行動态配置
  • Kubernetes 開發 SpringCloud (三)、使用 SpringCloud Feign 進行 SrpingCloud 服務間的通信
  • Kubernetes 開發 SpringCloud (四)、Kubnernetes 部署 Zipkin 搭配 Kafka+ElasticSearch 實作鍊路追蹤

系統環境:

  • Kubernetes 版本:1.14.0
  • SpringCloud Kubernetes 版本:1.0.2.RELEASE
  • 示例部署檔案 Github 位址:https://github.com/my-dlq/blog-example/tree/master/springcloud-kubernetes/springcloud-kubernetes-config-demo

一、介紹

元件簡介

       SpringCloud 一般都是用 SpringBoot 來做腳手架,而 SpringBoot 的配置一般都在 resources 目錄中的

application.yaml

bootstrap.yaml

檔案中。并且 SpringCloud 在本地開發模式中用的是元件 SpringCloud Config 配置中心來對配置檔案進行統一管理、動态更新等,不過在我們開發環境中在這種模式下将配置檔案存入 SVN 或者 Git,當網絡不穩定發生波動時候,服務無法與這些倉庫建立連接配接而導緻不可用。

       由于 Kubernetes 本身存在

ConfigMap

Secret

對象來存儲配置,是以在 Kubernetes 部署 SpringCloud 的應用嘗試不再采用統一配置中心管理配置,而是将配置檔案存入 Kubernetes 的 ConfigMap 與 Secret 資源中,經過嘗試這種做法确實可行。不過用這種方法還面臨一個問題是直接存入 ConfigMap 或者 Secret 中如果配置發生變化,程式是無法感覺到變化進而不會進行自動重新開機或重新整理配置。

       由于上面問題,SpringCloud Kubernetes 提供了

spring-cloud-starter-kubernetes-config

元件來解決在 Kubernetes 環境中使用 ConfigMap 或 Secret 動态配置發現與更新問題,當存在 ConfigMap 中的配置或者存在 Secret 中的密碼發生更改時候,在 Kubernetes 中的服務能及時監控到這一變化進而按照配置的配置更新政策進行動态更新或者服務重新開機。

功能簡介

SpringCloud Kubernetes Config 元件主要提供以下幾種功能:

  • 實時監控 ConfigMap、Secret 配置變化進而更新服務配置。
  • 定時輪詢加載 ConfigMap、Secret 配置進而更新服務配置。

二、SpringCloud Kubernetes 動态配置示例

這裡寫一個使用 spring-cloud-starter-kubernetes-config 元件動态引用 Kubernetes 中的 Config 與 Secret 配置的示例。

注意:示例是在本地啟動,通過 Kubectl 的配置檔案 config 連接配接 Kubernetes 擷取 ConfigMap、Secret 而并非 Kubernetes 中。如果需要将項目推送到 Kubernetes 中進行測試,需要提前建立好一個能讀取 Config 與 Secret 的 ServiceAccount 賬戶供項目使用,防止因為沒有權限而導緻無法擷取 Kubernetes 中的配置資訊。

1、Kubernetes 中部署 ConfigMap、Secret

提前建立

ConfigMap

Secret

兩個配置檔案,并操作

kubectl

工具将兩個對象部署到 Kubernetes 叢集友善測試。

test-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-config
data:
  config.booleanValue: "false"
  config.numberValue: "1000"
  config.stringValue: "configMap中的字元串"
           

test-secret.yaml

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  labels:
    secret: enabled
  name: test-secret
data:
  secret.username: YWRtaW4NCg==         #值:admin
  secret.password: MTIzNDU2             #值:123456
           

将兩個對象部署到 Kubernetes

  • -n :建立資源到指定的 Namespace
$ kubectl apply -f test-configmap.yaml -n mydlqcloud
$ kubectl apply -f test-secret.yaml -n mydlqcloud
           

2、建立 SpringCloud Config 示例項目

這裡用 SpringCloud Kubernetes 中的服務發現元件

spring-cloud-starter-kubernetes-config

來示範擷取 Kubernetes 環境中的

Config

Secret

示例。

(1)、Maven 引入相關變量

在"pom.xml"檔案中引入 SpringBoot 與 SpringCloud Kubernetes Config 相關 Jar。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>club.mydlq</groupId>
    <artifactId>springcloud-kubernetes-config-demo</artifactId>
    <version>0.0.1</version>
    <name>springcloud-kubernetes-config-demo</name>
    <description>springcloud kubernetes config demo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--SpringBoot Web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--SpringBoot Actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
		<!--SpringCloud Kubernetes Config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
            <version>1.0.2.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
           

(2)、配置 Bootstrap.yml 檔案

建立

bootstrap.yml

檔案并設定

flush

config

secret

的相關配置參數。

spring:
  application:
    name: springcloud-kubernetes-config-demo
  cloud:
    kubernetes:
      reload:
        enabled: true
        mode: polling            #監聽模式:
                                 #    (1)、polling:從 ConfigMap 和 Secret 中定期重新整理配置,檢測是否進行了修改。
                                 #    (2)、event(預設):監視配置映射或機密的更改。任何事件都會對配置進行重新檢查,如果發生更改,則會重新加載。
        period: 5000             #重新整理間隔,機關(ms)
        strategy: shutdown       #重新整理模式:
                                 #    (1)、refresh(預設):僅注釋@ConfigurationProperties或@RefreshScope重新加載的配置Bean
                                 #    (2)、restart_context:整個Spring ApplicationContext正常重新開機。使用新配置重新建立Bean。
                                 #    (3)、shutdown:關閉以激活容器的重新開機。使用此級别時,請確定将所有非守護程式線程的生命周期綁定到該級别,
                                 #         并将ApplicationContext 複制控制器或副本集配置為重新啟動該pod。
        monitoring-secrets: true #是否監控 Secret 的更改來執行更新
      config:
        enabled: true            #啟用 ConfigMap 配置功能
        enableApi: true          #啟用通過 K8S API 發現 ConfigMap 配置
        sources:
        - namespace: mydlqcloud  #指定 ConfigMap 名稱
          name: test-config      #指定 Namespace 名稱
      secrets:
        enabled: true            #啟用 Secret 配置功能
        enableApi: true          #啟用通過 K8S API 發現 Secret 配置,預設不開啟
        namespace: mydlqcloud    #指定 Namespace 名稱
        name: test-secret        #指定 Secret 名稱,根據這個名詞引入對應 Secret 配置
        #labels:                  #指定 Label 标簽名詞,根據這個标簽篩選 Secret,讀取其中配置
        #  secret: enabled        #自定義的 Label
           

(3)、配置 application 檔案

自定義本地配置,變量名保持和

ConfigMap

Secret

中的一緻,并且值要設定的不同,這樣友善測試時候區分擷取的變量是從本地擷取的還是從 Kubernetes 中的

ConfigMap

Secret

中擷取的。

服務動态配置需要設定"management.endpoint.restart.enabled=true"這個參數,否則啟動會報錯。
management:         #Actuator 配置
  server:
    port: 8081
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    restart:
      enabled: true

config:             #自定義程式中的 ConfigMap 參數配置
  numberValue: 1
  stringValue: 這是在程式中的配置
  booleanValue: "true"

secret:             #自定義程式中的 Secret 參數配置
  username: application
  password: 123456
           

(4)、設定 ConfigRead 類讀取自定義配置

設定 ConfigRead 類用于測試讀取 Kubernetes 中 ConfigMap 中的配置。

ConfigRead.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "config")
public class ConfigRead {

    private String stringValue;
    private Integer numberValue;
    private boolean booleanValue;

    public String getStringValue() {
        return stringValue;
    }
    public void setStringValue(String stringValue) {
        this.stringValue = stringValue;
    }
    public Integer getNumberValue() {
        return numberValue;
    }
    public void setNumberValue(Integer numberValue) {
        this.numberValue = numberValue;
    }
    public boolean isBooleanValue() {
        return booleanValue;
    }
    public void setBooleanValue(boolean booleanValue) {
        this.booleanValue = booleanValue;
    }

}
           

(5)、設定 SecretRead 類讀取自定義配置

設定 SecretRead 類用于測試讀取 Kubernetes 中 Secret 中的配置。

SecretRead.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "secret")
public class SecretRead {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
           

(6)、建立 Controller 類顯示自定義配置資訊

建立 ConfigController 類中寫兩個接口,分别用于測試調用

ConfigMap

Secret

import club.mydlq.admin.configMap.ConfigRead;
import club.mydlq.admin.secret.SecretRead;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

@RestController
public class ConfigController {

    @Autowired
    private ConfigRead configRead;

    @Autowired
    private SecretRead secretRead;

    @GetMapping("/configmap")
    public  Map<String,Object> getConfig() {
        Map<String,Object> map = new HashMap<>();
        map.put("StringValue:",configRead.getStringValue());
        map.put("NumberValue:",configRead.getNumberValue());
        map.put("BooleanValue:",configRead.isBooleanValue());
        return map;
    }

    @GetMapping("/secret")
    public  Map<String,Object> getSecret() {
        Map<String,Object> map = new HashMap<>();
        map.put("username:",secretRead.getUsername());
        map.put("password:",secretRead.getPassword());
        return map;
    }

}
           

(7)、建立啟動類并啟用服務發現注解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
           

3、調用接口測試

上面定義了兩個接口分别為:

  • 服務發現清單接口:/configmap
  • 服務執行個體資訊接口:/secret

然後進行測試,首先測試直接調用接口檢視是否能擷取 Kubernetes 中

ConfigMap

Secret

中的參數資訊。之後更改 Kubernetes 中 ConfigMap、Secret 參數的值後等待一段時間再次調用接口測試,檢測新擷取的參數資訊中的值是否發生變化。最後将 Kubernetes 中的

ConfigMap

Secret

删除,檢視是否能擷取程式内部設定的預設的參數。

下面按上面的步驟進行測試:

調用接口讀取 ConfigMap 與 Secret 配置測試

/configmap 資訊:

{
    "StringValue:": "configMap中的字元串",
    "NumberValue:": 1000,
    "BooleanValue:": false
}
           

/secret 資訊:

{
    "username:": "admin",
    "password:": "123456"
}
           

更新 ConfigMap 與 Secret 後調用接口測試

在 Kubernetes 中更改 ConfigMap 中的

StringValue

參數,往後面追加兩個字元

AB

,再

更改 Secret 中的

Username

參數的值 “admin” 往後面追加兩個字元

AB

形成新的 Base64字元串值為 “YWRtaW5BQgo=” ,用這個值替換 Secret 的參數

Username

值,這時候等幾秒後再次調用接口測試,檢視配置是否發生變化。

/configmap 資訊:

{
    "StringValue:": "configMap中的字元串AB",
    "NumberValue:": 1000,
    "BooleanValue:": false
}
           

/secret 資訊:

{
    "username:": "adminAB",
    "password:": "123456"
}
           

本人這裡調用接口擷取的資訊跟之前的已經發生變化。

将 ConfigMap 與 Secret 删除後調用接口測試

将 Kubernetes 中的

ConfigMap

Secret

删除後再次調用接口進行測試。

{
    "StringValue:": "這是在程式中的配置",
    "NumberValue:": 1,
    "BooleanValue:": true
}
           

/secret 資訊:

{
    "username:": "application",
    "password:": "123456"
}
           

可以看到配置已經變成程式中設定的配置,由此可以推測出使用

SpringCloud Kubernetes Config

可以擷取 Kubernetes 中

ConfigMap

Secret

的配置。如果配置發生更改,程式能夠及時檢測到并更新程式中的配置。如果不能擷取 Kubernetes 中的配置資訊,則直接使用程式中配置的預設資訊。

三、可配置的參數清單

SpringCloud kubernetes Config 中可以設定 ConfigMap 與 Secret 動态配置參數,如下:

ConfigMap 可配置參數

讀取 ConfigMap 的配置
參數名稱 類型 預設值 參數描述
spring.cloud.kubernetes.config.enabled Boolean true 是否啟動 Config 動态配置
spring.cloud.kubernetes.config.name String ${spring.application.name} 設定要查找的 ConfigMap 的名稱
spring.cloud.kubernetes.config.namespace String Client名稱空間 設定在哪個 Kubernetes Namespace 查找 ConfigMap 資源
spring.cloud.kubernetes.config.paths List null 設定ConfigMap裝入執行個體的路徑
spring.cloud.kubernetes.config.enableApi Boolean true ConfigMap通過API 啟用或禁用使用執行個體

Secret 可配置參數

讀取 Secret 的配置
參數名稱 類型 預設值 參數描述
spring.cloud.kubernetes.secrets.enabled Boolean true 是否啟動 Secret 動态配置
spring.cloud.kubernetes.secrets.name String ${spring.application.name} 設定要查找的 Secret 的名稱
spring.cloud.kubernetes.secrets.namespace String Client名稱空間 設定在哪個 Kubernetes Namespace 查找 Secret 資源
spring.cloud.kubernetes.secrets.labels Map null 設定用于查找 Secret 的标簽
spring.cloud.kubernetes.secrets.paths List null 設定安裝 Secret 的路徑
spring.cloud.kubernetes.secrets.enableApi Boolean false 啟用或禁用通過 API 監聽 Secret

Reload 可配置參數

配置動态更新配置
參數名稱 類型 預設值 參數描述
spring.cloud.kubernetes.reload.enabled Boolean false 啟動動态配置監控
spring.cloud.kubernetes.reload.monitoring-config-maps Boolean true 允許監視 ConfigMap 中的更改
spring.cloud.kubernetes.reload.monitoring-secrets Boolean false 允許監控 Secret 的變化
spring.cloud.kubernetes.reload.strategy Enum refresh

配置更新政策:

- refresh(更新)

- restart_context(重新開機Spring容器)

- shutdown(殺死應用使Kubernetes對其重新開機))

spring.cloud.kubernetes.reload.mode Enum event

指定監聽政策:

- event:配置發生變化就執行更新

- polling:定時檢測配置變化進而更新配置

spring.cloud.kubernetes.reload.period Duration 15s 使用 polling 政策時檢測間隔時間

—END—

歡迎關注我的個人部落格,關注最新動态: http://www.mydlq.club

繼續閱讀