MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Kubernetes 集群中配置中心的深度集成

2021-07-044.1k 阅读

Kubernetes 集群中配置中心的深度集成

在现代微服务架构中,配置管理是一个至关重要的环节。随着微服务数量的增多以及应用场景的复杂化,如何高效、灵活且安全地管理各个微服务的配置成为了关键挑战。Kubernetes(简称 K8s)作为容器编排领域的事实标准,为容器化应用提供了强大的管理能力,而配置中心的深度集成则能进一步提升 K8s 集群的运维效率和应用的灵活性。本文将深入探讨在 Kubernetes 集群中如何深度集成配置中心。

一、配置中心在微服务架构中的重要性

1.1 配置集中管理

在传统单体应用中,配置通常嵌入在代码中或者存在于本地配置文件里。但在微服务架构下,每个微服务可能有自己独立的配置需求,而且可能运行在多个实例上。将配置集中管理到配置中心,可以方便地对所有微服务的配置进行统一修改、版本控制和审计。例如,当需要修改数据库连接字符串时,只需在配置中心一处修改,所有依赖该配置的微服务就能获取到新的配置。

1.2 环境隔离与动态更新

不同的环境(开发、测试、生产)可能需要不同的配置。配置中心可以轻松实现环境隔离,为每个环境提供独立的配置集。同时,配置中心支持动态更新配置,无需重启微服务实例就能使新配置生效,这对于在线业务的运维非常关键。比如,在进行流量控制时,可以实时调整限流阈值,而不会影响服务的正常运行。

1.3 安全配置管理

配置中心可以对敏感配置(如数据库密码、API 密钥等)进行加密存储,并通过安全的方式将解密后的配置传递给微服务。这增强了配置的安全性,降低了敏感信息泄露的风险。

二、Kubernetes 原生配置管理机制

2.1 ConfigMap

ConfigMap 是 Kubernetes 提供的一种用于存储不敏感配置数据的 API 对象。它可以以键值对的形式存储配置信息,并通过挂载卷(Volume)或环境变量的方式注入到 Pod 中。

2.1.1 创建 ConfigMap

可以通过 YAML 文件创建 ConfigMap,例如:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  application.properties: |
    server.port=8080
    spring.datasource.url=jdbc:mysql://localhost:3306/mydb
    spring.datasource.username=root

上述 YAML 文件创建了一个名为 my - configmap 的 ConfigMap,其中包含了 application.properties 的配置内容。

2.1.2 在 Pod 中使用 ConfigMap

通过挂载卷的方式:

apiVersion: v1
kind: Pod
metadata:
  name: my - pod
spec:
  containers:
  - name: my - container
    image: my - image
    volumeMounts:
    - name: config - volume
      mountPath: /config
  volumes:
  - name: config - volume
    configMap:
      name: my - configmap

这样,my - configmap 中的配置就会被挂载到 /config 目录下,容器内的应用可以从该目录读取配置。

通过环境变量的方式:

apiVersion: v1
kind: Pod
metadata:
  name: my - pod
spec:
  containers:
  - name: my - container
    image: my - image
    env:
    - name: SERVER_PORT
      valueFrom:
        configMapKeyRef:
          name: my - configmap
          key: application.properties
          optional: false

这里从 my - configmap 中读取 application.properties 中的 server.port 配置,并设置为容器内的环境变量 SERVER_PORT

2.2 Secret

Secret 与 ConfigMap 类似,但主要用于存储敏感信息,如密码、证书等。Secret 支持多种类型,包括 Opaquekubernetes.io/dockerconfigjson 等。

2.2.1 创建 Secret

创建一个存储数据库密码的 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: my - secret
type: Opaque
data:
  password: cGFzc3dvcmQ=

这里的 password 是经过 Base64 编码的密码。

2.2.2 在 Pod 中使用 Secret

与 ConfigMap 类似,可以通过挂载卷或环境变量的方式使用 Secret。例如,通过挂载卷:

apiVersion: v1
kind: Pod
metadata:
  name: my - pod
spec:
  containers:
  - name: my - container
    image: my - image
    volumeMounts:
    - name: secret - volume
      mountPath: /secrets
  volumes:
  - name: secret - volume
    secret:
      secretName: my - secret

容器可以从 /secrets 目录下读取密码。

三、常用配置中心选型

3.1 Spring Cloud Config

Spring Cloud Config 是 Spring Cloud 生态系统中的配置管理工具,主要为 Spring Boot 应用提供配置管理支持。它支持从多种后端存储(如 Git、SVN、本地文件系统等)获取配置,并提供了加密/解密功能。

3.1.1 架构

Spring Cloud Config 由两部分组成:Config Server 和 Config Client。Config Server 负责存储和提供配置,而 Config Client 则是微服务中用于获取配置的组件。

3.1.2 配置示例

在 Config Server 端,配置 application.yml

server:
  port: 8888
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your - repo/config - repo

