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=true 或 spring.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 配置監視器可以透過兩種方式嚮應用程式傳送重新整理通知。
-
透過 HTTP,在這種情況下,被通知的應用程式必須暴露
/refresh執行器端點,並且該端點必須可以在叢集內部訪問。 -
使用 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.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 實現是預設使用的。當使用此實現時,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.actuatorPath 和 spring.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。