请使用 Spring Cloud Kubernetes 5.0.1(最新稳定版本)!spring-doc.cadn.net.cn

Spring Cloud Kubernetes 配置监听器

Kubernetes 提供了将 ConfigMap 或 Secret 作为卷挂载到应用程序容器中的能力。当 ConfigMap 或 Secret 的内容发生更改时,已挂载的卷将随之更新这些更改spring-doc.cadn.net.cn

然而,除非重新启动应用程序,否则 Spring Boot 不会自动更新这些更改。Spring Cloud 提供了在不重启应用程序的情况下刷新应用上下文的能力,方法是通过调用指标端点 /refresh 或通过使用 Spring Cloud Bus 发布 RefreshRemoteApplicationEventspring-doc.cadn.net.cn

要实现此配置刷新,适用于在 Kubernetes 上运行的 Spring Cloud 应用,可将 Spring Cloud Kubernetes 配置监听器控制器部署到您的 Kubernetes 集群中。spring-doc.cadn.net.cn

您可以从 GitHub 上的源代码 构建 Docker 镜像,并使用该镜像部署到 Kubernetes。spring-doc.cadn.net.cn

另一种配置方式是在用于部署配置观察器的 deployment.yaml 中提供一些环境变量。以下是一些重要的环境变量:spring-doc.cadn.net.cn

env:
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER
    value: DEBUG
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CLIENT_CONFIG_RELOAD
    value: DEBUG
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD
    value: DEBUG

这些功能可在配置观察器上启用调试日志记录,特别适用于初始设置阶段,以便诊断潜在的配置错误。spring-doc.cadn.net.cn

env:
  - name: SPRING_CLOUD_KUBERNETES_RELOAD_NAMESPACES_0
    value: "namespace-a"

此设置可让观察者知道在何处搜索秘密和配置映射。您在此处有两个选项:选择性命名空间(上方的设置)以及由 命名空间解析 所选定的命名空间(这是默认选项)。
请记住,所有这些选项均需要适当的 RBAC 规则。spring-doc.cadn.net.cn

来自 ConfigMap/Secret 的更改仅当该更改源自具有标签 spring.cloud.kubernetes.config=truespring.cloud.kubernetes.secret=true 的源时,才会触发配置监视器发出事件。spring-doc.cadn.net.cn

更简单地说,如果更改一个 ConfigMap(或 Secret),而该 ConfigMap(或 Secret)没有上述标签,则配置监听器将跳过为其触发事件(如果您启用了调试日志,此信息将在日志中可见)。spring-doc.cadn.net.cn

默认情况下,配置观察器将监视所配置命名空间中的所有 ConfigMap/Secret。如果您希望筛选仅观察特定来源,请通过设置以下内容实现:spring-doc.cadn.net.cn

SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE

这将告诉观察者仅监控具有标签:spring.cloud.kubernetes.config.informer.enabled=true 的源。spring-doc.cadn.net.cn

另一个重要的配置,尤其是对于以卷的形式挂载的配置映射(configmaps)和密钥(secrets)(通过 spring.cloud.kubernetes.config.paths/spring.cloud.kubernetes.secrets.paths 或使用 spring.config.import):spring-doc.cadn.net.cn

- name: SPRING_CLOUD_KUBERNETES_CONFIGURATION_WATCHER_REFRESHDELAY
  value: "10000"

这说明了在配置监视器触发事件前应等待多少毫秒。这一点非常重要,因为 Kubernetes 文档中指出:spring-doc.cadn.net.cn

当一个当前在卷中被使用的 ConfigMap 被更新时,投射的键最终也会被更新。spring-doc.cadn.net.cn

您需要将此 最终 部分与集群中该值的毫秒数进行匹配。spring-doc.cadn.net.cn

Spring Cloud Kubernetes 配置观察器可以通过两种方式向应用程序发送刷新通知。spring-doc.cadn.net.cn

  1. 通过 HTTP,在这种情况下,被通知的应用程序必须暴露并可从集群内部访问 /refresh 指标端点。spring-doc.cadn.net.cn

  2. 使用 Spring Cloud Bus,此时您需要在集群中部署一个消息代理,以便应用程序能够使用它。spring-doc.cadn.net.cn

部署 YAML

以下是一个示例部署 YAML,您可以将其用于将 Kubernetes 配置观察器部署到 Kubernetes。spring-doc.cadn.net.cn

---
apiVersion: v1
kind: List
items:
  - apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher
    spec:
      ports:
        - name: http
          port: 8888
          targetPort: 8888
      selector:
        app: spring-cloud-kubernetes-configuration-watcher
      type: ClusterIP
  - apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher:view
    roleRef:
      kind: Role
      apiGroup: rbac.authorization.k8s.io
      name: namespace-reader
    subjects:
      - kind: ServiceAccount
        name: spring-cloud-kubernetes-configuration-watcher
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: namespace-reader
    rules:
      - apiGroups: ["", "extensions", "apps"]
        resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
        verbs: ["get", "list", "watch"]
  - apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: spring-cloud-kubernetes-configuration-watcher-deployment
    spec:
      selector:
        matchLabels:
          app: spring-cloud-kubernetes-configuration-watcher
      template:
        metadata:
          labels:
            app: spring-cloud-kubernetes-configuration-watcher
        spec:
          serviceAccount: spring-cloud-kubernetes-configuration-watcher
          containers:
          - name: spring-cloud-kubernetes-configuration-watcher
            image: springcloud/spring-cloud-kubernetes-configuration-watcher:3.2.3
            imagePullPolicy: IfNotPresent
            readinessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/readiness
            livenessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/liveness
            ports:
            - containerPort: 8888

