Spring boot Kubernetes Service Discovery - spring

I am running into issues with Kubernetes Service Discovery on Spring Boot applications.
I should be able to discover the services whether my spring boot application is running within or out of Kubernetes cluster. Our local development won't be on k8s cluster.
I am using Service Discovery via DNS. I tried using spring-cloud-starter-kubernetes
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<version>0.2.0.RELEASE</version>
</dependency>
As per documentation you should be able to autowire DiscoveryClient and good to go
#Autowire
private DiscoveryClient discoveryClient;
DiscoveryClient is part of spring-cloud-commons. spring-cloud-starter-kuberenetes doesn't have it.
Anyone solved similar problem using the same library or a different one? Please share the solution
Thanks!

I have solved this issue using the Spring Cloud Kubernetes Dependencies
<spring.cloud.kubernetes>0.2.0.RELEASE</spring.cloud.kubernetes>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-ribbon</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-config</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
<version>${spring.cloud.kubernetes}</version>
</dependency>
What was very important for me was the ribbon dependency as it makes use of a load balanced rest template in order to substitute service names for the correct pod IP's that are found in your kubernetes cluster.
I have created a git repo as part of answering a larger set of questions but it should be more than sufficient if someone is looking a way to implement Kubernetes service discovery in place of Eureka or Consul.
https://github.com/foundery-rmb/kubernetes-service-discovery

Related

Zipkin server is not showing Microservices trace

I have a Microservice A calling another Microservice B with the following pom.xml and application.properties values:
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
application.properties
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1.0
spring.zipkin.sender.type=web
spring.zipkin.collector.http.enabled=true
Zipkin server version: zipkin-server-2.12.9
Spring Boot Version: 2.7.5
Spring cloud version: 2021.0.4
Issue is that trace that Microservice A called Microservice B with the trace-ID is not getting displayed in Zipkin.
Any issue?
Trace of Microservices calling chain with trace-ID should be coming in Zipkin server
The problem was that RestTemplate used to call the another service was create as New.
Solution is that create it as a bean and inject it to your code.

Springboot disable selected prometheus metrics

I am using springboot gateway 2.0.4.RELEASE.
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
After adding this dependency, it is exposing all metrics to prometheus endpoint.
I want to disable some of the metrics from exposing through /actuator/prometheus endpoint.
Let's say I want to disable
gateway_requests_seconds_count
gateway_requests_seconds_sum
gateway_requests_seconds_max
Does anyone know how can I achieve this ?
Thanks
Alpesh

Spring Cloud Kubernetes FeignClient Error

I am using spring cloud kubernetes with spring boot and necessary RBAC requirements needed for the project.
<!-- kubernetes -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
I have 2 microservices running in kubernetes
my-service
some-service
The my-service is running with spring boot 2.x and some-service is running with Spring boot 1.x. Both the services are exposed via the Kubernetes Service and with proper endpoints.
excerpt of application.yaml for my-service is as below.
some-service:
url: http://some-service:8080
serviceName: some-service
And the FeignClient used is as below.
//FeignClient(url = "${some-service.url}") // does not work either
#FeignClient(value = "${some-service.serviceName}")
#RequestMapping("/api")
public interface SomeServiceClient {
Also I have made spring.cloud.kubernetes.discovery.enabled=false
With this in place I expect that my-service should be able to talk to some-service via kubernetes service discovery But I get this error.
ERROR c.b.d.m.s.c.MatchCoordinator - error=FeignException: status 404 reading SomeServiceClient#get(Test
ion,Output) stacktrace=feign.FeignException: status 404 reading SomeServiceClient#get
I am unable to understand what am I doing wrong. Also I do not have the spring.application.name set for some-service since its a third party service.
Can someone please help. Also FYI that the services work properly with port-forwarding and if accessed via Ingress.
If you do not have a name set for some-service, and it's a 3rd party service, I think the better approach would be to call it via RestTemplate or something.
Feign client needs to have the service name configured and known, for it to call that particular service in the network using service discovery.
Well, I found that the discrepancy was at the some-service where the payload of was updated and my-service FeignClient was not updated. and hence caused the HTTP 404 Error. However it works now with the FeignClient properly and able to do a service discovery with the service name properly.

Prometheus java/Spring API for fetching metrics

I need to query for collected metrics in my application and the only way I found to do it is via Prometheus rest api as described here: https://prometheus.io/docs/prometheus/latest/querying/api/ Does any Spring or java api for fetching metrics from Prometheus exist, so that I wouldn't have to implement it from scratch?
If you want to collect metrics from your spring application using Prometheus, this is what you have to do:
In your application's pom.xml add this dependency:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.7.0</version>
</dependency>
In application.properties you need to add:
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
And this should be all, now when you start your Spring application you can check the collected metrics at /actuator/prometheus, you'll have all the metrics grouped here.
Good luck!

How to use zuul in spring cloud without spring boot actuator?

I want to use zuul as a proxy server in my application, but I don't want to use spring boot actuator, I tried to remove it from the dependency as follow:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>${spring-cloud-netflix.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</exclusion>
</exclusions>
</dependency>
However, it will cause some ClassNotFoundException.
I don't need spring boot actuator in my application, but it has so many autoconfiguration in spring boot that will produce many endpoints that I don't want.
Is there any good way to solve this?
The issue has been addressed in spring cloud netflix 1135. It will be available shortly in Brixton.SR2.

Resources