application.yml
spring:
application:
name: springbootmonitoring-app
cloud:
kubernetes:
discovery:
enabled: true
all-namespaces: false # Optional: Set to true if you need to discover services across all namespaces
discovery-server-url:
This app runs on a kubernetes cluster and I want it to monitor all the apps in the cluster.
When the app runs it fails with below error
2025-01-31 13:40:56.566 DEBUG [o.s.web.client.RestTemplate,,main] HTTP GET /apps
2025-01-31 13:40:56.661 DEBUG [o.s.web.client.RestTemplate,,main] Accept=[application/json, application/*+json]
2025-01-31 13:40:57.268 DEBUG [o.s.web.client.RestTemplate,,main] Response 401 UNAUTHORIZED
2025-01-31 13:40:57.448 ERROR [o.s.boot.SpringApplication,,main] Application run failed
2025-01-31T11:40:57.451618044Z org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: "{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}<EOL>"
This is because as you can see in the logs the Bearer token isn't there in the header.
But if I run the curl command inside the Spring boot admin pod it works fine.
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" /apps
This means the token is mounted fine and the Role and Role Bindings are in place. I am not sure why the kubernetes discovery isn't automatically using the token while making the discovery API call. Also is there a way to force kubernetes discovery to use the token
application.yml
spring:
application:
name: springbootmonitoring-app
cloud:
kubernetes:
discovery:
enabled: true
all-namespaces: false # Optional: Set to true if you need to discover services across all namespaces
discovery-server-url: https://kubernetes.default.svc.cluster.local
This app runs on a kubernetes cluster and I want it to monitor all the apps in the cluster.
When the app runs it fails with below error
2025-01-31 13:40:56.566 DEBUG [o.s.web.client.RestTemplate,,main] HTTP GET https://kubernetes.default.svc.cluster.local/apps
2025-01-31 13:40:56.661 DEBUG [o.s.web.client.RestTemplate,,main] Accept=[application/json, application/*+json]
2025-01-31 13:40:57.268 DEBUG [o.s.web.client.RestTemplate,,main] Response 401 UNAUTHORIZED
2025-01-31 13:40:57.448 ERROR [o.s.boot.SpringApplication,,main] Application run failed
2025-01-31T11:40:57.451618044Z org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: "{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}<EOL>"
This is because as you can see in the logs the Bearer token isn't there in the header.
But if I run the curl command inside the Spring boot admin pod it works fine.
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/apps
This means the token is mounted fine and the Role and Role Bindings are in place. I am not sure why the kubernetes discovery isn't automatically using the token while making the discovery API call. Also is there a way to force kubernetes discovery to use the token
I think you should configure the KubernetesDiscoveryProperties
to use the service account token, since this is the standard approach to authenticate with the Kubernetes API.
spring:
cloud:
kubernetes:
discovery:
enabled: true
all-namespaces: false
discovery-server-url: https://kubernetes.default.svc.cluster.local
authentication:
oauth-token: /var/run/secrets/kubernetes.io/serviceaccount/token
ca-cert-file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
The service account associated with your application must have the necessary permissions to access the Kubernetes API endpoints
I don't think you should specify discovery-server-url
with Kubernetes API server URL as it is intended to connect to a separated discovery server that acts as middle layer discovery client Spring Boot app and Kubernetes API server. You should build the discovery server from spring-cloud-kubernetes-discoveryserver image and deploy to Kubernetes. Afterwards, you can configure discovery-server-url
with the URL of the deployed discovery server. You can see the detailed documentation on setting up spring boot discovery server here.