How do you enable Spring Cloud Kubernetes discovery, and what is the difference between the Fabric8 and official-client starters?
answer
- Two starters: -fabric8 vs -client
- Fabric8 = io.fabric8 client; -client = official client-java
- One starter only, auto-config registers DiscoveryClient
- spring.cloud.kubernetes.discovery.enabled
- Discovery Server = centralize RBAC over HTTP
basics
~10 sAdd one starter — spring-cloud-starter-kubernetes-fabric8 or spring-cloud-starter-kubernetes-client — which auto-configures a DiscoveryClient. Both talk to the same Kubernetes API; they just use different underlying Java clients (Fabric8's io.fabric8 client vs the official kubernetes-client/java).
solid answer
~40 sYou pick one of two starter families. spring-cloud-starter-kubernetes-fabric8 uses the io.fabric8 Kubernetes client; spring-cloud-starter-kubernetes-client uses the official kubernetes-client/java. Adding the starter auto-configures a KubernetesDiscoveryClient (in newer releases an informer-based one) so DiscoveryClient and @LoadBalanced clients just work. @EnableDiscoveryClient is largely optional because auto-config activates it, but you can gate it with spring.cloud.kubernetes.discovery.enabled=true/false. Functionally the two clients are equivalent for discovery; the choice is about dependency footprint, existing usage, and which client your team standardizes on. The official-client family also pairs with a separate Discovery Server (HTTP) deployment so app pods don't each need cluster-wide RBAC. Both read Service/Endpoints from the API and require the pod's ServiceAccount to have list/watch/get on those resources.
code
java · 26 lines// pom.xml — pick ONE:
// <dependency>
// <groupId>org.springframework.cloud</groupId>
// <artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
// </dependency>
// -- or --
// <dependency>
// <groupId>org.springframework.cloud</groupId>
// <artifactId>spring-cloud-starter-kubernetes-client</artifactId>
// </dependency>
@SpringBootApplication
@EnableDiscoveryClient // explicit intent; auto-config often enables it anyway
public class GatewayApp {
public static void main(String[] args) { SpringApplication.run(GatewayApp.class, args); }
}
// application.yml
// spring:
// cloud:
// kubernetes:
// discovery:
// enabled: true
// all-namespaces: false
// service-labels:
// tier: backendgo deeper
Know that you add one starter and the DiscoveryClient appears; details of client choice can be fuzzy.
Should name both starter families, know they share the SPI, and toggle via spring.cloud.kubernetes.discovery.enabled.
Should discuss namespace scoping, label filters, and the Discovery Server RBAC-centralization tradeoff.
Should reason about API-server watch load, permission blast radius, and standardizing one client stack org-wide.
**The two client stacks.** Spring Cloud Kubernetes must talk to the kube-apiserver over its REST API. There are two mature Java clients for that, and Spring Cloud offers a starter for each: 1. **Fabric8** — `org.springframework.cloud:spring-cloud-starter-kubernetes-fabric8` (and `...-fabric8-all` bundling config + discovery + LoadBalancer). Uses the popular `io.fabric8:kubernetes-client`. Historically the original and most battle-tested option in this project. 2. **Official Kubernetes Java client** — `org.springframework.cloud:spring-cloud-starter-kubernetes-client` (and `...-client-all`). Uses `io.kubernetes:client-java`, the CNCF-official generated client. Both ultimately implement the same Spring Cloud Commons `DiscoveryClient` SPI, expose the same `getServices()`/`getInstances()` behavior, and integrate identically with **Spring Cloud LoadBalancer**. You should include **exactly one** to avoid conflicting auto-configuration. **Enabling.** Adding a starter triggers auto-configuration that registers the discovery client bean. `@EnableDiscoveryClient` on your `@SpringBootApplication` is the explicit, portable way to signal intent, but with Spring Cloud Kubernetes on the classpath discovery is typically active by default. You control it via properties: - `spring.cloud.kubernetes.discovery.enabled=true|false` - `spring.cloud.kubernetes.discovery.all-namespaces=true` — discover across all namespaces (default is the pod's own namespace). - `spring.cloud.kubernetes.discovery.service-labels.*` — filter which Services are visible. - `spring.cloud.kubernetes.discovery.include-not-ready-addresses=true` — also surface not-ready pods (rare; usually undesirable). - `spring.cloud.kubernetes.discovery.primary-port-name` — which named port to use when a Service exposes several. **Discovery Server (HTTP mode).** A concern with putting a discovery client in every app is that each pod's ServiceAccount then needs RBAC to list/watch Services and Endpoints cluster-wide. Spring Cloud Kubernetes offers a standalone **Spring Cloud Kubernetes Discovery Server** — one deployment that holds the RBAC and exposes discovery over HTTP; app pods use a lightweight `DiscoveryClient` that calls that server instead of the kube-apiserver directly. Property: `spring.cloud.kubernetes.discovery.discovery-server-url`. This centralizes permissions and reduces API-server watch load. **Which to choose?** - If your team already uses the Fabric8 client elsewhere, or you want the `-all` convenience bundle, pick Fabric8. - If you standardize on the CNCF official client or want the Discovery Server topology, the `-client` family is the natural fit. - For pure discovery behavior, they are interchangeable; the decision is ecosystem/dependency alignment, not capability. **Gotcha:** don't mix both starters; and remember that neither works without the RBAC grant on the pod's ServiceAccount.
- What happens if you accidentally include both the fabric8 and client starters?You get two competing DiscoveryClient auto-configurations and bean/classpath conflicts; discovery may fail to start or behave unpredictably. Include exactly one client stack per app.
- Why might a platform team prefer the Discovery Server over embedding a client in every app?It concentrates the cluster-wide RBAC (list/watch services and endpoints) into one deployment instead of granting it to every app's ServiceAccount, and reduces the number of watch connections to the kube-apiserver, which matters at scale.
saying these in an interview costs you the question
- Thinking Fabric8 and official client produce different discovery semantics
- Including both starters at once
- Believing @EnableDiscoveryClient is strictly mandatory
- Forgetting RBAC is still required regardless of client choice