Spring Cloud 使用 Kubernetes 作为配置中心

September 8, 2019 · 251 words · 2 min

Spring Cloud 使用 Kubernetes 作为配置中心

Spring Cloud 可以通过使用 Kubernetes 的 ConfigMap 作为配置中心,实现配置的拉取和刷新

创建应用

添加依赖

  • build.gradle
dependencies {
	implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-config'
}

添加配置

ConfigMap

kind: ConfigMap
apiVersion: v1
metadata:
  name: config-map-service
data:
  application.yaml: |-
    spring:
      profiles: dev
    config:
        applicationVersion: dev-0.0.1
    ---
    spring:
      profiles: prod
    config:
        applicationVersion: prod-0.0.1    

ConfigMap的名称要和应用名称一致,否则需要指定相应的名称;应用的配置信息可以使用application.yaml|properties作为 key,需要注意的是环境配置是spring.profiles,而不是spring.profiles.active,否则只会使用最后一行的配置

通过以下命令将 ConfigMap 添加到 Kubernetes 中

kubectl apply -f config-map.yaml 

application.properties

spring.application.name=config-map-service
spring.profiles.active=${PROFILE:dev}
management.endpoint.restart.enabled=true
# Reload Config
spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.reload.mode=polling
spring.cloud.kubernetes.reload.period=5000
spring.cloud.kubernetes.reload.strategy=refresh
  • spring.profiles.active=${PROFILE:dev}用于获取 Deployment 传递的参数来决定使用什么配置

  • spring.cloud.kubernetes.reload.enabled默认是关闭的,所以需要主动开启

  • spring.cloud.kubernetes.reload.mode有两种模式,pollingevent

    • polling会启动一个定时任务,定时拉取配置,时间由spring.cloud.kubernetes.reload.period配置
    • event会监听 Kubernetes 的事件,当 ConfigMap 或者 Secrets 发生变化时会触发配置更新事件
  • spring.cloud.kubernetes.reload.strategy配置更新策略,有 refresh,restart_contextshutdown

    • refresh可以通过设置@RefreshContext或者@ConfigurationProperties更新配置
    • restart_context会主动重启应用
    • shutdown会关闭应用,由 Deployment 检测存活失败后重启应用

需要注意的是,开启了 reload 后,还需要允许应用重启management.endpoint.restart.enabled=true,否则会提示有两个用于重启的 Bean 冲突

添加接口

  • ConfigProperties.java
@Data
@Component
@ConfigurationProperties(prefix = "config")
public class ConfigProperties {
    private String applicationVersion;
}
  • ConfigMapController.java
@RestController
@Slf4j
public class ConfigMapController {

    @Autowired
    private ConfigProperties configProperties;

    @Value("${spring.profiles.active}")
    private String profile;

    @GetMapping("/version")
    public String config() {
        return configProperties.getApplicationVersion();
    }

    @GetMapping("/profile")
    public String profile() {
        return profile;
    }
}

部署应用

  • 构建并上传镜像

  • config-map-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: config-map-service
  labels:
    app.kubernetes.io/name: config-map-service
spec:
  type: NodePort
  ports:
    - port: 8081
      nodePort: 30081
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: config-map-service

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: config-map-service
  labels:
    app.kubernetes.io/name: config-map-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: config-map-service
  template:
    metadata:
      labels:
        app.kubernetes.io/name: config-map-service
    spec:
      containers:
        - name: config-map-service
          image: "hellowoodes/spring-cloud-k8s-config-map:1.2"
          imagePullPolicy: IfNotPresent
          env:
            - name: PROFILE
              value: prod
          ports:
            - name: http
              containerPort: 8081
              protocol: TCP

其中Deployment 的spec.template.spec.envPROFILE用于指定环境

kubectl apply -f config-map-service.yaml

测试

待应用启动后, 访问相应的 URL

  • 查看此时的配置
curl 192.168.0.110:30081/profile
prod%
  • 查看配置的版本
curl 192.168.0.110:30081/version
prod-0.0.1%

修改应用配置,将版本号改为 prod-0.0.2并应用到 Kubernetes 中后再次访问

curl 192.168.0.110:30081/version
prod-0.0.2%
  • 修改spec.template.spec.env.PROFILE配置为 dev 并应用到 Kubernetes 中
curl 192.168.0.110:30081/profile
dev%

查看版本

curl 192.168.0.110:30081/version
dev-0.0.1%