上述配置表示 Config Server 从指定的 Git 仓库获取配置。

在 Config Client 端,在 bootstrap.yml 中配置:

spring:
  application:
    name: my - service
  cloud:
    config:
      uri: http://config - server:8888
      fail - fast: true

这样,my - service 微服务就能从 Config Server 获取配置。

3.2 Apollo

Apollo 是携程开源的配置管理中心,具有丰富的功能,如配置的灰度发布、版本管理、多环境支持等。它采用了客户端和服务端架构,服务端负责配置的存储和管理,客户端负责拉取和监听配置变化。

3.2.1 架构

Apollo 服务端包括 Config Service 和 Admin Service,分别负责配置的读取和管理。客户端通过 HTTP 长连接从 Config Service 获取配置,并通过 Watch 机制监听配置变化。

3.2.2 配置示例

在 Apollo 客户端,引入依赖:

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo - client</artifactId>
    <version>1.9.0</version>
</dependency>

application.properties 中配置:

app.id=my - app
apollo.meta=http://apollo - server:8080

这样,客户端就能连接到 Apollo 服务端获取配置。

3.3 Nacos

Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它提供了丰富的配置管理功能,支持多种数据格式(如 properties、yaml 等),并且与 Spring Cloud Alibaba 生态系统紧密集成。

3.3.1 架构

Nacos 由 Server 端和 Client 端组成。Server 端负责配置的存储、管理和推送,Client 端负责拉取和监听配置变化。

3.3.2 配置示例

在 Nacos 客户端,引入依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring - cloud - starter - alibaba - nacos - config</artifactId>
</dependency>

bootstrap.properties 中配置:

spring.application.name=my - service
spring.cloud.nacos.config.server - addr=127.0.0.1:8848
spring.cloud.nacos.config.file - extension=properties

通过上述配置,my - service 微服务可以从 Nacos 获取配置。

四、在 Kubernetes 集群中集成配置中心

4.1 以 Spring Cloud Config 为例

4.1.1 部署 Config Server

创建一个 Config Server 的 Deployment 和 Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: config - server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: config - server
  template:
    metadata:
      labels:
        app: config - server
    spec:
      containers:
      - name: config - server
        image: your - config - server - image
        ports:
        - containerPort: 8888
apiVersion: v1
kind: Service
metadata:
  name: config - server
spec:
  selector:
    app: config - server
  ports:
  - protocol: TCP
    port: 8888
    targetPort: 8888

4.1.2 配置微服务使用 Config Server

在微服务的 Deployment 中,配置环境变量:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my - service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my - service
  template:
    metadata:
      labels:
        app: my - service
    spec:
      containers:
      - name: my - service - container
        image: my - service - image
        env:
        - name: SPRING_APPLICATION_NAME
          value: my - service
        - name: SPRING_CLOUD_CONFIG_URI
          value: http://config - server:8888

这样,my - service 的各个实例就能从 Config Server 获取配置。

4.2 以 Apollo 为例

4.2.1 部署 Apollo Server

可以参考 Apollo 的官方文档进行部署。通常需要创建相关的数据库表,然后启动 Apollo 的 Config Service 和 Admin Service。例如,使用 Docker 部署:

docker run -d -p 8080:8080 apollo - config - service
docker run -d -p 8090:8090 apollo - admin - service

4.2.2 配置微服务使用 Apollo

在微服务的 Deployment 中,配置环境变量:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my - service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my - service
  template:
    metadata:
      labels:
        app: my - service
    spec:
      containers:
      - name: my - service - container
        image: my - service - image
        env:
        - name: APP_ID
          value: my - app
        - name: APOLLO_META
          value: http://apollo - server:8080

微服务通过这些环境变量连接到 Apollo Server 获取配置。

4.3 以 Nacos 为例

4.3.1 部署 Nacos Server

同样可以参考 Nacos 的官方文档进行部署。可以使用 Docker 快速部署:

docker run -d -p 8848:8848 nacos/nacos - server

4.3.2 配置微服务使用 Nacos

在微服务的 Deployment 中,配置环境变量:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my - service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my - service
  template:
    metadata:
      labels:
        app: my - service
    spec:
      containers:
      - name: my - service - container
        image: my - service - image
        env:
        - name: SPRING_APPLICATION_NAME
          value: my - service
        - name: SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR
          value: 127.0.0.1:8848

这样,微服务就能从 Nacos 获取配置。

五、配置中心与 Kubernetes 集成的高级特性

5.1 配置的动态更新与热加载

当配置在配置中心发生变化时,希望微服务能够实时感知并应用新的配置,而无需重启。以 Spring Boot 应用为例,结合 Spring Cloud Config 和 Spring Cloud Bus 可以实现配置的动态更新。

5.1.1 配置 Spring Cloud Bus

在微服务中引入 Spring Cloud Bus 依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring - cloud - starter - bus - rabbit</artifactId>
</dependency>

