如何通过Istio Gateway与VirtualService正确路由两个gRPC服务
问题根因
- 你为两个gRPC服务创建了独立的VirtualService,绑定同一个Gateway、同一个域名,且都使用
/作为URI前缀匹配,Istio对同域名同网关的多个独立VirtualService不会自动合并路由规则,会按资源优先级选择其中一个生效,因此永远只有一个服务能被路由到。 - 你尝试使用
/grpc-1、/grpc-2作为前缀匹配不生效,核心原因有两个:一是原生gRPC请求的路径格式固定为/[protobuf包名].[服务名]/[RPC方法名],默认不会携带你自定义的上下文前缀,请求根本匹配不到对应规则;二是就算你强制让客户端带前缀发起请求,没有配置路径重写的话,后端gRPC服务收到带多余前缀的路径,会直接返回方法未找到的错误。 - 你当前Gateway配置的端口协议为
HTTP,gRPC基于HTTP/2传输,协议配置错误也会导致部分路由场景异常。
方案1:基于gRPC服务全限定名匹配(推荐,无客户端改造)
这是Istio路由gRPC服务的标准方案,不需要修改客户端调用逻辑,直接基于gRPC原生路径规则做匹配即可。
- 先修正Gateway配置,将端口协议从
HTTP改为GRPC,适配gRPC的HTTP/2传输要求:
# grpc_gateway.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: grpc-gateway spec: selector: istio: ingressgateway servers: - port: name: grpc number: 80 protocol: GRPC hosts: - "*"
- 删除原来两个独立的VirtualService,将两个服务的路由规则合并到同一个VirtualService中,基于gRPC原生的全限定服务名做前缀匹配,长路径规则放在前面优先匹配:
# grpc-service-vs.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: grpc-service-vs spec: hosts: - "istio-ingressgateway-istio-system.apps.xxxx.zfjb.p1.openshiftapps.com" gateways: - grpc-gateway http: # 先匹配grpc-1的服务路径,替换成你proto中实际的包名+服务名 - match: - uri: prefix: "/your.package.Grpc1Service/" route: - destination: port: number: 9014 host: grpc-1 # 再匹配grpc-2的服务路径,替换成你proto中实际的包名+服务名 - match: - uri: prefix: "/your.package.Grpc2Service/" route: - destination: port: number: 9015 host: grpc-2
如果不确定自己的gRPC服务路径,可以直接抓包查看请求的:path头部,或者在后端服务侧打印请求路径获取。
方案2:自定义路径前缀+重写(需要客户端配合带前缀)
如果你一定要用/grpc-1、/grpc-2作为路由区分标识,可以按以下方式配置:
- Gateway配置和方案1一致,使用
GRPC协议。 - 合并VirtualService规则,配置前缀匹配+路径重写,转发前去掉自定义前缀,保证后端收到标准gRPC路径:
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: grpc-service-vs spec: hosts: - "istio-ingressgateway-istio-system.apps.xxxx.zfjb.p1.openshiftapps.com" gateways: - grpc-gateway http: - match: - uri: prefix: "/grpc-1" rewrite: uri: "/" route: - destination: port: number: 9014 host: grpc-1 - match: - uri: prefix: "/grpc-2" rewrite: uri: "/" route: - destination: port: number: 9015 host: grpc-2
注意:这个方案要求客户端发起gRPC请求时必须在路径前携带对应的
/grpc-1或/grpc-2前缀,否则无法匹配到对应路由规则。
配置注意事项
- 同一个域名、同一个Gateway绑定的路由规则,尽量合并到单个VirtualService中维护,避免多VirtualService的优先级冲突导致路由异常
- URI前缀匹配遵循最长匹配优先原则,更长的路径匹配规则需要放在更靠前的位置,避免被短路径规则提前拦截
- 如果是TLS加密的gRPC服务使用443端口,Gateway的协议同样要配置为
GRPC,不要用HTTP2或者HTTPS,否则Istio的gRPC相关路由能力不会生效。
内容的提问来源于stack exchange,提问作者dipanjan bhaumik
相关产品推荐
相关产品推荐

