Spring Cloud Kubernetes 配置觀察器
Kubernetes 提供了將 ConfigMap 或 Secret 掛載為應用程式容器中的卷的能力。當 ConfigMap 或 Secret 的內容發生變化時,掛載的卷將隨之更新。
然而,除非重啟應用程式,否則 Spring Boot 不會自動更新這些變化。Spring Cloud 提供了無需重啟應用即可重新整理應用上下文的能力,可以透過訪問 /refresh
actuator 端點或使用 Spring Cloud Bus 釋出 RefreshRemoteApplicationEvent
來實現。
為了在 Kubernetes 上執行的 Spring Cloud 應用中實現此配置重新整理,您可以將 Spring Cloud Kubernetes Configuration Watcher 控制器部署到您的 Kubernetes 叢集中。
該應用作為容器釋出,可在 Docker Hub 上獲取。但是,如果您需要自定義配置觀察器行為或更喜歡自己構建映象,您可以輕鬆地從 GitHub 上的原始碼構建自己的映象並使用。
配置它的另一種選擇是在用於部署配置觀察器的 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"
此變數讓觀察器知道在哪裡搜尋 secrets 和 configmaps。這裡有兩種選擇:選擇性名稱空間(上面的設定)和透過名稱空間解析(Namespace Resolution)選擇的名稱空間(這是預設選項)。請記住,所有這些選項都需要適當的 RBAC 規則。
configmaps/secrets 的更改只有在其來源於帶有以下標籤的源時,才會觸發配置觀察器發出事件:spring.cloud.kubernetes.config=true
或 spring.cloud.kubernetes.secret=true
。
簡單來說,如果您更改了一個沒有上述標籤的 configmap(或 secret),配置觀察器將跳過為此更改觸發事件(如果您啟用了除錯日誌記錄,這將在日誌中可見)。
預設情況下,配置觀察器將監控配置的名稱空間中的所有 configmaps/secrets。如果您想過濾只監控特定的源,可以透過設定以下變數實現:
SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE
這將告訴觀察器只監控帶有標籤:spring.cloud.kubernetes.config.informer.enabled=true
的源。
另一個重要的配置,特別是對於作為卷掛載的 configmaps 和 secrets(透過 spring.cloud.kubernetes.config.paths
/spring.cloud.kubernetes.secrets.paths
或使用 spring.config.import
),是
- name: SPRING_CLOUD_KUBERNETES_CONFIGURATION_WATCHER_REFRESHDELAY
value: "10000"
這指定了在配置觀察器觸發事件之前應該等待多少毫秒。這很重要,因為 Kubernetes 文件提到
當卷中當前使用的 ConfigMap 更新時,投影的鍵也會最終更新。
您需要將這個“最終”的部分與叢集中該值的毫秒數“匹配”。
Spring Cloud Kubernetes Configuration Watcher 可以透過兩種方式嚮應用傳送重新整理通知。
-
透過 HTTP,在這種情況下,被通知的應用必須暴露
/refresh
actuator 端點,並且可以從叢集內部訪問。 -
使用 Spring Cloud Bus,在這種情況下,您需要在叢集中部署一個訊息代理供應用使用。
部署 YAML
下面是一個您可以用來將 Kubernetes Configuration Watcher 部署到 Kubernetes 的示例部署 YAML。
---
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.1
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 Configuration 的正常工作很重要。控制器需要訪問許可權來讀取 Kubernetes 叢集中的 ConfigMaps、Pods、Services、Endpoints 和 Secrets 的資料。
監控 ConfigMaps 和 Secrets
如果對帶有有效標籤(如上所述)的 ConfigMap 或 Secret 進行了更改,則 Spring Cloud Kubernetes Configuration Watcher 將獲取該 ConfigMap 或 Secret 的名稱,並向同名應用傳送通知。但這可能不足以滿足您的用例,例如,您可能希望
-
將一個 config-map 繫結到多個應用,以便單個 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 實現
HTTP 實現是預設使用的實現。當使用此實現時,如果 ConfigMap 或 Secret 發生變化,Spring Cloud Kubernetes Configuration Watcher 的 HTTP 實現將使用 Spring Cloud Kubernetes Discovery Client 獲取與 ConfigMap 或 Secret 名稱匹配的所有應用例項,並嚮應用的 /refresh
actuator 端點發送一個 HTTP POST 請求。預設情況下,它將使用在 Discovery Client 中註冊的埠向 /actuator/refresh
傳送 POST 請求。
您還可以配置配置觀察器呼叫例項的 shutdown
actuator 端點。為此,您可以設定 spring.cloud.kubernetes.configuration.watcher.refresh-strategy=shutdown
。
非預設管理埠和 Actuator 路徑
如果應用使用非預設的 actuator 路徑和/或使用不同的埠作為管理端點,應用的 Kubernetes service 可以新增一個名為 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
另一種配置 actuator 路徑和/或管理埠的方式是設定 spring.cloud.kubernetes.configuration.watcher.actuatorPath
和 spring.cloud.kubernetes.configuration.watcher.actuatorPort
。
訊息實現
將 Spring Cloud Kubernetes Configuration Watcher 應用部署到 Kubernetes 時,可以透過將 profile 設定為 bus-amqp
(RabbitMQ) 或 bus-kafka
(Kafka) 來啟用訊息實現。預設情況下,使用訊息實現時,配置觀察器將使用 Spring Cloud Bus 向所有應用例項傳送 RefreshRemoteApplicationEvent
。這將導致應用例項在不重啟的情況下重新整理應用的配置屬性。
您還可以配置以便關閉應用例項來重新整理應用的配置屬性。當應用關閉時,Kubernetes 將重啟應用例項並載入新的配置屬性。要使用此策略,請設定 spring.cloud.kubernetes.configuration.watcher.refresh-strategy=shutdown
。