application.yml 中配置:

spring:
  rabbitmq:
    host: rabbitmq - server
    port: 5672
    username: guest
    password: guest

在 Config Server 端,添加 spring - cloud - config - monitor 依赖,并配置:

management:
  endpoints:
    web:
      exposure:
        include: bus - refresh

这样,当配置在 Config Server 发生变化时,通过发送一个 POST 请求到 /actuator/bus - refresh 端点,就能触发所有微服务更新配置。

5.2 多集群配置管理

在大型企业中,可能存在多个 Kubernetes 集群,如生产集群、测试集群等。配置中心需要支持在不同集群间共享和隔离配置。以 Apollo 为例,可以通过 Namespace 来实现多集群配置管理。

5.2.1 使用 Namespace

在 Apollo 中,可以为每个集群创建一个独立的 Namespace。例如,创建一个名为 prod - cluster 的 Namespace 用于生产集群的配置,创建 test - cluster 的 Namespace 用于测试集群的配置。微服务在启动时,根据所在集群选择对应的 Namespace 获取配置。

5.3 配置的版本控制与回滚

配置中心应该支持配置的版本控制,以便在出现问题时能够回滚到之前的配置版本。以 Spring Cloud Config 为例,由于它可以从 Git 仓库获取配置,利用 Git 的版本控制功能就能实现配置的版本管理。

5.3.1 利用 Git 版本控制

在 Config Server 配置从 Git 仓库获取配置后,通过 Git 的 committag 等操作,可以对配置进行版本标记。当需要回滚时,只需要切换到对应的 committag,Config Server 就能提供旧版本的配置,微服务也能获取到旧配置并应用。

六、配置中心集成的安全考虑

6.1 传输安全

配置在从配置中心传输到微服务的过程中,需要保证数据的保密性和完整性。通常可以采用 SSL/TLS 加密协议。

6.1.1 使用 SSL/TLS

以 Spring Cloud Config 为例,可以在 Config Server 端配置 HTTPS:

server:
  port: 8888
  ssl:
    key - store: classpath:keystore.jks
    key - store - password: password
    key - password: password

在 Config Client 端,配置信任该证书:

spring:
  cloud:
    config:
      uri: https://config - server:8888
      fail - fast: true
      discovery:
        enabled: true
        service - id: config - server
      retry:
        initial - interval: 1000
        multiplier: 2
        max - interval: 10000
        max - attempts: 10
  http:
    client:
      ssl:
        trust - store: classpath:truststore.jks
        trust - store - password: password

这样,配置在传输过程中就会被加密。

6.2 访问控制

配置中心需要严格控制对配置的访问,只有授权的微服务才能获取相应的配置。以 Apollo 为例,可以通过 Token 进行身份验证。

6.2.2 Token 身份验证

在 Apollo 客户端,配置 Token:

app.id=my - app
apollo.meta=http://apollo - server:8080
apollo.accesskey=your - access - key
apollo.secret=your - secret - key

Apollo Server 在接收到客户端请求时,会验证 Token 的有效性,只有验证通过才能返回配置。

6.3 配置加密

对于敏感配置,如数据库密码、API 密钥等,需要在配置中心进行加密存储。Spring Cloud Config 提供了加密/解密功能。

6.3.3 使用 Spring Cloud Config 加密

在 Config Server 端,配置加密密钥:

encrypt.key=your - encryption - key

然后可以使用 curl 命令对敏感配置进行加密:

curl localhost:8888/encrypt -d my - password

加密后的配置存储在 Git 仓库中,当微服务获取配置时,Config Server 会自动解密并提供给微服务。

七、故障排查与优化

7.1 常见故障及排查方法

7.1.1 配置获取失败

可能原因包括配置中心服务不可用、网络问题、配置中心配置错误等。可以通过查看微服务的日志,检查是否有连接配置中心失败的错误信息。例如,在 Spring Boot 应用中,可以查看 application.log 文件。如果是网络问题,可以使用 pingtelnet 命令检查配置中心的网络连通性。

7.1.2 配置更新不及时

这可能是由于配置中心的推送机制问题或微服务的监听机制异常。以 Apollo 为例,可以查看 Apollo Server 的日志,检查配置推送是否成功。在微服务端,检查是否正确配置了监听配置变化的逻辑。

7.2 性能优化

7.2.1 缓存配置

配置中心可以采用缓存机制来提高配置获取的性能。例如,Nacos 支持本地缓存,微服务在首次获取配置后,会将配置缓存到本地,下次获取时直接从本地缓存读取,减少对 Nacos Server 的请求。

7.2.2 批量获取配置

微服务可以尽量批量获取配置,减少与配置中心的交互次数。比如,在 Spring Cloud Config 中,可以通过设置 spring.cloud.config.fail - fast: true,并合理配置 spring.cloud.config.retry 参数,使微服务在启动时一次性获取所有配置,而不是多次重试单个配置的获取。