使用 K8s ConfigMap 替换 Apollo
在微服务架构中,配置管理是一个非常关键的部分。Apollo 是我们使用较多的一个配置管理系统,它提供了实时更新、配置缓存、灰度发布等高级功能。不过随着 Kubernetes 的普及,大家可能会问配置管理与 Kubernetes 的生态系统能否无缝对接呢?答案是肯定的,Kubernetes 里有一个类似的资源,即 ConfigMap,也叫配置字典,主要就是用来干配置管理这件事的。本文将简单介绍一下如何将 Apollo 替换为 Kubernetes ConfigMap,并尽可能少地进行代码改动。看完之后如何选型,相信你就会有自己的答案了!
切换步骤
1. 创建 ConfigMap
首先,将 Apollo 中的配置项导出,并创建相应的 ConfigMap。比如我们在 Apollo 里有一个名为 my-config 的 app,使用的是 application.properties
配置文件,则可以使用以下 YAML 文件创建一个名为 configmap.yaml 的 ConfigMap 资源:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
application.properties: |
some.config.key=someValue
another.config.key=anotherValue
# 其他配置项...
然后使用 kubectl
命令将其应用到 Kubernetes 集群中的 test 命名空间里:
kubectl -n test apply -f configmap.yaml
2. 修改 Kubernetes Deployment
在 Deployment 配置中,将 ConfigMap 挂载到容器的文件系统中,并指定 Spring Boot 使用这个额外的配置文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 1
template:
spec:
containers:
- name: my-container
image: my-image
args:
- "--spring.config.additional-location=file:/config/application.properties"
volumeMounts:
- name: config-volume
mountPath: /config/application.properties
subPath: application.properties
volumes:
- name: config-volume
configMap:
name: my-config
items:
- key: application.properties
path: application.properties
3. 修改 Spring Boot 应用代码
移除与 Apollo 相关的注解和依赖。在 Spring Boot 应用的启动类中,移除 @EnableApolloConfig
注解:
package com.foobar.demo;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients({"demo.service.feign"})
@ServletComponentScan(basePackages = {"demo.config"})
@MapperScan(value = "com.foobar.demo.mapper")
@EnableEncryptableProperties
@ComponentScan(basePackages = { "demo.service.feign", "com.foobar.demo", "demo.aop","demo.config", "demo.user.service", "demo.utils", "cn.foobar"})
public class MyDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MyDemoApplication.class, args);
}
}
在 pom.xml
中移除 Apollo 客户端的相关依赖:
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.8.0</version>
</dependency>
至此,基本的切换工作就完成了。我们的应用将使用 Kubernetes ConfigMap 中的配置文件,而不再使用 Apollo。
Apollo 与 ConfigMap 的方案对比
Apollo 的优势:
- 实时更新和热加载:Apollo 支持配置的实时更新,客户端可以自动接收并应用新配置,无需重启应用。
- 配置缓存:Apollo 客户端会将配置缓存到本地,提高读取配置的效率和性能。
- 灰度发布:支持配置的灰度发布,可以逐步推送配置变更,降低风险。
- 版本管理:Apollo 提供配置的版本控制和回滚功能,方便管理配置历史。
ConfigMap 的优势:
- 与 Kubernetes 深度集成:ConfigMap 作为 Kubernetes 原生资源,与其他 Kubernetes 资源无缝集成,管理和使用的方式是一致的。
- 简洁性:直接在 Kubernetes 中管理配置,减少了引入第三方系统的复杂性。
- 声明式管理:通过 YAML 文件声明配置,可以与 Kubernetes 资源一同进行版本控制和审计。
- 自动化工具支持:可以与 Helm、Kustomize 等工具配合,支持复杂的部署和配置管理场景。
ConfigMap 的不足之处:
- 缺乏实时更新和热加载:
- 可以使用
Reloader
等工具监控 ConfigMap 的变化,并自动触发 Pod 重启或信号通知应用重新加载配置。 - 可以让应用程序实现文件监听机制,自动重新加载配置文件内容。
- 可以使用
- 缺乏配置缓存:
- 需要在应用程序中自行实现缓存逻辑,如果需要缓存机制的话。
- 缺乏高级管理功能:
- 可以使用 Helm 管理 ConfigMap,通过 Helm 的版本管理功能实现配置版本控制和回滚。
- 可以将配置文件存储在 Git 仓库中,通过 Git 的版本控制管理配置变更。
结语
将 Apollo 替换为 Kubernetes ConfigMap 并不复杂,但需要注意配置管理的细节改动和功能上的差异。通过使用一些工具和方法,可以弥补 ConfigMap 在配置中心场景下相对于 Apollo 的不足,达到类似 Apollo 的配置管理效果,不过在复杂性上就变得更高了,大家还是得根据自身的实际情况来做决定才最为妥当。