skip to content

How does Spring Cloud Kubernetes reload configuration when a ConfigMap changes, and what are the watch vs polling modes?

level: seniorimportance: must knowfreq 55%

answer

  1. reload.enabled=false by default -> opt in
  2. mode: event(watch) vs polling(period=15s)
  3. strategy: refresh | restart_context | shutdown
  4. refresh -> RefreshEvent -> ContextRefresher rebind + @RefreshScope recreate
  5. watch needs list/watch RBAC; polling needs only get/list

basics

~20 s

Enable 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 s

Reload 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 lines
yaml
spring:
  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: false

go deeper

for a junior

Know reload is opt-in and that changing a ConfigMap can update a running app if enabled.

for a middle

Explain event vs polling modes and the default period, plus that a RefreshEvent is fired.

for a senior

Detail the three strategies, what refresh actually rebinds, and the RBAC difference between modes.

for a principal

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

context