How does Spring Cloud Kubernetes reload configuration when a ConfigMap changes, and what are the watch vs polling modes?
answer
- reload.enabled=false by default -> opt in
- mode: event(watch) vs polling(period=15s)
- strategy: refresh | restart_context | shutdown
- refresh -> RefreshEvent -> ContextRefresher rebind + @RefreshScope recreate
- watch needs list/watch RBAC; polling needs only get/list
basics
~20 sEnable spring.cloud.kubernetes.reload.enabled=true. In event (watch) mode it watches ConfigMaps/Secrets via the Kubernetes API and reacts instantly; in polling mode it re-reads them on a fixed period. A detected change fires a refresh that rebinds beans.
solid answer
~40 sReload is off by default; you enable `spring.cloud.kubernetes.reload.enabled=true`. Two detection modes: `event` (a.k.a. watch) uses a Kubernetes watch/informer on the ConfigMap and Secret objects, so changes propagate near-instantly but need `list`/`watch` RBAC; `polling` re-reads the objects every `reload.period` (default 15s) and diffs them — no watch RBAC, but slower and chattier. When a change is detected, the configured `strategy` runs — default `refresh` publishes a `RefreshEvent` that triggers `ContextRefresher`, rebinding `@ConfigurationProperties` beans and recreating `@RefreshScope` beans. Alternatives are `restart_context` (restart the app context) and `shutdown` (stop the app and let Kubernetes restart the pod). Watch mode is preferred in production for immediacy; polling is a fallback when watch RBAC isn't granted.
code
yaml · 10 linesspring:
cloud:
kubernetes:
reload:
enabled: true # off by default
mode: event # 'event' (watch/informer) or 'polling'
strategy: refresh # refresh | restart_context | shutdown
period: 15000 # polling interval (ms), used only in polling mode
monitoring-config-maps: true
monitoring-secrets: falsego deeper
Know reload is opt-in and that changing a ConfigMap can update a running app if enabled.
Explain event vs polling modes and the default period, plus that a RefreshEvent is fired.
Detail the three strategies, what refresh actually rebinds, and the RBAC difference between modes.
Reason about production trade-offs: no staging gate on instant reload, downtime of restart/shutdown strategies, watch reconnection, and refresh-awareness pitfalls.
**Reload is opt-in.** By default the ConfigMap/Secret property sources are read once at startup and never again. Set `spring.cloud.kubernetes.reload.enabled=true` to make a running app track changes. This is the whole point of the leaf: get Config-Server-style dynamic refresh using only Kubernetes primitives. **Detection modes (`spring.cloud.kubernetes.reload.mode`):** - **`event` (watch, the default when reload is enabled):** opens a Kubernetes *watch* (Fabric8) / *informer* (official client) on the relevant ConfigMap and Secret objects. The API server streams change notifications, so a `kubectl edit configmap` is picked up within moments. Requires RBAC `get`, `list`, and `watch` on `configmaps` (and `secrets` if monitoring those). Watches can drop and are re-established; a re-list on reconnect catches missed changes. - **`polling`:** a scheduler re-reads the objects every `spring.cloud.kubernetes.reload.period` (default 15s) and compares against the last-seen state. It only needs `get`/`list` (no `watch`), works where watch is restricted, but adds latency and periodic API load. **Reaction strategies (`spring.cloud.kubernetes.reload.strategy`):** - **`refresh` (default):** publishes an internal `RefreshEvent`; Spring Cloud's `ContextRefresher.refresh()` rebuilds the `Environment`, re-binds all `@ConfigurationProperties` beans in place, and *disposes* every `@RefreshScope` bean so the next access lazily recreates it with new values. No restart, sub-second, keeps in-flight requests. This is the same machinery `POST /actuator/refresh` uses. - **`restart_context`:** closes and restarts the Spring `ApplicationContext` (not the JVM). Heavier; use when beans that aren't refresh-aware must re-read config (e.g. some infra beans built once at context init). - **`shutdown`:** stops the application; you rely on the Kubernetes Deployment to restart the pod, which re-reads everything fresh. Simplest mental model, but incurs a real restart / brief unavailability (mitigated by rolling strategy + multiple replicas). **What actually changes on `refresh`.** Only beans that are refresh-aware: `@ConfigurationProperties` beans (rebound) and `@RefreshScope` beans (recreated). A plain singleton that captured a `@Value` at construction does NOT update — this is the #1 gotcha. Put fields that must change behind `@RefreshScope` or a `@ConfigurationProperties` holder. **Monitoring toggles.** `spring.cloud.kubernetes.reload.monitoring-config-maps` and `...monitoring-secrets` control which kinds are watched (config maps monitored by default; secrets monitoring may be off by default depending on version — verify). You can also restrict to the app's own ConfigMap/Secret rather than all in the namespace. **Gotchas.** - Missing `watch` RBAC in `event` mode → reload silently does nothing (or errors); fall back to polling. - `restart_context`/`shutdown` cause brief downtime — pair with replicas + readiness probes. - A malformed ConfigMap can push bad config live instantly in `event` mode — no staging gate; consider validation. - Secrets injected as env vars never change in a live container regardless of reload strategy; only property-source values and volume mounts update. **When to use which.** Prefer `event`+`refresh` for fast, zero-downtime config changes when RBAC allows watch. Use `polling` when the cluster forbids watch. Use `restart_context`/`shutdown` when your beans can't refresh cleanly and correctness matters more than the restart cost.
- A ConfigMap value changed and reload is enabled, but my bean still shows the old value. Why?The bean isn't refresh-aware. `refresh` strategy only rebinds `@ConfigurationProperties` beans and recreates `@RefreshScope` beans. A plain singleton that captured a `@Value` at construction keeps the old value. Move the field behind `@RefreshScope` or a `@ConfigurationProperties` holder — or use `restart_context`.
- What RBAC does `event` (watch) mode require that `polling` does not?`event` mode needs the `watch` verb (plus `list`) on `configmaps`/`secrets` to open a Kubernetes watch/informer. `polling` only needs `get`/`list` because it re-reads on a timer instead of subscribing to change events.
saying these in an interview costs you the question
- Thinking `refresh` restarts the app or JVM
- Assuming every bean updates on refresh (ignoring @RefreshScope requirement)
- Believing reload is on by default
- Confusing polling and event RBAC needs