spring-cloud-kubernetes icon indicating copy to clipboard operation
spring-cloud-kubernetes copied to clipboard

Support Gateway proxy routing to Service of non current NS

Open damon008 opened this issue 4 years ago • 1 comments

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.

damon008 avatar Apr 09 '21 06:04 damon008

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]

damon008 avatar Apr 09 '21 06:04 damon008

@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 DiscoveryClient will 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

wind57 avatar Apr 09 '24 13:04 wind57

@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?

ryanjbaxter avatar Apr 09 '24 17:04 ryanjbaxter

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

wind57 avatar Apr 09 '24 17:04 wind57

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

ryanjbaxter avatar Apr 10 '24 14:04 ryanjbaxter

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.

wind57 avatar Apr 10 '24 14:04 wind57