Spring Cloud Kubernetes 配置观察器

Kubernetes 提供了将 ConfigMap 或 Secret 作为卷挂载到应用程序容器中的能力。当 ConfigMap 或 Secret 的内容发生变化时,挂载的卷将随这些变化而更新

然而,Spring Boot 不会自动更新这些更改,除非您重新启动应用程序。Spring Cloud 提供了在不重新启动应用程序的情况下刷新应用程序上下文的能力,可以通过调用 actuator 端点 /refresh 或使用 Spring Cloud Bus 发布 RefreshRemoteApplicationEvent 来实现。

为了实现 Spring Cloud 应用程序在 Kubernetes 上运行时的配置刷新,您可以将 Spring Cloud Kubernetes Configuration Watcher 控制器部署到您的 Kubernetes 集群中。

您可以从 GitHub 上的源代码 构建 Docker 镜像,并使用它部署到 Kubernetes。

另一种配置它的选项是在用于部署配置监视器的 deployment.yaml 中提供一些环境变量。以下是一些重要的变量:

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

这些变量启用了配置监视器的调试日志记录,在初始设置时特别有用,可以诊断潜在的配置错误。

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

这个变量让监视器知道在哪里搜索 Secret 和 ConfigMap。您有两个选项:选择性命名空间(上面的设置)和由 命名空间解析 选择的命名空间(这是默认选项)。请记住,所有这些选项都需要适当的 RBAC 规则。

只有当更改来自带有标签 spring.cloud.kubernetes.config=truespring.cloud.kubernetes.secret=true 的源时,ConfigMap/Secret 的更改才会触发配置监视器发出事件。

简单来说,如果您更改了一个 ConfigMap(或 Secret),但它没有上述标签,配置监视器将跳过为此触发事件(如果您启用了调试日志记录,这将在日志中可见)。

默认情况下,配置监视器将监视配置命名空间中的所有 ConfigMap/Secret。如果您只想监视特定的源,可以通过设置以下选项来实现:

SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE

这将告诉监视器只监视带有标签 spring.cloud.kubernetes.config.informer.enabled=true 的源。

另一个重要的配置,特别是对于作为卷挂载的 ConfigMap 和 Secret(通过 spring.config.import)是

- name: SPRING_CLOUD_KUBERNETES_CONFIGURATION_WATCHER_REFRESHDELAY
  value: "10000"

这表示我们应该等待多少毫秒才能从配置监视器触发事件。这很重要,因为 Kubernetes 文档指出

当卷中当前使用的 ConfigMap 更新时,投影的键也会最终更新。

您需要将这个“最终”部分与集群上的毫秒值“匹配”。

Spring Cloud Kubernetes 配置监视器可以通过两种方式向应用程序发送刷新通知。

  1. 通过 HTTP,在这种情况下,被通知的应用程序必须暴露 /refresh 执行器端点,并且该端点必须可以在集群内部访问。

  2. 使用 Spring Cloud Bus,在这种情况下,您需要部署一个消息代理到您的集群供应用程序使用。

部署 YAML

以下是一个示例部署 YAML,您可以用来将 Kubernetes 配置监视器部署到 Kubernetes。

---
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:5.0.0
            imagePullPolicy: IfNotPresent
            readinessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/readiness
            livenessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/liveness
            ports:
            - containerPort: 8888

服务账户和相关的角色绑定对于 Spring Cloud Kubernetes Configuration 正常工作至关重要。控制器需要访问权限以读取 Kubernetes 集群中 ConfigMap、Pod、Service、Endpoint 和 Secret 的数据。

监控 ConfigMap 和 Secret

如果对带有有效标签(如上所述)的 ConfigMap 或 Secret 进行了更改,Spring Cloud Kubernetes Configuration Watcher 将获取 ConfigMap 或 Secret 的名称,并向具有该名称的应用程序发送通知。但这可能不足以满足您的用例,例如,您可能希望:

  • 将一个 ConfigMap 绑定到多个应用程序,以便单个 ConfigMap 中的更改会触发多个服务的刷新。

  • 让基于配置文件的源为您的应用程序触发事件。

因此,您可以指定一个附加注解:

spring.cloud.kubernetes.configmap.appsspring.cloud.kubernetes.secret.apps。它接受一个逗号分隔的应用程序名称字符串,指定当此 Secret/ConfigMap 发生更改时将收到通知的应用程序名称。

例如:

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 Discovery Client 获取与 ConfigMap 或 Secret 名称匹配的所有应用程序实例,并向应用程序的 actuator /refresh 端点发送 HTTP POST 请求。默认情况下,它将使用在发现客户端中注册的端口向 /actuator/refresh 发送 POST 请求。

您还可以配置配置监视器调用实例的 shutdown 执行器端点。为此,您可以设置 spring.cloud.kubernetes.configuration.watcher.refresh-strategy=shutdown

非默认管理端口和执行器路径

如果应用程序使用非默认的执行器路径和/或为管理端点使用不同的端口,则应用程序的 Kubernetes 服务可以添加一个名为 boot.spring.io/actuator 的注解,并将其值设置为应用程序使用的路径和端口。例如:

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.actuatorPort

消息实现

当 Spring Cloud Kubernetes Configuration Watcher 应用程序部署到 Kubernetes 时,可以通过将配置文件设置为 bus-amqp (RabbitMQ) 或 bus-kafka (Kafka) 来启用消息实现。默认情况下,当使用消息实现时,配置监视器将使用 Spring Cloud Bus 向所有应用程序实例发送 RefreshRemoteApplicationEvent。这将导致应用程序实例刷新应用程序的配置属性而无需重新启动实例。

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

配置 RabbitMQ

当启用 bus-amqp 配置文件时,您需要配置 Spring RabbitMQ 以指向您希望使用的 RabbitMQ 实例的位置以及进行身份验证所需的任何凭据。这可以通过设置标准的 Spring RabbitMQ 属性来完成,例如:

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

配置 Kafka

当启用 bus-kafka 配置文件时,您需要配置 Spring Kafka 以指向您希望使用的 Kafka Broker 实例的位置。这可以通过设置标准的 Spring Kafka 属性来完成,例如:

spring:
  kafka:
    producer:
      bootstrap-servers: localhost:9092
© . This site is unofficial and not affiliated with VMware.