istio virtual service route destination with context path - kubernetes

I have istio configuration on which the docker container runs jasperreports on tomcat(bitnami jasperreports). the application itself could be accessed with context path at http://IP:8080/jasperserver.
I am planning to use istio in my kubernetes configuration, expose the service using http gateway and virtual service. can I add context path of "jasperserver" in addition to destination host and port number in virtual service configuration?
here is my current virtualservice configuration
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: http-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: jasper-virtual-services
spec:
hosts:
- "*"
gateways:
- http-gateway
http:
- match:
- uri:
exact: /report
route:
- destination:
host: jasperserver.reporting.svc.cluster.local
port:
number: 80

You are probably looking for rewrites
Something like
http:
- match:
- uri:
exact: /report
rewrite:
uri: /jasperserver

Related

How to route two grpc services using Istio virtual service and gateway

I have two grpc services (grpc-1 & grpc-2) in my project. I have deployed the grpc services on two different ports in openshift and created necessary configuration in Istio like gateway and virtual services.
I observed that at any time only one grpc service getting invoked as I am using "/" to route to services. I also tried to add context path like "/grpc-1" and "/grpc-2" but it didn't work.
Below is my code snippet from virtual services and gateway
grpc_gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: grpc-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
name: http
number: 80
protocol: HTTP
hosts:
- "*"
grpc-1-vs.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: grpc-1-vs
spec:
hosts:
- "istio-ingressgateway-istio-system.apps.xxxx.zfjb.p1.openshiftapps.com"
gateways:
- grpc-gateway
http:
- match:
- uri:
prefix: "/"
route:
- destination:
port:
number: 9014
host: grpc-1
grpc-2-vs.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: grpc-2-vs
spec:
hosts:
- "istio-ingressgateway-istio-system.apps.xxxx.zfjb.p1.openshiftapps.com"
gateways:
- grpc-gateway
http:
- match:
- uri:
prefix: "/"
route:
- destination:
port:
number: 9015
host: grpc-2
I am not able to route to two grpc services based on request url. Only one grpc service is being routed.

istio VirtualService is not working for my configuration

I have a digitalocean kubernetes cluster with istio installed on it. I get 404 not found error on accessing the apis on the postman application. Here's my vs-gateway yaml file:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ut-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: utbuild1
spec:
hosts:
- "*"
gateways:
- ut-gateway
http:
- match:
- uri:
prefix: /v3/api/products/search
rewrite:
uri: /api/products/search # or /
route:
- destination:
host: utbuild1 # pods/service created using istio-k8s-single-deployment.yaml (this service has 3 pods)
- match:
- uri:
prefix: /v4admin/api
route:
- destination:
host: utbuild1-admin # pod/service created using istio-k8s-single-deployment.yaml

404 Not Found when migrating from ingress to istio

I'm trying to migrate from ingress to istio gateway + virtual service routing, but I keep receiving a 404 Not Found error.
The only link that the app should be accessed to is using my-todos.com, configured locally.
What am I missing here?
Note: the ingress controller works just fine. Initially, todo-lb.default.svc.cluster.local in the istio.yaml file was just set to todo-lb, representing the configured load balancer, still with no success.
Here is the ingress.yaml file (to migrate from):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: todo-ingress
spec:
rules:
- host: my-todos.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: todo-lb
port:
number: 3001
- path: /api
pathType: Prefix
backend:
service:
name: {{ .Values.api.apiName }}
port:
number: {{ .Values.api.apiPort }}
Here is the istio.yaml file (to migrate TO):
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: todo-istio-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- my-todos.com
# - "*"
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: tls-secret
hosts:
- my-todos.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: todo-lb
spec:
hosts:
- my-todos.com
# - "*"
gateways:
- todo-istio-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: todo-lb.default.svc.cluster.local
port:
number: 3001
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: todo-api
spec:
hosts:
- my-todos.com
# - "*"
gateways:
- todo-istio-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
host: {{ .Values.api.apiName }}
port:
number: {{ .Values.api.apiPort }}
From what I see you've wrong gateway configuration in your virtual service, that's why it might not work.
If gateway is not in the same namespace as virtual service, you have to specify that in virtual service
Check the spec.gateways section
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-Mongo
spec:
gateways:
- some-config-namespace/my-gateway # can omit the namespace if gateway is in same
namespace as virtual service.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
There is related istio documentation about that.
So please move your todo-istio-gateway to default namespace.
or use
gateways:
- istio-system/todo-istio-gateway
Few things to check if that won't help:
Is your app deployed in default namespace?
Is your app injected?
Problem might be with your Gateway api:
404 errors occur when multiple gateways configured with same TLS certificate
Configuring more than one gateway using the same TLS certificate will cause browsers that leverage HTTP/2 connection reuse (i.e., most browsers) to produce 404 errors when accessing a second host after a connection to another host has already been established.
For example, let’s say you have 2 hosts that share the same TLS certificate like this:
Wildcard certificate .test.com installed in istio-ingressgateway
Gateway configuration gw1 with host service1.test.com, selector istio: ingressgateway, and TLS using gateway’s mounted (wildcard) certificate
Gateway configuration gw2 with host service2.test.com, selector istio: ingressgateway, and TLS using gateway’s mounted (wildcard) certificate
VirtualService configuration vs1 with host service1.test.com and gateway gw1
VirtualService configuration vs2 with host service2.test.com and gateway gw2
Since both gateways are served by the same workload (i.e., selector istio: ingressgateway) requests to both services (service1.test.com and service2.test.com) will resolve to the same IP. If service1.test.com is accessed first, it will return the wildcard certificate (.test.com) indicating that connections to service2.test.com can use the same certificate. Browsers like Chrome and Firefox will consequently reuse the existing connection for requests to service2.test.com. Since the gateway (gw1) has no route for service2.test.com, it will then return a 404 (Not Found) response.
You can avoid this problem by configuring a single wildcard Gateway, instead of two (gw1 and gw2). Then, simply bind both VirtualServices to it like this:
Gateway configuration gw with host *.test.com, selector istio: ingressgateway, and TLS using gateway’s mounted (wildcard) certificate
VirtualService configuration vs1 with host service1.test.com and gateway gw
VirtualService configuration vs2 with host service2.test.com and gateway
checkout this link:
https://istio.io/latest/docs/ops/common-problems/network-issues/#404-errors-occur-when-multiple-gateways-configured-with-same-tls-certificate
In addition to #Jakub answer, there can be one more reason you can get 404 error. Your current ingress rules in virtual service looks like this:
Hostname
Path
Route
my-todos.com
/
Forward to todo-lb.default.svc.cluster.local
my-todos.com
/api
Forward to {{ .Values.api.apiName }}
In Istio, each of the above is an ingress rule. If in Istio ingress-gateway, the rules are added in the above order, then all the URL path including the prefix /api gets routed to the first service i.e. todo-lb.default. It is better to create a single Virtual service like this and then see if the routing works as expected.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: todo-api
spec:
hosts:
- my-todos.com
gateways:
- <namespace>/todo-istio-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
host: {{ .Values.api.apiName }}
port:
number: {{ .Values.api.apiPort }}
- match:
- uri:
prefix: /
route:
- destination:
host: todo-lb.default
port:
number: 3001

