【问题标题】:How to route multiple gRPC services based on path in Istio(Kubernetes)如何在 Istio(Kubernetes) 中基于路径路由多个 gRPC 服务
【发布时间】:2020-10-09 01:02:18
【问题描述】:

我已经设法在根路径中运行了一个 grpc 服务。但是我试图通过在虚拟服务中添加自定义路径路由来添加更多的 grpc 服务,但这不起作用。任何帮助将不胜感激。

这是网关:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

我有这个虚拟服务路由到只有一个 grpc 服务并且工作正常

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  hosts:
    - "*"
  gateways:
    - my-gateway
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-1-svc

但我想尝试以下类似的方法,但 它不起作用

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  hosts:
    - "*"
  gateways:
    - my-gateway
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/my-grpc-1"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-1-svc
  - name: "my-grpc-2"
    match:
    - uri:
        prefix: "/my-grpc-2"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-2-svc

【问题讨论】:

  • 您是否尝试将网关对象中的协议字段更改为grpc
  • 您好@Prata,您的问题解决了吗?
  • @DawidKruk 我不能将此路径前缀匹配用于单独的 grpc 服务,但我所做的是我在入口控制器中为不同的 grpc 服务打开不同的端口
  • @Prata 很高兴您找到了解决方法。请考虑自己创建答案,以提高知名度并向社区展示可能的解决方法。

标签: kubernetes grpc istio


【解决方案1】:

以下是使用 grpc 和 istio 时的一些提示(使用 istio 1.9.2 测试)。

1.设置服务协议:

kind: Service
metadata:
  name: my-grpc-service
spec:
  ports:
  - number: 9009
    appProtocol: grpc

2.设置网关协议:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
spec:
  servers:
    - port:
        number: 80
        name: grpc
        protocol: GRPC
      hosts:
        - "*"

3.grpc 生成的 uri 路径前缀将与 .proto 文件中的package 值相同:

syntax = "proto3";    
package somepath;

将其用作match.uri.prefix:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/somepath"

【讨论】:

    【解决方案2】:

    这可能不起作用,因为您的应用侦听 / 并且使用您的第一个虚拟服务(有效),istio 向 / 发送请求,而您的第二个虚拟服务不会发生这种情况。

    这里的答案是将rewrite 添加到您的第二个虚拟服务中。

    HTTPRewrite 可用于在将请求转发到目的地之前重写 HTTP 请求的特定部分。重写原语只能与 HTTPRouteDestination 一起使用。以下示例演示了如何在进行实际 API 调用之前将 api 调用 (/ratings) 的 URL 前缀重写为评级服务。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: ratings-route
    spec:
      hosts:
      - ratings.prod.svc.cluster.local
      http:
      - match:
        - uri:
            prefix: /ratings
        rewrite:
          uri: /v1/bookRatings
        route:
        - destination:
            host: ratings.prod.svc.cluster.local
            subset: v1
    

    应该是这样的

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: my-virtual-svc
    spec:
      hosts:
        - "*"
      gateways:
        - my-gateway
      http:
      - name: "my-grpc-1"
        match:
        - uri:
            prefix: "/my-grpc-1"
        rewrite:
          uri: "/"
        route:
        - destination:
            port:
              number: 9090
            host: my-grpc-1-svc
      - name: "my-grpc-2"
        match:
        - uri:
            prefix: "/my-grpc-2"
        rewrite:
          uri: "/"
        route:
        - destination:
            port:
              number: 9090
            host: my-grpc-2-svc
    

    有关它的相关文档是here


    我认为您可以尝试使用 github issue comment 中提到的 gRPC 服务的 FQN 来做到这一点

    另一个想法是使用提到的 nginx here

    【讨论】:

    • 感谢您的回复,但即使我设置了它也没有用:'rewrite.uri: /'。您的解决方案不适用于 grpc,但适用于 http REST 服务。一种解决方案可能是使用域来路由 grpc 连接/请求,但我想使用路径进行路由。
    • 在你为 2 个 grpc 服务应用你的 vs 之后,你得到 404 的问题是什么?如果您将第一个前缀从 my-grpc-1 更改为 / 那么第一个工作和第二个得到 404?也许像this 这样的东西可以提供帮助?
    • 是gRPC服务器,没有404,404是http服务器的状态码,集群中没有http服务器,只有gRPC。问题是 gRPC 客户端无法使用 VirtualService 中提到的路径连接到 gRPC 服务器...仅适用于根路径。
    【解决方案3】:

    路由 grpc 的便捷方式是 Ingress。但是它需要为ngnix添加一些设置:

    如果您希望将加密流量转发到您的 POD 并终止 gRPC 服务器本身的 TLS,添加 ingress 注释
    nginx.ingress.kubernetes.io/backend-protocol: "GRPCS"。

    否则

    请注意,gRPC 服务必须指定为后端服务。 nginx.ingress.kubernetes.io/grpc-backend: "true"

    NGINX Ingress Controller: This example demonstrates how to route traffic to a gRPC service through the nginx controller.

    【讨论】:

      猜你喜欢
      • 2019-02-14
      • 2018-09-04
      • 2020-02-27
      • 1970-01-01
      • 2023-03-26
      • 2021-10-23
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多