Can one Virtual service fan out the request to multiple services - istio

You will have request for (say /test ) , and that request has to be redirected to multiple services
kind of multitasking behavior
I tried below things , but it didn't work
- route:
- destination:
host: details
subset: v1
- destination:
host: preview
subset: v1
I have code for matching the test prefix and added only that part where actual redirection is happening.
In simpler way . I want to know , how to achieve fan out in istio

You haven't shared a full VirtualService manifest, however in the similar scenario I used the following configuration in order to distinguish HTTP requests to the same prefix path by applying specific custom headers:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- example
gateways:
- example-gateway
http:
- match:
- headers:
test:
exact: details
- uri:
prefix: /test
route:
- destination:
host: details
subset: v1
- match:
- headers:
test:
exact: preview
- uri:
prefix: /test
route:
- destination:
host: preview
subset: v1
Of course don't forget to accomplish appropriate DestinationRule's
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
spec:
host: details
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: preview
spec:
host: preview
subsets:
- name: v1
labels:
version: v1
You can find more relevant information in the official Istio traffic management documentation.

Try to use mirror option in Istio https://istio.io/docs/tasks/traffic-management/mirroring/

Related

cookie-based virtual service routing does not work

We followed the instructions in the Istio Rules Configuration docs to setup routing rule based on a cookie.
There is the actual istio virtual service configuration:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
meta.helm.sh/release-name: prodstagingistio
meta.helm.sh/release-namespace: istio-system
creationTimestamp: "2022-07-14T16:12:56Z"
generation: 22
labels:
app.kubernetes.io/managed-by: Helm
name: api-gateway-virtualservice
namespace: istio-system
resourceVersion: "149056406"
uid: a5be0a58-6fd8-467c-9a98-5de9ac71b1dd
spec:
gateways:
- api-gateway
hosts:
- api0-prod.dev.domain.com
- api0-staging.dev.domain.com
http:
- match:
- authority:
exact: api0-prod.dev.domain.com
headers:
cookie:
regex: ^(.*;.)?(feature-b=true)(;.*)?$
route:
- destination:
host: api-gateway.blue.svc.cluster.local
- match:
- authority:
exact: api0-prod.dev.domain.com
route:
- destination:
host: api-gateway.green.svc.cluster.local
- match:
- authority:
exact: api0-staging.dev.domain.com
route:
- destination:
host: api-gateway.orange.svc.cluster.local
Supposedly, when accessing https://api0-prod.dev.domain.com with cookie value (feature-b=true) in http header, the traffic should be redirected to api-gateway.blue.svc.cluster.local. But regardless of the cookie setting, the traffic was sent to api-gateway.green.svc.cluster.local.
But I can't find anything wrong according to the document.
Can anything help taking a look of the config and see why the cookie setting doesn't work?
The virtual service routes should be like below to match cookie. Similarly you need to add for green.
http:
- match:
- headers:
cookie:
regex: ^(.*;.)?(feature-b=true)(;.*)?$
route:
- destination:
host: api-gateway.blue.svc.cluster.local
subset: blue-sub

How do I get Istio route matching to work?

I have an Istio gateway, Istio VirtualService, and app deployed running as a service. The virtual service is deployed like so:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-app-route
spec:
hosts:
- "*"
gateways:
- my-gateway
http:
- match:
- uri:
prefix: "/my-app"
route:
- destination:
host: my-app-service
port:
number: 8000
When I navigate to http://myurl.com/my-app I would expect to see a JSON response from the service it is pointing to, but I just get a 404. However if I remove the match and redeploy like so:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-app-route
spec:
hosts:
- "*"
http:
- route:
- destination:
host: my-app-service
port:
number: 800
And then go to http://myurl.com/my-app I can see the expected JSON response. Any help?

Is it possible to apply virtualService and Destination to the specified version of the POD

