【问题标题】:Spring Cloud Kubernetes + Spring Cloud Gateway: Unable to find instance for k8s serviceSpring Cloud Kubernetes + Spring Cloud Gateway:无法找到 k8s 服务的实例
【发布时间】:2019-12-26 21:16:11
【问题描述】:

我正在使用 Spring Cloud Kubernetes + Spring Cloud Gateway(SCG),但在 GKE 上部署我的应用程序时遇到了一些麻烦。 SCG没有找到k8s服务,我还是报这个错:

There was an unexpected error (type=Service Unavailable, status=503).
Unable to find instance for uiservice

uiservice 是 Angular 应用程序。

当我查看.../actuator/gateway/routes 时,我得到了这个结果:

[
  {
    "route_id": "CompositeDiscoveryClient_gateway",
    "route_definition": {
      "id": "CompositeDiscoveryClient_gateway",
      "predicates": [
        {
          "name": "Path",
          "args": {
            "pattern": "/gateway/**"
          }
        }
      ],
      "filters": [
        {
          "name": "RewritePath",
          "args": {
            "regexp": "/gateway/(?<remaining>.*)",
            "replacement": "/${remaining}"
          }
        }
      ],
      "uri": "lb://gateway",
      "order": 0
    },
    "order": 0
  },
  {
    "route_id": "CompositeDiscoveryClient_uiservice",
    "route_definition": {
      "id": "CompositeDiscoveryClient_uiservice",
      "predicates": [
        {
          "name": "Path",
          "args": {
            "pattern": "/uiservice/**"
          }
        }
      ],
      "filters": [
        {
          "name": "RewritePath",
          "args": {
            "regexp": "/uiservice/(?<remaining>.*)",
            "replacement": "/${remaining}"
          }
        }
      ],
      "uri": "lb://uiservice",
      "order": 0
    },
    "order": 0
  },
  {
    "route_id": "uiservice_route",
    "route_definition": {
      "id": "uiservice_route",
      "predicates": [
        {
          "name": "Path",
          "args": {
            "_genkey_0": "/*"
          }
        }
      ],
      "filters": [],
      "uri": "lb://uiservice",
      "order": 0
    },
    "order": 0
  },
  ....
]

请注意,服务很容易被发现,因为:"route_id": "CompositeDiscoveryClient_gateway""route_id": "CompositeDiscoveryClient_uiservice",这些路由不是我的(我没有定义它们)。

我看了一下这个帖子:How to set up Spring Cloud Gateway application so it can use the Service Discovery of Spring Cloud Kubernetes? 没有成功。

我的配置:

   spring:
      profiles:
        active: prod
      cloud:
        kubernetes:
          reload:
            enabled: true
        gateway:
          discovery:
            locator:
              enabled: true 
              lower-case-service-id: true
          globalcors:
            cors-configurations: 
              '[/**]':
                allowedOrigins: uiservice
                allowedMethods: "*"
                allowCredentials: true
                maxAge: 7200
                allowedHeaders: "*"
                exposedHeaders:
                - "Access-Control-Allow-Origin"
                - "Access-Control-Allow-Methods"
                - "Access-Control-Max-Age"
                - "Access-Control-Allow-Headers"
                - "Cache-Control"
                - "Authorization"
                - "Content-Type"
          routes:
          #======UISERVICE========
          - id: uiservice_route
            uri: lb://uiservice 
            predicates:
            - Path=/* #default route

          - id: uiservice_route_assets
            uri: lb://uiservice
            predicates:
            - Path=/assets/**
   management:
      endpoints:
        web:
          exposure:
            include: "*"
      endpoint:
          restart:
            enabled: true

另外,如何禁用网关自动发现?我不想要"route_id": "CompositeDiscoveryClient_gateway"

依赖关系:

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-kubernetes-all</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

感谢您的帮助

【问题讨论】:

    标签: kubernetes spring-cloud spring-cloud-gateway spring-cloud-kubernetes


    【解决方案1】:

    在浪费了一个下午之后,我终于找到了解决方案。我认为使用 Ribbon 时服务发现存在问题。我使用 k8s dns 服务发现而不是依赖 Ribbon,所以我的新配置是:

    routes:
    - id: uiservice_route
      uri: http://uiservice:4200 # switch 'lb://' to 'http://'
      predicates:
      - Path=/* 
    

    K8s uiservice 配置:

    apiVersion: v1
    kind: Service
    metadata:
      name: uiservice
    spec:
      sessionAffinity: ClientIP
      selector:
        app: uiservice
      ports:
        - name: http
          port: 4200
          targetPort: ui-port
    

    出现了一个新问题:为什么要使用 Ribbon 来负载均衡请求,因为 k8s 服务本身就是这样做的?

    【讨论】:

    【解决方案2】:

    设置以下属性

    spring:
      cloud:
        gateway:
          discovery:
            locator:
              enabled: false
    

    【讨论】:

    • 谢谢,将属性设置为false 解决了自动发现问题,但我仍然有Unable to find instance for uiservice
    • 您认为这可能是功能区问题吗,因为当我设置 url-expression: "uri" 时一切正常,但这是一个糟糕的解决方案,因为请求不再是负载平衡的。
    • 我终于找到了解决办法,见上,你能回答最后一个问题吗?谢谢
    • @akuma8 看来您已经花了很多时间来解决这个问题。你能解决吗?我在同一条船上,我的网关无法发现服务。你能提供一些指导吗?
    • @Amit 在下面看到我的回答stackoverflow.com/a/57605600/6643803
    【解决方案3】:

    应该是这样的:

    spring:
      application.name: gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true
              url-expression: "'http://'+serviceId+':'+getPort()"
              lower-case-service-id: true
    

    当调用http://gateway/my-service-name/api/etc时,如果服务存在于kubernetes中则调用my-service-name/api/etc

    所以你需要确保有这样的服务:

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service-name
      namespace: default
      labels:
        app: my-service-name
    spec:
      type: NodePort
      ports:
        - port: 8080
          nodePort: 30080
      selector:
        app: my-service-name
    

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2021-07-26
      • 2018-10-25
      • 2020-02-10
      • 2019-02-11
      • 2020-08-14
      • 2021-02-03
      • 2018-04-23
      • 2021-10-23
      相关资源
      最近更新 更多