javaspring-boot-actuatorspring-cloud-kubernetes

Spring Actuator - Service discovery - /health "description":"Discovery Client not initialized","status":"UNKNOWN"


Question related to service discovery with Spring Boot Actuator, combined with Spring Cloud Kubernetes please.

Currently, I have a web app that has both the actuator and spring boot kubernetes dependencies. I am also using the discovery client provided by kubernetes, things are working fine.

However, when I curl my health endpoint, I do see those strange statements:

discoveryComposite":{"description":"Discovery Client not initialized","status":"UNKNOWN","components":{"discoveryClient":{"description":"Discovery Client not initialized","status":"UNKNOWN"}}

"reactiveDiscoveryClients":{"description":"Discovery Client not initialized","status":"UNKNOWN","components":{"Kubernetes Reactive Discovery Client":{"description":"Discovery Client not initialized","status":"UNKNOWN"}

Simple Reactive Discovery Client":{"description":"Discovery Client not initialized","status":"UNKNOWN"}}}

"readinessState":{"status":"UP"},"refreshScope":{"status":"UP"}},"groups":["liveness","readiness"]}*

May I ask why is it "unknown"? I would have expected at least one of the three here to how up something, and definitely not "Discovery Client not initialized".

Did I forget to initialize something? To register something? To configure something?

Btw, this is really a question regarding discovery with kubernetes. Not related to Eureka, not related to Consul and such.

Many thanks


Solution

  • Having the same issue, I've noticed that the org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicator has its discoveryInitialized field set to false. This is because no one triggered an InstanceRegisteredEvent in the application context. Usually the event should be triggered from the start() method of so called "registration" - a bean responsible for registration of current application instance in service registry, e.g. EurekaAutoServiceRegistration in case of Eureka.

    The point is that Kubernetes is not a service registry per se and it doesn't require explicit registration (because every pod within it is "registered" by default due to the nature of orchestration). That is why Spring Cloud Kubernetes does nothing by default to register the application instance with Kubernetes.

    However there is org.springframework.cloud.kubernetes.registry.KubernetesAutoServiceRegistration class that can "emulate" the process of auto registration by simply emitting messages to the log. As of v1.1.0 this class is @Deprecated and has no usages in the framework elsewhere. The only profit I see of using it at the moment, is that it can trigger the missing InstanceRegisteredEvent for initializing the DiscoveryClientHealthIndicator. You can use it by adding the following bean declaration to any of your @Configuration classes:

    @Bean
    public KubernetesAutoServiceRegistration kubernetesAutoServiceRegistration(
             ApplicationContext context, 
             KubernetesServiceRegistry registry,
             KubernetesRegistration registration) {
      return new KubernetesAutoServiceRegistration(context, registry, registration);
    }
    

    But please do not rely on it heavily as it will likely be removed in forthcoming versions of the framework.

    As an alternative you can emit the InstanceRegisteredEvent by yourself somewhere from your code but make sure you do it when the application is actually ready to work with discovery client.