
歡迎關注我的個人部落格,關注最新動态: 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