Mounting applications of different paths with Istio - kubernetes

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

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.

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

istio virtual service route destination with context path

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

Istio VirtualService always 404s

I've had a single VirtualService running through a simple http Gateway and everything works fine:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: satc-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: report
spec:
hosts:
- report-create.default.svc.cluster.local
gateways:
- satc-gateway
http:
- match:
- uri:
prefix: /v1/report
route:
- destination:
host: report-create
port:
number: 8080
I have since added a second VirtualService for a the second service in the cluster through the same Gateway
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: routing
spec:
hosts:
- routing-svc.default.svc.cluster.local
gateways:
- satc-gateway
http:
- match:
- uri:
prefix: /v1/routing
route:
- destination:
host: routing-svc.default.svc.cluster.local
port:
protcol: http
number: 8080
Whilst the first VirtualService still seems to serve, the second consistently 404s. I have added a simple endpoint "/v1/routing/test" to return a Hello World message to ensure the issue doesn't spawn from application logic.
Both VirtualServices seem to be running as expected, though only requests to report are returning anything other than a 404:
report [satc-gateway] [report-create.default.svc.cluster.local] 2h
routing [satc-gateway] [routing-svc.default.svc.cluster.local] 18m
I have tried removing the first deployment all together to ensure it is now hoovering up all the traffic coming in to the cluster and still get 404s. I've also tried executing the routes from inside the pod with a successful response, both services use container port 8080 which I have also triple checked.
I seem to have hit a bit of a wall with this, unsure what is the next best steps in order to debug correctly.
I have analyzed both your yamls and found few issues regarding the second one:
there are 2 extra spaces in the prefix: line
there is a typo in the 'protocol:' line (missed an o)
there are some differences in the destination: part
Please make the adjustments and let me know if that helped.

Istio in AKS with DNS

I deployed the book application from Istio in a AKS cluster that has a Loadbalancer and a custom domain. Here is the gateway.yaml:
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:
- "x.myaks.domain"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "x.myaks.domain"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
The problem is, when I navigate in my browser to x.myaks.domain/productpage, I get an DNS unresolved error. Does anyone know how to expose services with Istio in AKS clusters under a domain?
Doing curl -H "Host: x.myaks.domain" loadbalancerip/productpage works perfectly
Update
I just have the info that an automatic DNS entry in Azure is created when the Ingress ressource is defined.
Is it possible to use istio with an Ingress ressource?
If not, how to secure the data between an istio envoy proxy and the nginx ingress controller?
For ingress objects ExternalDNS will create a DNS record based on the host specified for the ingress object.
For services ExternalDNS will look for the annotation external-dns.alpha.kubernetes.io/hostname on the service and use the corresponding value.