Spring Cloud Kubernetes Configuration Watcher
Kubernetes 提供了在您应用程序的容器中 mount a ConfigMap or Secret as a volume 的能力。当 ConfigMap 或 Secret 的内容更改时, mounted volume will be updated with those changes。
然而,在您重启应用程序之前,Spring Boot 不会自动更新这些更改。Spring Cloud 提供通过点击 actuator 端点 /refresh
或通过使用 Spring Cloud Bus 发布`RefreshRemoteApplicationEvent` 来刷新应用程序上下文而不重启应用程序的能力。
若要在 Kubernetes 上运行的 Spring Cloud 应用程序中实现此配置刷新,您可以向 Kubernetes 集群中部署 Spring Cloud Kubernetes Configuration Watcher 控制器。
该应用程序发布为一个容器,并且在 Docker Hub 中可用。但是,如果您需要自定义配置监视程序行为或希望自己构建该映像,那么您可以轻松地从 source code on GitHub 构建自己的映像并使用该映像。
配置它的另一个选择是在用于部署配置 watcher 的 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
这些变量将启用配置 watcher 上的调试日志记录,并且在初始设置中特别有用,以便诊断潜在的错误配置。
env:
- name: SPRING_CLOUD_KUBERNETES_RELOAD_NAMESPACES_0
value: "namespace-a"
这一选项让监视程序知道到哪里查找秘密和 ConfigMap。您在此处有两个选项:选择性命名空间(上面的设置)和由 Namespace Resolution 选择的命名空间(这是默认选项)。请记住,所有这些选项都需要适当的 RBAC 规则。
configmap/secret 中的更改将仅在特定更改来自标签为:spring.cloud.kubernetes.config=true
或 spring.cloud.kubernetes.secret=true
的源的情况下触发配置 watcher 发出事件。
简而言之,如果您更改了一个 configmap(或 secret),它 不 具有上述标签,配置 watcher 将跳过为其触发事件(如果您启用了调试日志记录,这将在日志中显示)。
默认情况下,配置 watcher 将监视配置命名空间中所有 configmap/secret。如果您希望仅过滤以监视特定源,您可以通过设置以下来实现:
SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE
这将告诉 watcher 仅监视具有标签:spring.cloud.kubernetes.config.informer.enabled=true
的源。
另一项重要的配置,特别是对于作为存储卷挂载(通过 spring.cloud.kubernetes.config.paths
/spring.cloud.kubernetes.secrets.paths
或使用 spring.config.import
)的 configmap 和 secret,是:
- name: SPRING_CLOUD_KUBERNETES_CONFIGURATION_WATCHER_REFRESHDELAY
value: "10000"
这表示在从配置 watcher 发出事件之前我们应该等待多少毫秒。这非常重要,因为 kubernetes 文档说: 当前在存储卷中使用的 ConfigMap 更新后,最终也会更新投影的键。 您需要将这个 eventually 部分“匹配”到集群中的该毫秒值。 Spring Cloud Kubernetes Configuration Watcher 可以通过两种方式向应用程序发送刷新通知。
-
通过 HTTP,在这种情况下,正在通知的应用程序必须具有在集群内部公开且可访问的
/refresh
actuator 端点 -
使用 Spring Cloud Bus,在这种情况下,需要为应用程序部署到主机中一个消息代理。
Deployment YAML
以下是样本部署 YAML,您可以使用它将 Kubernetes Configuration Watcher 部署到 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:{spring-cloud-version}
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 8888
path: /actuator/health/readiness
livenessProbe:
httpGet:
port: 8888
path: /actuator/health/liveness
ports:
- containerPort: 8888
服务帐户和关联的角色绑定对于 Spring Cloud Kubernetes 配置正常工作非常重要。控制器需要访问权限来读取 Kubernetes 集群中 ConfigMap、Pod、服务、端点和 Secret 的数据。
Monitoring ConfigMaps and Secrets
如果对带有有效标签的 ConfigMap 或 Secret 进行更改(如上文所述),那么 Spring Cloud Kubernetes Configuration Watcher 将获取 ConfigMap 或 Secret 的名称,并向具有该名称的应用程序发送通知。这可能不足以满足您的用例,例如,您可能希望:
-
将 ConfigMap 绑定到多个应用程序,以便单个 ConfigMap 中的更改触发多个服务的刷新
-
让基于配置文件的源触发应用程序的事件
由于这个原因,您还可以指定附加注释:
spring.cloud.kubernetes.configmap.apps
或 spring.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 Implementation
HTTP 实现是默认使用的实现。当使用此实现时,如果 Spring Cloud Kubernetes Configuration Watcher 发生更改到 ConfigMap 或 Secret,那么 HTTP 实现将使用 Spring Cloud Kubernetes Discovery Client 获取与 ConfigMap 或 Secret 名称匹配的所有应用程序实例,并向应用程序的执行器“/refresh
”端点发送 HTTP POST 请求。默认情况下,它将使用在发现客户端中注册的端口,向 /actuator/refresh
发送 post 请求。
Non-Default Management Port and Actuator Path
如果应用程序使用的是非默认执行器路径和/或为管理端点使用的是不同的端口,那么该应用程序的 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.actuatorPath
和 spring.cloud.kubernetes.configuration.watcher.actuatorPort
。
Messaging Implementation
当在 Kubernetes 中部署 Spring Cloud Kubernetes Configuration Watcher 应用程序时,可以通过将概要文件设置为 bus-amqp
(RabbitMQ)或 bus-kafka
(Kafka)来启用消息传递实施。