How to bind gateway to a specific namespace? - kubernetes

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.

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.

How to access the prometheus & grafana via Istion ingress gateway? I have installed the promethius anfd grafana through Helm

I used below command to bring up the pod:
kubectl create deployment grafana --image=docker.io/grafana/grafana:5.4.3 -n monitoring
Then I used below command to create custerIp:
kubectl expose deployment grafana --type=ClusterIP --port=80 --target-port=3000 --protocol=TCP -n monitoring
Then I have used below virtual service:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana
spec:
hosts:
- "*"
gateways:
- cogtiler-gateway.skydeck
http:
- match:
- uri:
prefix: /grafana
route:
- destination:
port:
number: 3000
host: grafana
kubectl apply -f grafana-virtualservice.yaml -n monitoring
Output:
virtualservice.networking.istio.io/grafana created
Now, when I try to access it, I get below error from grafana:
**If you're seeing this Grafana has failed to load its application files
1. This could be caused by your reverse proxy settings.
2. If you host grafana under subpath make sure your grafana.ini root_path setting includes subpath
3. If you have a local dev build make sure you build frontend using: npm run dev, npm run watch, or npm run build
4. Sometimes restarting grafana-server can help **
The easiest and working out of the box solution to configure that would be with a grafana host and / prefix.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grafana-gateway
namespace: monitoring
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-grafana
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-vs
namespace: monitoring
spec:
hosts:
- "grafana.example.com"
gateways:
- grafana-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: grafana
port:
number: 80
As you mentioned in the comments, I want to use path based routing something like my.com/grafana, that's also possible to configure. You can use istio rewrite to configure that.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grafana-gateway
namespace: monitoring
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-grafana
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-vs
namespace: monitoring
spec:
hosts:
- "*"
gateways:
- grafana-gateway
http:
- match:
- uri:
prefix: /grafana
rewrite:
uri: /
route:
- destination:
host: grafana
port:
number: 80
But, according to this github issue you would have also additionally configure grafana for that. As without the proper grafana configuration that won't work correctly.
I found a way to configure grafana with different url with the following env variable GF_SERVER_ROOT_URL in grafana deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: grafana
name: grafana
spec:
replicas: 1
selector:
matchLabels:
app: grafana
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: grafana
spec:
containers:
- image: docker.io/grafana/grafana:5.4.3
name: grafana
env:
- name: GF_SERVER_ROOT_URL
value: "%(protocol)s://%(domain)s/grafana/"
resources: {}
Also there is a Virtual Service and Gateway for that deployment.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grafana-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-grafana
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-vs
spec:
hosts:
- "*"
gateways:
- grafana-gateway
http:
- match:
- uri:
prefix: /grafana/
rewrite:
uri: /
route:
- destination:
host: grafana
port:
number: 80
You need to create a Gateway to allow routing between the istio-ingressgateway and your VirtualService.
Something in the lines of :
kind: Gateway
metadata:
name: ingress
namespace: istio-system
spec:
selector:
# Make sure that the istio-ingressgateway pods have this label
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- my.domain.com
You also need a DNS entry for your domain (my-domain.com) that points to the IP address of your istio-ingressgateway.
When your browser will hit my.domain.com, then it'll be redirected to the istio-ingressgateway. The istio-ingressgateway will inspect the Host field from the request, and redirect the request to grafana (according to VirtualService rules).
You can check kubectl get svc -n istio-system | grep istio-ingressgateway to get the public IP of your ingress gateway.
If you want to enable TLS, then you need to provision a TLS certificate for your domain (most easy with cert-manager). Then you can use https redirect in your gateway, like so :
kind: Gateway
metadata:
name: ingress
namespace: whatever
spec:
selector:
# Make sure that the istio-ingressgateway pods have this label
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- my.domain.com
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- my.domain.com
tls:
mode: SIMPLE
# name of the secret containing the TLS certificate + keys. The secret must exist in the same namespace as the istio-ingressgateway (probably istio-system namespace)
# This secret can be created by cert-manager
# Or you can create a self-signed certificate
# and add it to manually inside the browser trusted certificates
credentialName: my-domain-tls
Then you VirtualService
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana
spec:
hosts:
- "my.domain.com"
gateways:
- ingress
http:
- match:
- uri:
prefix: /grafana
route:
- destination:
port:
number: 3000
host: grafana