服务账号(Service Account)及其关联的角色绑定(Role Binding)对于 Spring Cloud Kubernetes 配置正常工作至关重要。控制器需要访问权限,以读取 Kubernetes 集群中关于 ConfigMaps、Pods、Services、Endpoints 和 Secrets 的数据。spring-doc.cadn.net.cn

监控 ConfigMaps 和 Secret

如果对具有有效标签(如上所述)的 ConfigMap 或 Secret 进行了更改,则 Spring Cloud Kubernetes Configuration Watcher 将获取该 ConfigMap 或 Secret 的名称,并向应用程序发送一条包含该名称的通知。不过,这可能不足以满足您的使用场景,例如您可能希望:spring-doc.cadn.net.cn

  • 将配置映射(ConfigMap)绑定到多个应用程序,以便对单个 ConfigMap 中的任何更改都会触发多个服务的刷新。spring-doc.cadn.net.cn

  • 根据个人资料来源触发事件,以供您的应用程序使用spring-doc.cadn.net.cn

出于这个原因,您可以指定一个额外的注解:spring-doc.cadn.net.cn

spring.cloud.kubernetes.configmap.appsspring.cloud.kubernetes.secret.apps。它接受一个以逗号分隔的应用程序名称字符串,指定在该密钥/配置映射发生更改时将接收通知的应用程序。spring-doc.cadn.net.cn

kind: ConfigMap
apiVersion: v1
metadata:
  name: example-configmap
  labels:
    spring.cloud.kubernetes.config: "true"
  annotations:
    spring.cloud.kubernetes.configmap.apps: "app-a, app-b"

HTTP 实现

HTTP 实现是默认使用的。当使用此实现时,若 Spring Cloud Kubernetes 配置监听器检测到 ConfigMap 或 Secret 发生变更,则 HTTP 实现将使用 Spring Cloud Kubernetes 发现客户端来获取所有与 ConfigMap 或 Secret 名称匹配的应用实例,并向应用的 Actuator /refresh 端点发送 HTTP POST 请求。默认情况下,它会通过发现客户端中注册的端口,向 /actuator/refresh 发送 POST 请求。spring-doc.cadn.net.cn

你还可以配置配置监视器,以调用实例的 shutdown 操作端点。为此,你可以设置 spring.cloud.kubernetes.configuration.watcher.refresh-strategy=shutdownspring-doc.cadn.net.cn

非默认管理端口和指标路径

如果应用程序使用非默认的指标端点路径和/或为管理端点使用不同的端口,该应用程序的 Kubernetes 服务可以添加一个名为 boot.spring.io/actuator 的注解,并将其值设置为应用程序所使用的路径和端口。例如spring-doc.cadn.net.cn

apiVersion: v1
kind: Service
metadata:
  labels:
    app: config-map-demo
  name: config-map-demo
  annotations:
    boot.spring.io/actuator: http://:9090/myactuator/home
spec:
  ports:
    - name: http
      port: 8080
      targetPort: 8080
  selector:
    app: config-map-demo

另一种您可以选择配置端点路径和/或管理端口的方式是设置spring.cloud.kubernetes.configuration.watcher.actuatorPathspring.cloud.kubernetes.configuration.watcher.actuatorPortspring-doc.cadn.net.cn

消息实现

消息传递实现可以通过在将 Spring Cloud Kubernetes 配置监听器应用部署到 Kubernetes 时,将配置文件设置为 bus-amqp(RabbitMQ)或 bus-kafka(Kafka)来启用。默认情况下,当使用消息传递实现时,配置监听器会通过 Spring Cloud Bus 向所有应用实例发送一个 RefreshRemoteApplicationEvent,这将导致应用实例无需重启即可刷新应用程序的配置属性。spring-doc.cadn.net.cn

您还可以配置该配置,以便在刷新应用程序的配置属性时关闭应用程序实例。当应用程序关闭时,Kubernetes 将重启应用程序实例,并加载新的配置属性。要使用此策略,请设置 spring.cloud.kubernetes.configuration.watcher.refresh-strategy=shutdownspring-doc.cadn.net.cn

配置 RabbitMQ

当启用 bus-amqp 配置文件时,您需要配置 Spring RabbitMQ,使其指向您希望使用的 RabbitMQ 实例的位置,并提供任何必要的身份验证凭据。您可以通过设置标准的 Spring RabbitMQ 属性来完成此操作,例如spring-doc.cadn.net.cn

spring:
  rabbitmq:
    username: user
    password: password
    host: rabbitmq

配置 Kafka

当启用 bus-kafka 配置文件时,您需要配置 Spring Kafka,使其指向您希望使用的 Kafka 代理实例的位置。这可以通过设置标准的 Spring Kafka 属性来完成,例如spring-doc.cadn.net.cn

spring:
  kafka:
    producer:
      bootstrap-servers: localhost:9092