使用SpringCloud Kubernetes组件获取Config和Secret
介绍
SpringCloud Kubernetes,提供了使用 Kubernetes 本地服务的 Spring Cloud 通用接口实现。目标是促进 Spring Cloud 和运行在 Kubernetes 中的 Spring Boot 应用程序的集成。
SpringCloud Kubernetes 能在 Kubernetes 中完成服务发现和配置监听功能主要依赖 Fabric8 提供的Kubernetes Client 组件,该组件是 Kubernetes Java API 的第三方客户端,它的主要功能是远程操作 Kubernetes API 完成在 Kubernetes 环境下的一系列操作。
功能:
- 在 Kubernetes 中实现服务发现、服务名称解析功能。
- 在 Kubernetes 中读取
ConfigMaps
和 Secrets
的配置,当 ConfigMap 或 Secret 更改时重新加载应用程序属性。
- 在 Kubernetes 可去掉 Kubernetes 自带的服务负载均衡,实现与
Ribbon
结合,通过 Ribbon 完成负载均衡。
权限配置
在有k8s集群的机器上把root/.kube/目录下的config文件复制一份放到windows用户下的.kube文件夹中
Maven 配置
spring boot项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> </parent>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId> <version>1.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies>
|
k8s中的config和secret文件
test-configmap.yaml
1 2 3 4 5 6 7 8 9
| apiVersion: v1 kind: ConfigMap metadata: name: test-config namespace: default data: config.booleanValue: "false" config.numberValue: "1000" config.stringValue: "configMap中的字符串"
|
test-secret.yaml
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: v1 kind: Secret type: Opaque metadata: labels: secret: enabled name: test-secret namespace: default data: secret.username: YWRtaW4NCg== secret.password: MTIzNDU2
|
简单的Controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @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.getBooleanValue()); 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; } }
|
实体类
ConfigRead.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @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; }
}
|
SecretRead.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @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; } }
|
项目参数配置
application.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| spring: application: name: k8sdemo cloud: kubernetes: client: namespace: default discovery: enabled: true all-namespaces: true
server: port: 8080
management: server: port: 8081 endpoints: web: exposure: include: "*" endpoint: restart: enabled: true
config: numberValue: 1 stringValue: 这是在程序中的配置 booleanValue: "true"
secret: username: application password: 123456
|
Bootstrap.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| spring: application: name: k8sdemo cloud: kubernetes: reload: enabled: true mode: polling period: 5000 strategy: shutdown monitoring-secrets: true config: enabled: true enableApi: true sources: - namespace: default name: test-config secrets: enabled: true enableApi: true namespace: default name: test-secret
|
创建启动类并启用服务发现注解
1 2 3 4 5 6 7 8
| @SpringBootApplication public class Application {
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}
|
测试接口
调用接口读取 ConfigMap 与 Secret 配置测试
/configmap 信息:
1 2 3 4 5
| { "StringValue:": "configMap中的字符串", "NumberValue:": 1000, "BooleanValue:": false }
|
/secret 信息:
1 2 3 4
| { "username:": "admin", "password:": "123456" }
|
更新 ConfigMap 与 Secret 后调用接口测试
在 Kubernetes 中更改 ConfigMap 中的 StringValue
参数,往后面追加两个字符 AB
,再 更改 Secret 中的 Username
参数的值 “admin” 往后面追加两个字符 AB
形成新的 Base64字符串值为 “YWRtaW5BQgo=” ,用这个值替换 Secret 的参数 Username
值,这时候等几秒后再次调用接口测试,查看配置是否发生变化。
/configmap 信息:
1 2 3 4 5
| { "StringValue:": "configMap中的字符串AB", "NumberValue:": 1000, "BooleanValue:": false }
|
/secret 信息:
1 2 3 4
| { "username:": "adminAB", "password:": "123456" }
|
将 ConfigMap 与 Secret 删除后调用接口测试
将 Kubernetes 中的 ConfigMap
、Secret
删除后再次调用接口进行测试。
1 2 3 4 5
| { "StringValue:": "这是在程序中的配置", "NumberValue:": 1, "BooleanValue:": true }
|
/secret 信息:
1 2 3 4
| { "username:": "application", "password:": "123456" }
|
参考链接
Kubernetes 开发 SpringCloud (二)、使用 SpringCloud Kubernetes 组件进行动态配置