istio rules doesn't works from external calls

I want that all ingress traffic for specific service is served by version 8 of this service.
Service is reachable from outside with following host:
my.ciro.it
If I call my.ciro.it I can see that rules works fine.Always respondes with 8 version. If I call my.ciro.it from other service (my2.ciro.it) rules doesn't works and service respondes alternative with version 8 or 9.
This is my virtual service and destination rules:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ciro-service2-destination-rules
spec:
host: ciro-service2.myns.svc.cluster.local
subsets:
- labels:
version: v8
name: v8
- labels:
version: v9
name: v9
trafficPolicy:
tls:
mode: DISABLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ciro-service2-virtual-service
spec:
hosts:
- my.ciro.it
gateways:
- ciro-service2-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: ciro-service2.myns.svc.cluster.local
subset: v8
port:
number: 8082
weight: 100
- destination:
host: ciro-service2.myns.svc.cluster.local
subset: v9
port:
number: 8082
weight: 0
add gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ciro-service2-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "my.ciro.it"
---
The hosts in Your yaml files is my.ciro.it. Which does not match with my2.ciro.it. If Your plan is to use these rules on both sub-domains hosts You can use wildcard hosts:
...
spec:
hosts:
- *.ciro.it
...
Otherwise You should have:
...
spec:
hosts:
- my2.ciro.it
...
The solution is very simple.
gateways:
- ciro-service2-gateway
- mesh
Add mesh gateway, the rules also applied on internal calls.

Kubernetes and Istio dynamic port mapping

It there a way to use some kind of dynamic port mapping in the following scenario
(Istio > Kubernetes service):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-virtualservice
spec:
hosts:
# my-service.default.svc.cluster.local ?
- "*"
gateways:
- my-gateway
http:
- match:
- uri:
prefix: /somepath/
route:
- destination:
host: my-service
And when using Istio, the end user do not need to know the port, and therefore is possible to create and use a dynamic free port?
Defining a service:
# K8s - Service
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- name: my-port
port: #*** Dynamic port? ***#
targetPort: 80

Why I can't expose the grafana that comes from istio with Istio Gateway?

I am using helm to install istio-1.0.0 version with --set grafana.enabled=true.
To access the grafana dashboard, I have to do port forwarding using kubectl command. It works okay. However, i want to access it using public ip, hence I am using this gateway yaml file
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grafana-gateway
namespace: agung-ns
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 15031
name: http-grafana
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-global-route
namespace: agung-ns
spec:
hosts:
- "grafana.domain"
gateways:
- grafana-gateway
- mesh
http:
- route:
- destination:
host: "grafana.istio-system"
port:
number: 3000
weight: 100
I tried to curl it, but it returns 404 status, which means something wrong with routing logic and/or my configuration above.
curl -HHost:grafana.domain http://<my-istioingressgateway-publicip>:15031 -I
HTTP/1.1 503 Service Unavailable
date: Tue, 14 Aug 2018 13:04:27 GMT
server: envoy
transfer-encoding: chunked
Any idea?
I think the problem is that you refer service in different namespace. You need to add FQDN (grafana.istio-system.svc.cluster.local).
If you need istio, grafana, prometheus and jaeger integrated, exposed through gateway and with enabled security you can check the project I am working on:
https://github.com/kyma-project/kyma
I did expose it like this:
grafana.yml
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: grafana-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "my.dns.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana-vts
namespace: istio-system
spec:
hosts:
- "my.dns.com"
gateways:
- grafana-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: grafana
port:
number: 3000
then:
kubectl apply grafana.yml