How to bind gateway to a specific namespace?

I have the following scenario:
When the user A enter the address foo.example1.example.com in the
browser, then it should call the service FOO in the namespace
example1.
When the user B enter the address foo.example1.example.com in the
browser, then it should call the service FOO in the namespace
example2.
I am using istio, the question is, how to configure the gateway, that is bind specific to a namespace:
Look at an example of istio gateway configuration:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ns_example1
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "example1.example.com"
EOF
When I would deploy the gateway, then it will apply to current namespace but I would like to specify a namespace.
How to assign a gateway to specific namespace?
I think this link should answer your question.
There is many things You won't need, but there is idea You want to apply to your istio cluster.
So You need 1 gateway and 2 virtual services.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: foocorp-gateway
namespace: default
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
servers:
- port:
number: 80
name: http-example1
protocol: HTTP
hosts:
- "example1.example.com"
- port:
number: 80
name: http-example2
protocol: HTTP
hosts:
- "example2.example.com"
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example1
namespace: ex1
spec:
hosts:
- "example1.example.com"
gateways:
- foocorp-gateway
http:
- match:
- uri:
exact: /
route:
- destination:
host: example1.ex1.svc.cluster.local
port:
number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example2
namespace: ex2
spec:
hosts:
- "example2.example.com"
gateways:
- foocorp-gateway
http:
- match:
- uri:
exact: /
route:
- destination:
host: example2.ex2.svc.cluster.local
port:
number: 80
EDIT
You can create gateway in namespace ex1 and ex2, then just change gateway field in virtual service and it should work.
Remember to add namespace/gateway, not only gateway name, like there.
gateways:
- some-config-namespace/gateway-name
Let me know if that help You.

Mounting applications of different paths with Istio

We have installed Istio on my Kubernetes cluster on AWS (we are using EKS). We have deployed several applications such as: Airflow, Jenkins, Grafana, etc. and we are able to reach them with port-forward. So, they are working as expected.
Now, what we would like to achieve is the possibility of mounting the applications on specific paths so that we can access them via an unique entrypoint.
Here an example to explain what I mean with "unique entrypoint":
http://a517f7.eu-west-1.elb.amazonaws.com/aiflow/ and you can see Airflow dahsboard
http://a517f7.eu-west-1.elb.amazonaws.com/jenkins/ and you can see Jenkins dahsboard
http://a517f7.eu-west-1.elb.amazonaws.com/grafana/ and you can see Grafana dahsboard
What we tried is the following
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: apps-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: airflow-virtual-service
spec:
hosts:
- "*"
gateways:
- apps-gateway
http:
- match:
- uri:
prefix: /airflow
route:
- destination:
host: webserver.airflow.svc.cluster.local
port:
number: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-virtual-service
spec:
hosts:
- "*"
gateways:
- apps-gateway
http:
- match:
- uri:
prefix: /grafana
route:
- destination:
host: grafana.grafana.svc.cluster.local
port:
number: 3306
---
and so on
In this way but I keep having Aiflow 404 = lots of circles or similar depending on the service.
Do you know how to achieve such a result with Istio? We are also open to also use Nginx or Traefik.
So based on the comments:
The best way to expose a frontend & backend it's to separate both with a wildcard domain like *.domain.com.
For the frontend:
my-app.domain.com/
For the backend services it will always start with a subdomain like api:
api.domain.com/foo
For backend service you will need to use rewrite if your backend service it's no serving the path.
rewrite:
uri: "/"
Check Istio docs for more info about rewrite https://istio.io/docs/reference/config/istio.networking.v1alpha3/#Destination