URL Regex match for Istio- VirtualService throwing 404 - kubernetes

My Gateway and VirtualService for the sample BookInfo looks like this:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
route:
- destination:
host: productpage
port:
number: 9080
- match:
- uri:
regex: "v1"
route:
- destination:
host: productpage
port:
number: 9080
I am terminating TLS at the gateway and in the HTTP route, I have configured a regex match on "v1" for HTTP and routing it the productpage service.
I am testing this by sending a request to http://External-IP/api/v1/products (the sample application's productpage service is configured to return a text body on this endpoint), but the request fails with HTTP 404. I am not sure what I am doing wrong here, any help is highly appreciated.

I think I found the mistake here, the regex : "v1" does not do partial match.
- match:
- uri:
regex: v1
route:
- destination:
host: productpage
port:
number: 9080
Instead I had to specify regex : .*v1.* to make it work. I am able to route now.
- match:
- uri:
regex: .*v1.*
route:
- destination:
host: productpage
port:
number: 9080

Well, unless I'm reading this wrong your path filters dont match your request, your request is /api and your filters dont have that

Related

Is there a way were we can specify two services for single context path in istio virtual service?

I have two different micro-services running in same name space, both have same context path (ex - my/context/path), further controllers are different in both of them, for example service one supports - my/context/path/service1 and service2 supports my/context/path/service2
now when i defined vs like this, its always redirecting to the service1, is there a possible way to achieve this?
below is my VS:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-service
namespace: ns-ns
spec:
gateways:
- gateway.ns-ns
hosts:
- '*'
http:
- match:
- uri:
prefix: /my/context/path
route:
- destination:
host: service1.ns-ns.svc.cluster.local
port:
number: 9000
- route:
- destination:
host: service2.ns-ns.svc.cluster.local
port:
number: 9000
I also tried below VS, but this also seems to redirect to first service.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-service
namespace: ns-ns
spec:
gateways:
- gateway.ns-ns
hosts:
- '*'
http:
- match:
- uri:
prefix: /my/context/path
route:
- destination:
host: service1.ns-ns.svc.cluster.local
port:
number: 9000
- match:
- uri:
prefix: /my/context/path/service2
route:
- destination:
host: service2.ns-ns.svc.cluster.local
port:
number: 9000
i am not sure if this is achievable or not, or do i need to separate the context part of both the services?
The routes are matched in order. Thus you need to start from the most specific to the most generic. e.g.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-service
namespace: ns-ns
spec:
gateways:
- gateway.ns-ns
hosts:
- '*'
http:
- match:
- uri:
prefix: /my/context/path/service2
route:
- destination:
host: service2.ns-ns.svc.cluster.local
port:
number: 9000
- match:
- uri:
prefix: /my/context/path
route:
- destination:
host: service1.ns-ns.svc.cluster.local
port:
number: 9000

Istio ingress gateway subdomainrouting based

I have three service that I need to expose via istio ingress gateway, i have setup those services dns records to point to the ingress gateway load balancer but i have not succeded to make it work.
The gateway and virtual service config file :
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: test-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*.mywebsite.io"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtualservice
spec:
hosts:
- "*.mywebsite.io"
gateways:
- test-gateway
http:
- name: "api-gateway"
match:
- uri:
exact: "gateway.mywebsite.io"
route:
- destination:
host: gateway.default.svc.cluster.local
port:
number: 8080
- name: "visitor-service"
match:
- uri:
exact: "visitor-service.mywebsite.io"
route:
- destination:
host: visitor-service.default.svc.cluster.local
port:
number: 8000
- name: "auth-service"
match:
- uri:
exact: "auth-service.mywebsite.io"
route:
- destination:
host: auth-service.default.svc.cluster.local
port:
number: 3004
I guess the URI part of the HttpMatchRequest does not work that way. Try to add VirtualServices for each subdomain, i.e. something like.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: gateway-virtualservice
spec:
hosts:
- "gateway.mywebsite.io"
gateways:
- test-gateway
http:
- name: "api-gateway"
match:
- uri:
exact: "/" #or prefix
route:
- destination:
host: gateway.default.svc.cluster.local
port:
number: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: visitor-virtualservice
spec:
hosts:
- "visitor-service.mywebsite.io"
gateways:
- test-gateway
http:
- name: "visitor-service"
match:
- uri:
exact: "/"
route:
- destination:
host: visitor-service.default.svc.cluster.local
port:
number: 8000

Istio Ingress Gateway not working in Anthos

