配置中心实现-configmap
关于SpringCloud Config
如果您开发过SpringCloud应用,相信您对SpringCloud Config不会陌生,在微服务环境中,业务应用可以从config server获取所需的配置信息,如下图所示:
关于kubernetes的configmap
这是kubernetes提供的基本服务之一,创建一个configmap资源,对应着一份配置文件,可以将该资源通过数据卷的形式映射到Pod上,这样Pod就能用上这个配置文件了,如下图:
spring-cloud-kubernetes带来的礼物
spring-cloud-starter-kubernetes-config是spring-cloud-starter-kubernetes框架下的一个库,作用是将kubernetes的configmap与SpringCloud Config结合起来,通过spring-cloud-starter-kubernetes-config,我们的应用就像在通过SpringCloud Config取得配置信息,只不过这里的配置信息来自kubernetes的configmap,而不是SpringCloud Config server,如下图所示:
理论上的准备工作已经差不多了,接下来通过实战来展示spring-cloud-starter-kubernetes-config的神奇之处;
实现
编码
1.在业务工程中添加对spring-cloud-kubernetes-config组件的依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
2.项目的src\main\resources\bootstrap.yml的文件中,添加工程对configmap的读取依赖。
如果不指定namespace,默认会读pod所部署的namespace下的configmap。
spring:
cloud:
kubernetes:
config:
sources:
- name: ${spring.application.name}
# namespace: ${cloud.kubernetes.namespace}
也可以在bootstrap.properties中
spring.cloud.kubernetes.config.sources.name=${spring.application.name}
可见新增了配置项spring.cloud.kubernetes.config.source.name和spring.cloud.kubernetes.config.source.namespace,用于配置信息来源于kubernetes的哪个namespace下的哪个configmap;
- 增加一个配置类UserProperties.java,注解ConfigurationProperties的prefix="us.common.user"表示该类用到的配置项都是名为"message"的配置项的子内容 :
package com.us.common.user.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Getter;
import lombok.Setter;
@ConfigurationProperties(prefix = "us.common.user")
@Getter
@Setter
public class UserProperties {
private String message = "This is a static message";
}
4.启动类UniverseServiceAppication .java,使用注解EnableConfigurationProperties使用配置类UserProperties 有效。
@EnableDiscoveryClient
@EnableTransactionManagement
@SpringBootApplication
@EnableConfigurationProperties(UserProperties.class) //添加该行代码
public class UniverseServiceAppication {
public static void main(String[] args) {
SpringApplication.run(UniverseServiceAppication.class, args);
}
}
5.提供一个Rest API 用于配置动态被修改的测试。
package com.us.common.user.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.us.common.user.properties.UserProperties;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
/**
* 用户
*/
@Slf4j
@RestController
@Api(tags = "用户模块配置api")
public class UserConfigController {
@Autowired
private UserProperties userProperties;
@GetMapping("/users/conf/hello")
public String hello() {
return userProperties.getMessage() + " [" + new SimpleDateFormat().format(new Date()) + "]";
}
}
权限配置
由于应用要获取k8s的config信息,需要所在的pod有访问k8s的api-server的权限,下面通过一些配置,对namespace下的pod进行授权。
- 创建角色
执行以下脚本
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: saas-dev
name: endpoints-reader-saas-dev
rules:
- apiGroups: [""]
resources: ["pods","configmaps"]
verbs: ["get", "watch", "list"]
- 角色对namespace的绑定
kubectl create clusterrolebinding endpoints-reader-saas-dev-default \
--clusterrole=endpoints-reader-saas-dev \
--serviceaccount=saas-dev:default
验证
先启动应用,通过URL访问url, http://IP:PORT/users/conf/hello,会得到"static"的关键字。
This is a static message
再添加一个configmap配置,对properties中的属性配置进行修改。
kind: ConfigMap
apiVersion: v1
metadata:
name: universe-service
namespace: saas-dev
data:
application.yml: |-
us:
common:
user:
message: This is a dynamic message
将配置应用到k8s环境以后,通过URL访问url, http://IP:PORT/users/conf/hello,会得到"dynamic"的关键字。
This is a dynamic message
验证完成。