问题
I'm wondering how I can match gRPC routes on the same port. Here's an example of what I was hoping to accomplish with my VirtualService:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istio-ingress
spec:
hosts:
- "*"
gateways:
- istio-gateway
http:
- match:
- uri:
prefix: "/custom.api/stream"
- port: 31400
route:
- destination:
host: stream-handler.default.svc.cluster.local
port:
number: 8444
timeout: 60s
retries:
attempts: 3
perTryTimeout: 2s
- match:
- port: 31400
route:
- destination:
host: api.default.svc.cluster.local
port:
number: 8443
timeout: 60s
retries:
attempts: 3
perTryTimeout: 2s
So basically: for all requests into 31400 the first match looks for requests to stream at "/custom.api/stream" which has a destination of my stream server.
The second rule as a catch all to gain entry to my main API.
My goal is to have all connections coming through 31400 and then splinter off the request to a dedicated internal service. In the future I'll likely split off services even further (not just for streaming). ie. entire groups of the endpoint might be handled by separate clusters.
When I deploy this rule though the whole VS seems to fail and nothing responds.
回答1:
Ports are externally exposed in the Ingressgateway
and should be internally configured using a Gateway
. The VirtualService
is intended for layer 7 routing only (once attached to a Gateway
).
In your match
configuration, you're specifying that the addressed host should receive requests in the port 31400, not that the service is listening there. From the documentation:
port: Specifies the ports on the host that is being addressed. Many services only expose a single port or label ports with the protocols they support, in these cases it is not required to explicitly select the port.
In your case, you might want to create a new Gateway
to take care of the exposed port's configuration and then, attach the routing part using your VirtualService
:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grpc-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 31400
name: grpc
protocol: GRPC
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grpc-virtualservice
spec:
hosts:
- "*"
gateways:
- grcp-gateway
http:
- match:
- uri:
exact: "/custom.api/stream"
route:
- destination:
host: stream-handler.default.svc.cluster.local
port:
number: 8444
timeout: 60s
retries:
attempts: 3
perTryTimeout: 2s
- match:
- uri:
prefix: "/"
route:
- destination:
host: api.default.svc.cluster.local
port:
number: 8443
timeout: 60s
retries:
attempts: 3
perTryTimeout: 2s
Since match
cannot be empty, you need to prefix it to pick up whatever is coming except for the previous URI exact match.
回答2:
Here are my observations:
- VirtualService ->
http.match.port
. I don't thinkport
is used correctly here. If this is supposed to indicate the listening to incoming requests to port 31400, then this should actually be in the Gateway YAML specificationistio-gateway
. - Please share the specification of your Gateway named
istio-gateway
. Basically, it is there where you specify that you are listening toport.number: 31400
. The VirtualService is where you indicate to which service/host and port you want to route or "splinter off the request".
Please check and see if it helps.
来源:https://stackoverflow.com/questions/57501384/match-istio-virtual-services-routes-for-different-paths-on-same-port