I created a cluster in GKE - (Google Kubernetes Engine)
Folowed the instructions here https://cloud.google.com/service-mesh/docs/quickstart-asm
but used my own deployment files.
I deployed these service and gateway file.
Partial Service
---
apiVersion: v1
kind: Service
metadata:
name: node-microservice-service
spec:
selector:
app: node-microservice
# type: LoadBalancer
ports:
- name: tcp-node
protocol: TCP
port: 8080
targetPort: 8080
# nodePort: 30000
---
Gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: backend-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "backend.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend-ingress
spec:
hosts:
- "backend.com"
gateways:
- backend-gateway
http:
- match:
- uri:
prefix: "/node"
route:
- destination:
port:
number: 8080
host: node-microservice-service
- match:
- uri:
prefix: "/java"
route:
- destination:
port:
number: 8080
host: java-microservice-service
- match:
- uri:
prefix: "/golang"
route:
- destination:
port:
number: 8080
host: golang-microservice-service
- match:
- uri:
prefix: "/python"
route:
- destination:
port:
number: 8080
host: python-microservice-service
- route:
- destination:
port:
number: 8080
host: python-microservice-service
I am using the proper IP address and host together still unable to reach the microservices through the istio ingress gateway service.

How to use OR logic in istio virtual service header exact match?

I have two services running and 4 different headers. I want to direct requests with headers a and c to one service and b and d to another service. What is the best way to achieve that in a virtual service manifests?
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sample_virtualservice
namespace: sample_namespace
spec:
hosts:
- sample_service.sample_namespace.svc.cluster.local
http:
- match:
- headers:
x-test:
exact: "a" OR "c" //This doesn't work but I want to achieve.
route:
- destination:
host: service_1.sample_namespace.svc.cluster.local
port:
number: 80
- route:
- destination:
host: service_2.sample_namespace.svc.cluster.local
port:
number: 80
I believe there must be a better way instead of mentioning the same route destination multiple times in a manifest file.
I found a clean solution of using regex instead of exact which allows us to send requests to the same destination for different headers without mentioning the same route destination multiple times in a manifest file.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sample_virtualservice
namespace: sample_namespace
spec:
hosts:
- sample_service.sample_namespace.svc.cluster.local
http:
- match:
- headers:
x-test:
regex: "a|c"
route:
- destination:
host: service_1.sample_namespace.svc.cluster.local
port:
number: 80
- route:
- destination:
host: service_2.sample_namespace.svc.cluster.local
port:
number: 80
As far as I know there are not logical operators in istio virtual service.
They are only available in rules and mixer expression language.
As you mentioned for now the only option is to use the same route multiple times.
So virtual service would look like this.
http:
- name: "a"
match:
- headers:
x-test:
exact: "a"
route:
- destination:
host: service_1.sample_namespace.svc.cluster.local
port:
number: 80
- name: "b"
match:
- headers:
x-test:
exact: "b"
route:
- destination:
host: service_1.sample_namespace.svc.cluster.local
port:
number: 80
- name: "c"
match:
- headers:
x-test:
exact: "c"
route:
- destination:
host: service_2.sample_namespace.svc.cluster.local
port:
number: 80
- name: "d"
match:
- headers:
x-test:
exact: "d"
route:
- destination:
host: service_2.sample_namespace.svc.cluster.local
port:
number: 80
Additional info, I see you have virtual service deployed in sample_namespace, remember that gateway should be deployed in the same namespace. If it´s not, you should add it like in below example.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
Check the spec.gateways section
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-Mongo
namespace: sample_namespace
spec:
gateways:
- some-config-namespace/my-gateway

Istio route rules

I'm trying to set some route rules and I have a problem in the following case. If I send a HTTP request to the port, let's say, 5000 of the service "service-a" I want my route rule to forward the request to the port 5001 of the service "service-b". Is it possible?
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-route
spec:
hosts:
- service-a:5000
- service-a
- service-a.service:5000
- service-a.service
- service-a.service.consul:5000
- service-a.service.consul
gateways:
- my-gateway
http:
- match:
- uri:
prefix: "/v1/service-a"
rewrite:
uri: "/v1/ser-a"
route:
- destination:
port:
number: 5001
name: service-b
The gateway was defined as follows:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
app: my-gatweway-controller
servers:
- port:
number: 5000
name: http
protocol: HTTP
hosts:
- localhost
- port:
number: 5001
name: http
protocol: HTTP
hosts:
- localhost
The result is an internal error 500 and the request lands on port 5000 instead on 5001. Does anybody know how to solve the problem?
Best regards
Martin
The port rewriting was fixed three days ago by this PR - https://github.com/istio/istio/pull/5543, it should appear in the next release of Istio.