I have two http services A and B, and each service has two versions v1 and v2.
If A(v1) calls B, eg. use http://b:8080, both B(v1) and B(v2) can answer the call.
When A (v2) calls B, only B (v2) gets the call.
How should I define virtualService and Destination rules in this scenario?
You would need to match the pod from where the traffic is coming from with sourceLabels and the route it to the specific subsets. Here's an example of how that might look like:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: route-av1-bv1-2
spec:
hosts:
- service-b
http:
#Match the traffic from App-A-version-1 towards App-B versions 1 & 2
- match:
- sourceLabels:
app: av1
- route:
- destination:
host: service-b
subset: v1
- route:
- destination:
host: service-b
subset: v2
#Match the traffic from App-A-version-2 towards only App-B-version-2
- match:
- sourceLabels:
app: av2
- route:
- destination:
host: service-b
subset: v2
And the DestinationRule:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: route-av1-bv1-2
spec:
host: service-b
subsets:
- name: v1
labels:
app: bv1
- name: v2
labels:
app: bv2
Istio traffic management sections describes the VirtualService and DestinationRule very well along with some good examples.

Istio queryParams always returning truthy

Set up istio and the basic bookinfo app
set up the virtual service as such:
one with headers:
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: bookinfo
spec:
hosts:
- '*'
gateways:
- bookinfo-gateway
http:
- match:
- headers:
apiKey:
exact: test
rewrite:
uri: /productpage
route:
- destination:
host: productpage
port:
number: 9080
tcp: ~
tls: ~
and another with queryParams as the routing differentiator:
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: bookinfo
spec:
hosts:
- '*'
gateways:
- bookinfo-gateway
http:
- match:
- headers:
apiKey:
exact: test
rewrite:
uri: /productpage
route:
- destination:
host: productpage
port:
number: 9080
tcp: ~
tls: ~
For some reason, the header policy seems to work fine. i.e if I dont submit the header=test, istio will return 404.
HOWEVER, for the queryParams, it is always returning thruthy. am I doing something wrong? or is this an istio related issue at its core.
(note: these 2 vs are not running in parallel, but rather an update from one to another, so it cant be some wonkyness with having 2 similar VS)
Ideally i would expect for the queryParam vs headers to act the same.
This was in fact a quasi-defect.
The docs for istio-1.2 was incorrectly stating feature that was found in 1.3.
For those of you in a similar situation, upgrading to istio 1.3.x should resolve it.

Istio VirtualService HTTP header match issue

The following Istio 0.8 VirtualService fails to match the HTTP header.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
foo:
exact: bar
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v3
I have followed https://github.com/istio/issues/issues/38 and Istio RouteRule based on headers user-agent doesn't work. However am unable to get it to function.
Pointers would be really helpful as the sleep service returns the product page similar to POSTMAN with no implication of the match condition!
This VirtualService by itself won't work if you don't have a DestinationRule to define your subsets (versions).
I will demonstrate how it should be done with the HelloWorld sample that is packed with the 0.8 release:
Step 1: Deploy the samples/helloworld/helloworld.yaml
Step 2: Define a DestinationRule for the two available versions:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
spec:
host: helloworld
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Step 3: Replace the default VirtualService with the one that matches header attribute for routing:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- headers:
foo:
exact: bar
route:
- destination:
host: helloworld
subset: v2
- route:
- destination:
host: helloworld
subset: v1
Step 4: Test it:
Without header: curl http://$INGRESS_GATEWAY/hello
Output:
Hello version: v1, instance: helloworld-v1-fd9b784bb-wcnj9
With header: curl -H "foo: bar" http://$INGRESS_GATEWAY/hello
Output:
Hello version: v2, instance: helloworld-v2-56694b7d6d-gbhqb
You need to call the reviews service through the ingressgateway. If you aren't doing that, there are two ways you could be hitting a problem:
If you are calling productpage (curl <ingress url>/productpage -H "foo: bar"), there is not any logic to propagate the foo: bar header from productpage to the reviews service. The example with the user-agent works because the user-agent is automatically propagated (a special case). If you want to use foo: bar, you would have to add logic to the productpage service to grab the foo header and send it on to the reviews service.
You are calling the reviews service directly (for instance, you gave the reviews service a node port). This would fail because your request is not being routed by an Istio proxy --instead it is being handled by the k8s service load balancer. You need to call an Istio proxy, like the ingressgateway.