Support Gateway proxy routing to Service of non current NS
Is your feature request related to a problem? Please describe. I test one: In same Namespace of Gateway and Services,the Gateway can routing to these Services,but those Services can not be found in other Namespace.
Describe the solution you'd like I hope the gateway can found endpoints of service in any one of namespaces.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
Additional context Add any other context or screenshots about the feature request here.
Env:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.8.RELEASE</version>
<relativePath/>
</parent>
<springcloud.version>Hoxton.SR9</springcloud.version>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
For example: the pod of Gateway in the A namespace,the pod of admin-web in the B namespace.
the yaml of Gateway about route like this:
spring:
cloud:
kubernetes:
discovery:
all-namespaces: true
gateway:
discovery:
locator:
enabled: true
lowerCaseServiceId: true
routes:
- id: admin-web
uri: lb://admin-web-service
order: -1
predicates:
- Path=/admin-web/**
filters:
- StripPrefix=1
curl http://ip:port/admin-web/XXX
I found can not routing to admin-web, show logs:
2021-04-09 06:39:56.337 WARN 1 --- [erListUpdater-0] o.s.c.k.r.KubernetesEndpointsServerList : Did not find any endpoints in ribbon in namespace [A] for name [admin-web-service] and portName [null]
@ryanjbaxter I have a question here please. Since we do not have ribbon anymore, then this issue can be closed?
Two side notes:
- I've created a demo project with gateway and kubernetes-discovery + load-balancer here
- I have searched for some time, but could not find any documentations about such an integration. The gateway project does not provide one with spring-cloud-kubernetes. It mentions that
DiscoveryClientwill auto-create routes, if it is present, but that does not work by default; we also need to include load-balancer. I would gladly update the documentation, if you tell me where. In our project or the gateway pages?
Thank you
@damon008 please try using Spring Cloud 2023.0.1 and let us know if this is still an issue
@wind57 Can you describe what you mean by it doesn't work when you add the k8s discovery client implementation to the class path? Do you have code I can look at as an example?
gladly. here is the sample project: https://github.com/wind57/gateway-demo
There are instruction how to deploy and test there. Simply comment out spring-cloud-kubernetes-client-loadbalancer and build again, and the the last two curl commands from the README will fail.
I hope it makes sense
I think we could probably use some additional documentation in Spring Cloud Gateway here.
Actually you don't need to include spring-cloud-kubernetes-client-loadbalancer, you just need to include spring-cloud-starter-loadbalancer. The reason it is required because by default the URL expression Spring Cloud Gateway uses to create the routes uses the protocol lb://
https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/discovery/DiscoveryLocatorProperties.java#L48
Any uri that uses the lb:// protocol will try to be loadbalanced. It is not unique to using the Spring Cloud K8S DiscoveryClient it would be the same for any DiscoveryClient implementation.
For reference here are the routes that get created by default:
- id: ReactiveCompositeDiscoveryClient_wiremock-default-service
predicates:
- name: Path
args:
pattern: /wiremock-default-service/**
filters:
- name: RewritePath
args:
regexp: /wiremock-default-service/?(?<remaining>.*)
replacement: '/${remaining}'
uri: 'lb://wiremock-default-service'
metadata:
app: gateway-demo-only
port.http: '8080'
k8s_namespace: default
type: ClusterIP
kubectl.kubernetes.io/last-applied-configuration: >
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"gateway-demo-only"},"name":"wiremock-default-service","namespace":"default"},"spec":{"ports":[{"name":"http","port":8080,"targetPort":8080}],"selector":{"app":"wiremock"},"type":"ClusterIP"}}
order: 0
- id: ReactiveCompositeDiscoveryClient_wiremock-service
predicates:
- name: Path
args:
pattern: /wiremock-service/**
filters:
- name: RewritePath
args:
regexp: /wiremock-service/?(?<remaining>.*)
replacement: '/${remaining}'
uri: 'lb://wiremock-service'
metadata:
app: gateway-demo-only
port.http: '8080'
k8s_namespace: wiremock-namespace
type: ClusterIP
kubectl.kubernetes.io/last-applied-configuration: >
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"gateway-demo-only"},"name":"wiremock-service","namespace":"wiremock-namespace"},"spec":{"ports":[{"name":"http","port":8080,"targetPort":8080}],"selector":{"app":"wiremock"},"type":"ClusterIP"}}
order: 0
right, I came to exactly the same conclusion, that is the reason I exposed the gateway endpoint, to see what routes are created. I ended up debugging the code in gateway and seeing exactly what you describe here.
Now that I think about, you are indeed correct about the spring-cloud-starter-loadbalancer. I have become a hammer, every problem I see is a "nail". Since I've contributed so much to k8s project, I see that as a "solution" to everything.
Thank you for the input here and I'll create a PR to update the documentation there.